Beispiel #1
0
        private void AddPropertyToInterfaceFile(UnifiedModelEntity entity, List <PropertyDefinition> withAttributes, List <PropertyDefinition> withoutAttributes, StringBuilder propertiesString, UnifiedModelProperty property)
        {
            this.log.LogInformation($"Processing property '{property.Name}' of type '{entity.TypeName}'");

            string propertyToAdd = LoadFile(ModelPropertyPublic);

            if (property.NavigationPropertyIsCollection)
            {
                Replace(ref propertyToAdd, PropertyTypeKey, $"I{RestTypeToCollectionName(property.Type)}");
            }
            else if (property.NavigationProperty)
            {
                Replace(ref propertyToAdd, PropertyTypeKey, $"I{RestTypeToNavigationTypeName(property.Type)}");
            }
            else
            {
                Replace(ref propertyToAdd, PropertyTypeKey, ShortenType(property.Type));
            }

            if (withAttributes != null || withoutAttributes != null)
            {
                // Add attributes which where already defined previously
                var matchingProperty = withAttributes != null?FindMatchingPropertyBasedUponAttributes(withAttributes, "SharePointPropertyAttribute", property) : null;

                if (matchingProperty == null)
                {
                    // Do we have match on the attribute usage properties based upon name (not all properties have the SharePointPropertyAttribute)
                    matchingProperty = withAttributes != null?withAttributes.FirstOrDefault(p => p.Name == property.Name) : null;
                }

                if (matchingProperty == null)
                {
                    matchingProperty = withoutAttributes != null?withoutAttributes.FirstOrDefault(p => p.Name == property.Name) : null;
                }

                if (matchingProperty != null)
                {
                    Replace(ref propertyToAdd, PropertyNameKey, matchingProperty.Name);
                    Replace(ref propertyToAdd, PropertyGetSetKey, property.NavigationProperty ? "get;" : PropertyDefinitionToGetSet(matchingProperty));
                }
                else
                {
                    Replace(ref propertyToAdd, PropertyNameKey, property.Name);
                    Replace(ref propertyToAdd, PropertyGetSetKey, property.NavigationProperty ? "get;" : "get; set;");
                }
            }
            else
            {
                Replace(ref propertyToAdd, PropertyNameKey, property.Name);
                Replace(ref propertyToAdd, PropertyGetSetKey, property.NavigationProperty ? "get;" : "get; set;");
            }

            propertiesString.AppendLine(propertyToAdd);
            propertiesString.AppendLine();
        }
Beispiel #2
0
 private void AddCollectionToGenerate(UnifiedModelEntity entity, UnifiedModelProperty property)
 {
     if (property.NavigationPropertyIsCollection)
     {
         var collectionName = RestTypeToCollectionName(property.Type);
         var collectionKey  = $"{entity.Namespace}.{collectionName}";
         if (!neededCollections.ContainsKey(collectionKey))
         {
             neededCollections.Add(collectionKey, new CollectionInformation()
             {
                 Name = collectionName, ModelType = RestTypeToNavigationTypeName(property.Type), Namespace = entity.Namespace, Folder = entity.Folder
             });
         }
     }
 }
Beispiel #3
0
        private async Task <UnifiedModel> ProcessProvider(UnifiedModelMapping mapping, KeyValuePair <string, XDocument> edmxDocumentInfo)
        {
            UnifiedModel model = new UnifiedModel
            {
                Provider = edmxDocumentInfo.Key
            };

            Dictionary <string, AnalyzedModelType> analyzedModelTypes = new Dictionary <string, AnalyzedModelType>();
            var edmxDocument = edmxDocumentInfo.Value;

            foreach (var location in mapping.Locations)
            {
                // Combine code information with information from the metadata into a model that will be used to drive code generation
                var edmxNamespace   = (XNamespace)mapping.EdmxNamespace;
                var schemaNamespace = (XNamespace)mapping.SchemaNamespace;

                // Get information about the current code implementation
                var analyzedTypes = await codeAnalyzer.ProcessNamespace(location);

                analyzedTypes.ToList().ForEach(x =>
                {
                    if (!analyzedModelTypes.ContainsKey(x.Key))
                    {
                        analyzedModelTypes.Add(x.Key, x.Value);
                    }
                });

                // Now process the properties from the EDMX providers
                var providerSchemaElements = edmxDocument.Descendants(schemaNamespace + "Schema").Where(e => e.Attribute("Namespace")?.Value == location.SchemaNamespace);
                foreach (var providerSchemaElement in providerSchemaElements)
                {
                    //var providerEntities = providerSchemaElement.Elements(schemaNamespace + "EntityType").Where(e => e.Attribute("Name")?.Value == "Web");
                    var providerEntities = providerSchemaElement.Elements(schemaNamespace + "EntityType");
                    foreach (var providerEntity in providerEntities)
                    {
                        UnifiedModelEntity entity = new UnifiedModelEntity
                        {
                            TypeName        = providerEntity.Attribute("Name").Value,
                            Namespace       = location.Namespace,
                            SchemaNamespace = location.SchemaNamespace,
                            Folder          = location.Folder,
                            SPRestType      = $"{providerSchemaElement.Attribute("Namespace").Value}.{providerEntity.Attribute("Name").Value}",
                            BaseType        = providerEntity.Attribute("BaseType")?.Value
                        };

                        // Process simple properties
                        foreach (var property in providerEntity.Elements(schemaNamespace + "Property"))
                        {
                            var propertyNameAttribute = property.Attribute("Name");
                            var propertyTypeAttribute = property.Attribute("Type");
                            if (propertyNameAttribute != null && propertyTypeAttribute != null)
                            {
                                var propertyName = NormalizePropertyName(propertyNameAttribute.Value);
                                var propertyType = ResolvePropertyType(propertyTypeAttribute.Value);
                                if (propertyType != null)
                                {
                                    UnifiedModelProperty modelProp = new UnifiedModelProperty()
                                    {
                                        Name = propertyName,
                                        Type = propertyType,
                                        NavigationProperty = false
                                    };
                                    entity.Properties.Add(modelProp);
                                }
                            }
                        }

                        // Process navigation properties
                        foreach (var property in providerEntity.Elements(schemaNamespace + "NavigationProperty"))
                        {
                            //<NavigationProperty Name="Alerts" Relationship="SP.SP_Web_Alerts_SP_Alert_AlertsPartner" ToRole="Alerts" FromRole="AlertsPartner" />

                            var propertyNameAttribute         = property.Attribute("Name");
                            var propertyRelationshipAttribute = property.Attribute("Relationship");
                            var propertyToRoleAttribute       = property.Attribute("ToRole");

                            if (propertyNameAttribute != null && propertyRelationshipAttribute != null && propertyToRoleAttribute != null)
                            {
                                var propertyName = NormalizePropertyName(propertyNameAttribute.Value);
                                if (propertyName != null)
                                {
                                    // Find associationset:

                                    //<AssociationSet Name="SP_Web_Alerts_SP_Alert_AlertsPartnerSet" Association="SP.SP_Web_Alerts_SP_Alert_AlertsPartner">
                                    //    <End Role="AlertsPartner" EntitySet="Webs" />
                                    //    <End Role="Alerts" EntitySet="Alerts" />
                                    //</AssociationSet>

                                    var associatedSet = edmxDocument.Descendants(schemaNamespace + "AssociationSet").FirstOrDefault(e => e.Attribute("Association")?.Value == propertyRelationshipAttribute.Value);
                                    if (associatedSet != null)
                                    {
                                        // Find related association

                                        //<Association Name="SP_Web_Alerts_SP_Alert_AlertsPartner">
                                        //    <End Type="SP.Alert" Role="Alerts" Multiplicity="*" />
                                        //    <End Type="SP.Web" Role="AlertsPartner" Multiplicity="0..1" />
                                        //</Association>

                                        //Remove namespace from association : SP.SP_Web_Alerts_SP_Alert_AlertsPartner can be found as SP_Web_Alerts_SP_Alert_AlertsPartner
                                        var associationNameToFind = associatedSet.Attribute("Association").Value.Substring(associatedSet.Attribute("Association").Value.LastIndexOf(".") + 1);

                                        var association = edmxDocument.Descendants(schemaNamespace + "Association").FirstOrDefault(e => e.Attribute("Name")?.Value == associationNameToFind);

                                        if (association != null)
                                        {
                                            // Find the needed "End"
                                            var associatedEnd = association.Elements(schemaNamespace + "End").FirstOrDefault(e => e.Attribute("Role")?.Value == propertyToRoleAttribute.Value);
                                            if (associatedEnd != null)
                                            {
                                                UnifiedModelProperty modelProp = new UnifiedModelProperty()
                                                {
                                                    Name = propertyName,
                                                    Type = associatedEnd.Attribute("Type").Value,
                                                    // Multiplicity = * (collection) or 0..1
                                                    NavigationPropertyIsCollection = associatedEnd.Attribute("Multiplicity").Value.Equals("*"),
                                                    NavigationProperty             = true
                                                };
                                                entity.Properties.Add(modelProp);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        model.Entities.Add(entity);
                    }
                }

                // Combine with mapping file data
                if (mapping != null && mapping.ExcludedTypes != null)
                {
                    foreach (var entityFromMapping in mapping.ExcludedTypes)
                    {
                        var typeToExclude = model.Entities.FirstOrDefault(p => p.SPRestType == entityFromMapping.Type);
                        if (typeToExclude != null)
                        {
                            if (entityFromMapping.Properties.Any())
                            {
                                foreach (var property in entityFromMapping.Properties)
                                {
                                    var propertyToExclude = typeToExclude.Properties.FirstOrDefault(p => p.Name.Equals(property, StringComparison.InvariantCultureIgnoreCase));
                                    if (propertyToExclude != null)
                                    {
                                        propertyToExclude.Skip = true;
                                    }
                                }
                            }
                            else
                            {
                                // Exclude the complete type
                                typeToExclude.Skip = true;
                            }
                        }
                    }
                }

                // Hookup with the possibly available types in the PnP Core SDK
                foreach (var analyzedModelType in analyzedModelTypes)
                {
                    if (analyzedModelType.Value.SPRestTypes.Any())
                    {
                        foreach (var spRestType in analyzedModelType.Value.SPRestTypes)
                        {
                            var typeToUpdate = model.Entities.FirstOrDefault(p => p.SPRestType == spRestType);
                            if (typeToUpdate != null)
                            {
                                typeToUpdate.AnalyzedModelType = analyzedModelType.Value;
                            }
                        }
                    }
                }
            }

            return(model);
        }
Beispiel #4
0
        private Tuple <List <UnifiedModelProperty>, List <UnifiedModelProperty> > OrderProperties(UnifiedModelEntity entity, List <PropertyDefinition> withAttributes, List <PropertyDefinition> withoutAttributes)
        {
            List <UnifiedModelProperty> existingProperties = new List <UnifiedModelProperty>();
            List <UnifiedModelProperty> newProperties      = new List <UnifiedModelProperty>();

            foreach (var property in entity.Properties)
            {
                if (withAttributes != null || withoutAttributes != null)
                {
                    // Try to match based upon attribute usage
                    // e.g. Id edmx you have property Description
                    //      In code you have property DisplayName decorated with [SharePointType("Description")]
                    var matchingProperty = withAttributes != null?FindMatchingPropertyBasedUponAttributes(withAttributes, "SharePointPropertyAttribute", property) : null;

                    if (matchingProperty == null)
                    {
                        // Do we have match on the attribute usage properties based upon name (not all properties have the SharePointPropertyAttribute)
                        matchingProperty = withAttributes != null?withAttributes.FirstOrDefault(p => p.Name == property.Name) : null;

                        if (matchingProperty == null)
                        {
                            // Do we have a regular property?
                            matchingProperty = withoutAttributes != null?withoutAttributes.FirstOrDefault(p => p.Name == property.Name) : null;
                        }
                    }

                    if (matchingProperty != null)
                    {
                        existingProperties.Add(property);
                    }
                    else
                    {
                        newProperties.Add(property);
                    }
                }
                else
                {
                    newProperties.Add(property);
                }
            }

            return(new Tuple <List <UnifiedModelProperty>, List <UnifiedModelProperty> >(existingProperties, newProperties));
        }
Beispiel #5
0
        private void AddPropertyToClassFile(UnifiedModelEntity entity, List <PropertyDefinition> withAttributes, List <PropertyDefinition> withoutAttributes, StringBuilder propertiesString, UnifiedModelProperty property)
        {
            this.log.LogInformation($"Processing property '{property.Name}' of type '{entity.TypeName}'");

            string baseProperty = "";

            if (!property.NavigationProperty)
            {
                // Regular props
                baseProperty = LoadFile(ModelPropertyInternal);
            }
            else
            {
                // Navigation props
                if (property.NavigationPropertyIsCollection)
                {
                    baseProperty = LoadFile(ModelNavigationCollectionPropertyInternal);
                }
                else
                {
                    baseProperty = LoadFile(ModelNavigationPropertyInternal);
                }
            }

            var propertyToAdd = baseProperty.Replace(PropertyTypeKey, ShortenType(property.Type));

            if (property.NavigationPropertyIsCollection)
            {
                var collectionName = RestTypeToCollectionName(property.Type);
                Replace(ref propertyToAdd, CollectionNameKey, collectionName);
            }
            else if (property.NavigationProperty)
            {
                Replace(ref propertyToAdd, NavigationTypeKey, RestTypeToNavigationTypeName(property.Type));
            }

            string propertyAttributesString          = "";
            bool   navigationPropertyAttributesAdded = false;

            if (withAttributes != null || withoutAttributes != null)
            {
                // Add attributes which where already defined previously
                var matchingProperty = withAttributes != null?FindMatchingPropertyBasedUponAttributes(withAttributes, "SharePointPropertyAttribute", property) : null;

                if (matchingProperty == null)
                {
                    // Do we have match on the attribute usage properties based upon name (not all properties have the SharePointPropertyAttribute)
                    matchingProperty = withAttributes != null?withAttributes.FirstOrDefault(p => p.Name == property.Name) : null;
                }

                if (matchingProperty != null)
                {
                    foreach (var attr in matchingProperty.CustomAttributes)
                    {
                        navigationPropertyAttributesAdded = true;
                        if (!string.IsNullOrEmpty(propertyAttributesString))
                        {
                            propertyAttributesString += Environment.NewLine;
                        }

                        propertyAttributesString += CustomAttributeToCode(attr);
                    }

                    Replace(ref propertyToAdd, PropertyNameKey, matchingProperty.Name);
                    AddCollectionToGenerate(entity, property);
                }
                else
                {
                    Replace(ref propertyToAdd, PropertyNameKey, property.Name);
                    AddCollectionToGenerate(entity, property);
                }
            }
            else
            {
                Replace(ref propertyToAdd, PropertyNameKey, property.Name);
                AddCollectionToGenerate(entity, property);
            }

            if (!navigationPropertyAttributesAdded)
            {
                // Add properties we know have to be there
                //if (property.NavigationPropertyIsCollection)
                //{
                //    propertyAttributesString = AddAttribute("SharePointProperty", $"\"{property.Name}\"", "Expandable = true");
                //}
            }

            if (!string.IsNullOrEmpty(propertyAttributesString))
            {
                Replace(ref propertyToAdd, PropertyAttributesKey, propertyAttributesString);
            }
            else
            {
                Replace(ref propertyToAdd, $"{PropertyAttributesKey}{Environment.NewLine}", propertyAttributesString);
            }

            propertiesString.AppendLine(propertyToAdd);
            propertiesString.AppendLine();
        }
Beispiel #6
0
        private void AddKeyPropertyToClassFile(UnifiedModelEntity entity, List <PropertyDefinition> withAttributes, StringBuilder propertiesString)
        {
            string keyPropertyField = "";
            string keyPropertyType  = "";

            //if (withAttributes != null)
            //{
            //    bool found = false;
            //    foreach (var existingProperty in withAttributes)
            //    {
            //        if (found)
            //        {
            //            break;
            //        }

            //        var attributesToCheck = existingProperty.CustomAttributes.Where(p => p.AttributeType.Name == "KeyPropertyAttribute");
            //        foreach (var attributeToCheck in attributesToCheck)
            //        {
            //            if (attributeToCheck.HasConstructorArguments)
            //            {
            //                keyPropertyField = attributeToCheck.ConstructorArguments[0].Value.ToString();
            //                keyPropertyType = ShortenType(attributeToCheck.ConstructorArguments[0].Type.Name);
            //                found = true;
            //            }
            //        }
            //    }
            //}

            if (string.IsNullOrEmpty(keyPropertyField))
            {
                var property = entity.Properties.FirstOrDefault(p => p.Name == "Id");
                if (property == null)
                {
                    property = entity.Properties.FirstOrDefault(p => p.Name == "StringId");
                }

                if (property != null)
                {
                    keyPropertyField = property.Name;
                    keyPropertyType  = ShortenType(property.Type);
                }
            }

            if (!string.IsNullOrEmpty(keyPropertyField))
            {
                var keyProperty = LoadFile(ModelKeyPropertyInternal);
                Replace(ref keyProperty, KeyPropertyNameKey, keyPropertyField);

                if (keyPropertyType == "Guid")
                {
                    Replace(ref keyProperty, KeyPropertyValueKey, "Guid.Parse(value.ToString())");
                }
                else if (keyPropertyType == "string")
                {
                    Replace(ref keyProperty, KeyPropertyValueKey, "value.ToString()");
                }
                else if (keyPropertyType == "int" || keyPropertyType == "Int32" || keyPropertyType == "Int64")
                {
                    Replace(ref keyProperty, KeyPropertyValueKey, "(int)value");
                }

                propertiesString.AppendLine(keyProperty);
            }
        }
Beispiel #7
0
        private void GenerateModelFiles(UnifiedModelEntity entity)
        {
            //var classFileGen = LoadFile(ModelClassGenInternal);
            var classFile     = LoadFile(ModelClassInternal);
            var interfaceFile = LoadFile(ModelClassPublic);

            Replace(ref classFile, TypeKey, entity.TypeName);
            Replace(ref classFile, NamespaceKey, entity.Namespace);
            Replace(ref classFile, RestTypeKey, entity.SPRestType);
            Replace(ref interfaceFile, TypeKey, entity.TypeName);
            Replace(ref interfaceFile, NamespaceKey, entity.Namespace);

            Tuple <List <PropertyDefinition>, List <PropertyDefinition> > splitExistingPropertiesImplementation = null;

            if (entity.AnalyzedModelType != null && entity.AnalyzedModelType.Implementation != null)
            {
                splitExistingPropertiesImplementation = SplitExistingPropertiesBasedUponAttribute(entity.AnalyzedModelType.Implementation);
            }

            Tuple <List <PropertyDefinition>, List <PropertyDefinition> > splitExistingPropertiesInterface = null;

            if (entity.AnalyzedModelType != null && entity.AnalyzedModelType.Public != null)
            {
                splitExistingPropertiesInterface = SplitExistingPropertiesBasedUponAttribute(entity.AnalyzedModelType.Public);
            }

            Tuple <List <UnifiedModelProperty>, List <UnifiedModelProperty> > orderedPropertiesImplementation = OrderProperties(entity, splitExistingPropertiesImplementation?.Item1, splitExistingPropertiesImplementation?.Item2);
            Tuple <List <UnifiedModelProperty>, List <UnifiedModelProperty> > orderedPropertiesInterface      = OrderProperties(entity, splitExistingPropertiesInterface?.Item1, splitExistingPropertiesInterface?.Item2);

            StringBuilder classPropertiesString     = new StringBuilder();
            StringBuilder interfacePropertiesString = new StringBuilder();

            if (orderedPropertiesImplementation.Item1.Any())
            {
                classPropertiesString.AppendLine("        #region Existing properties");
                classPropertiesString.AppendLine();
            }

            if (orderedPropertiesInterface.Item1.Any())
            {
                interfacePropertiesString.AppendLine("        #region Existing properties");
                interfacePropertiesString.AppendLine();
            }

            foreach (var property in orderedPropertiesImplementation.Item1)
            {
                if (!property.Skip)
                {
                    AddPropertyToClassFile(entity, splitExistingPropertiesImplementation?.Item1, splitExistingPropertiesImplementation?.Item2, classPropertiesString, property);
                }
                else
                {
                    log.LogInformation($"Property {property.Name} was skipped");
                }
            }

            foreach (var property in orderedPropertiesInterface.Item1)
            {
                if (!property.Skip)
                {
                    AddPropertyToInterfaceFile(entity, splitExistingPropertiesInterface?.Item1, splitExistingPropertiesInterface?.Item2, interfacePropertiesString, property);
                }
                else
                {
                    log.LogInformation($"Property {property.Name} was skipped");
                }
            }

            if (orderedPropertiesImplementation.Item1.Any())
            {
                classPropertiesString.AppendLine("        #endregion");
                classPropertiesString.AppendLine();
            }

            classPropertiesString.AppendLine("        #region New properties");
            classPropertiesString.AppendLine();

            if (orderedPropertiesInterface.Item1.Any())
            {
                interfacePropertiesString.AppendLine("        #endregion");
                interfacePropertiesString.AppendLine();
            }

            interfacePropertiesString.AppendLine("        #region New properties");
            interfacePropertiesString.AppendLine();

            foreach (var property in orderedPropertiesImplementation.Item2)
            {
                if (!property.Skip)
                {
                    AddPropertyToClassFile(entity, splitExistingPropertiesImplementation?.Item1, splitExistingPropertiesImplementation?.Item2, classPropertiesString, property);
                }
                else
                {
                    log.LogInformation($"Property {property.Name} was skipped");
                }
            }

            foreach (var property in orderedPropertiesInterface.Item2)
            {
                if (!property.Skip)
                {
                    AddPropertyToInterfaceFile(entity, splitExistingPropertiesInterface?.Item1, splitExistingPropertiesInterface?.Item2, interfacePropertiesString, property);
                }
                else
                {
                    log.LogInformation($"Property {property.Name} was skipped");
                }
            }

            classPropertiesString.AppendLine("        #endregion");
            interfacePropertiesString.AppendLine("        #endregion");

            AddKeyPropertyToClassFile(entity, splitExistingPropertiesImplementation?.Item1, classPropertiesString);

            Replace(ref classFile, PropertiesKey, classPropertiesString.ToString());
            Replace(ref interfaceFile, PropertiesKey, interfacePropertiesString.ToString());

            SaveFile(classFile, $"{entity.TypeName}.cs", entity.Folder, false);
            SaveFile(interfaceFile, $"I{entity.TypeName}.cs", entity.Folder, true);
        }