/// <summary>   Process this. </summary>
        ///
        /// <remarks>   Ken, 10/5/2020. </remarks>
        ///
        /// <param name="entityObject">             The entity object. </param>
        /// <param name="entityPropertyItem">       The entity property item. </param>
        /// <param name="annotationType"></param>
        /// <param name="typeBuilder">              The type builder. </param>
        /// <param name="appHierarchyNodeObject">   The application hierarchy node object. </param>
        /// <param name="generatorConfiguration">   The generator configuration. </param>
        ///
        /// <returns>   True if it succeeds, false if it fails. </returns>

        public bool Process(EntityObject entityObject, EntityPropertyItem entityPropertyItem, Type annotationType, TypeBuilder typeBuilder, AppUIHierarchyNodeObject appHierarchyNodeObject, IGeneratorConfiguration generatorConfiguration)
        {
            if (entityPropertyItem.PropertyName == "UIGroup")
            {
                foreach (var childProperty in entityPropertyItem.ChildProperties)
                {
                    var annotationAtrributeType = generatorConfiguration.FindDataAnnotationType(childProperty.PropertyName + "Attribute");
                    var handler = generatorConfiguration.GetDataAnnotationTypeHandler(childProperty.PropertyName, annotationAtrributeType);

                    if (handler != null)
                    {
                        if (!handler.Process(entityObject, childProperty, annotationAtrributeType, typeBuilder, appHierarchyNodeObject, generatorConfiguration))
                        {
                            throw new Exception($"Cannot process annotation type '{ annotationAtrributeType.AsDisplayText() }' and property '{ childProperty.PropertyName }");
                        }
                    }
                    else
                    {
                        throw new HandlerNotFoundException($"Cannot find annotation type handler for annotation type '{ annotationAtrributeType.AsDisplayText() }' and property '{ childProperty.PropertyName }");
                    }
                }

                return(true);
            }
            else if (annotationType != null)
            {
                return(Process(entityObject, null, entityPropertyItem, appHierarchyNodeObject, annotationType, (c) => typeBuilder.SetCustomAttribute(c)));
            }
            else
            {
                throw new Exception($"Cannot find Attribute type or custom handler to process property '{ entityPropertyItem.PropertyName }");
            }
        }
        /// <summary>   Process this.  </summary>
        ///
        /// <remarks>   Ken, 10/5/2020. </remarks>
        ///
        /// <param name="entityObject">             The entity object. </param>
        /// <param name="attributeObject">          The attribute object. </param>
        /// <param name="entityPropertyItem">       The entity property item. </param>
        /// <param name="annotationType"></param>
        /// <param name="propertyBuilder">          The property builder. </param>
        /// <param name="appHierarchyNodeObject">   The application hierarchy node object. </param>
        /// <param name="generatorConfiguration">   The generator configuration. </param>
        ///
        /// <returns>   True if it succeeds, false if it fails. </returns>

        public bool Process(EntityObject entityObject, AttributeObject attributeObject, EntityPropertyItem entityPropertyItem, Type annotationType, PropertyBuilder propertyBuilder, AppUIHierarchyNodeObject appHierarchyNodeObject, IGeneratorConfiguration generatorConfiguration)
        {
            if (annotationType != null)
            {
                return(Process(entityObject, attributeObject, entityPropertyItem, appHierarchyNodeObject, annotationType, (c) => propertyBuilder.SetCustomAttribute(c)));
            }
            else
            {
                throw new Exception($"Cannot find Attribute type or custom handler to process property '{ entityPropertyItem.PropertyName }");
            }
        }
Example #3
0
        /// <summary>   Process from JSON. </summary>
        ///
        /// <remarks>   Ken, 10/2/2020. </remarks>
        ///
        /// <param name="entityModelJsonFile">      The entities JSON file. </param>
        /// <param name="businessModelJsonFile">    The business model file. </param>
        /// <param name="entitiesProjectPath">      Full pathname of the entities project file. </param>

        public void ProcessFromJson(string entityModelJsonFile, string businessModelJsonFile, string entitiesProjectPath)
        {
            var          config        = this.GeneratorConfiguration;
            var          directory     = new DirectoryInfo(projectFolderRoot);
            var          solutionFile  = directory.GetFiles("*.sln", SearchOption.TopDirectoryOnly).SingleOrDefault();
            var          hydraJsonFile = directory.GetFiles("hydra.json", SearchOption.AllDirectories).FirstOrDefault();
            ConfigObject configObject  = null;
            IModelAugmentationHandler      modelAugmentationHandler;
            IEntitiesModelGeneratorHandler generatorHandler;
            FileInfo                 outputFile;
            BusinessModel            businessModel;
            EntityDomainModel        entityDomainModel;
            VSProject                entitiesProject;
            string                   fileName;
            string                   appName                  = null;
            string                   appDescription           = null;
            string                   organizationName         = null;
            AppUIHierarchyNodeObject appUIHierarchyNodeObject = null;

            if (hydraJsonFile != null)
            {
                configObject = ConfigObject.Load(hydraJsonFile.FullName);

                appName          = configObject.AppName;
                appDescription   = configObject.AppDescription;
                organizationName = configObject.OrganizationName;
            }

            if (solutionFile != null)
            {
                var solutionName   = Path.GetFileNameWithoutExtension(solutionFile.Name);
                var solutionFolder = Path.GetDirectoryName(solutionFile.FullName);

                if (appName == null)
                {
                    appName          = solutionName;
                    organizationName = solutionName;
                }

                fileName = Path.Combine(projectFolderRoot, "entities.json");
            }
            else
            {
                if (appName != null)
                {
                    fileName = Path.Combine(projectFolderRoot, "entities.json");
                }
                else
                {
                    fileName = Path.Combine(projectFolderRoot, "entities.json");

                    organizationName = "NoOrganization";
                    appName          = "NoApp";
                }
            }

            config.KeyValuePairs = new Dictionary <string, object>();
            config.KeyValuePairs.Add("ConfigObject", configObject);
            config.AppName        = appName;
            config.AppDescription = appDescription;

            outputFile = new FileInfo(fileName);

            if (config.CurrentPass == GeneratorPass.Files)
            {
                if (outputFile.Exists)
                {
                    outputFile.MakeWritable();
                }
            }

            WriteLine("Loading entity model from json file");

            entityDomainModel = config.CreateEntityDomainModelFromJsonFile(entityModelJsonFile);

            WriteLine("Loading business model");

            businessModel = config.CreateBusinessModelFromJson(businessModelJsonFile);

            modelAugmentationHandler = config.GetModelAugmentationHandler();
            entitiesProject          = new VSProject(entitiesProjectPath);

            if (modelAugmentationHandler != null)
            {
                WriteLine("Augmenting entity model for code generation");

                modelAugmentationHandler.Process(entityDomainModel, businessModel, projectType, projectFolderRoot, entitiesProject, config, out appUIHierarchyNodeObject);
            }

            generatorHandler = config.GetEntitiesModelGeneratorHandler();

            if (generatorHandler != null)
            {
                WriteLine("Processing entity model and generating code file");

                generatorHandler.Process(entityDomainModel, businessModel, appUIHierarchyNodeObject, projectType, projectFolderRoot, entitiesProject, config);

                if (config.CurrentPass == GeneratorPass.Files)
                {
                    WriteLine($"Generated { outputFile.FullName }");
                }
            }
            else
            {
                WriteError("No handler found implementing IEntitiesModelGeneratorHandler");
                throw new HandlerNotFoundException("Entities model generation");
            }
        }
Example #4
0
        /// <summary>   Process this.  </summary>
        ///
        /// <remarks>   Ken, 10/4/2020. </remarks>
        ///
        /// <param name="entityDomainModel">        The entity domain model. </param>
        /// <param name="businessModel">            The business model. </param>
        /// <param name="appUIHierarchyNodeObject"></param>
        /// <param name="appSettingsObjects">       The application settings objects. </param>
        /// <param name="projectType">              Type of the project. </param>
        /// <param name="projectFolderRoot">        The project folder root. </param>
        /// <param name="generatorConfiguration">   The generator configuration. </param>
        ///
        /// <returns>   True if it succeeds, false if it fails. </returns>

        public bool Process(EntityDomainModel entityDomainModel, BusinessModel businessModel, AppUIHierarchyNodeObject appUIHierarchyNodeObject, Dictionary <AppSettingsKind, BusinessModelObject> appSettingsObjects, Guid projectType, string projectFolderRoot, IGeneratorConfiguration generatorConfiguration)
        {
            var profilePreferencesObject = appSettingsObjects[AppSettingsKind.ProfilePreferences];
            var userObject = businessModel.GetDescendants().Single(o => o.Id == profilePreferencesObject.ShadowItem);
            var userEntity = userObject.UIHierarchyNodeObject.Entities.Single(e => e.HasIdentityEntityKind(IdentityEntityKind.User));

            foreach (var attribute in userEntity.Attributes.Where(a => a.HasIdentityFieldKind(IdentityFieldKind.Client) || a.HasIdentityFieldKind(IdentityFieldKind.PasswordHash)))
            {
                attribute.Properties.Add(new EntityPropertyItem
                {
                    PropertyName  = "AllowUserEdit",
                    PropertyValue = "true"
                });
            }

            return(true);
        }
Example #5
0
        /// <summary>   Process this. </summary>
        ///
        /// <remarks>   Ken, 10/3/2020. </remarks>
        ///
        /// <param name="entityDomainModel">        The entity domain model. </param>
        /// <param name="businessModel">            The business model. </param>
        /// <param name="projectType">              Type of the project. </param>
        /// <param name="projectFolderRoot">        The project folder root. </param>
        /// <param name="entitiesProject"></param>
        /// <param name="generatorConfiguration">   The generator configuration. </param>
        /// <param name="appUIHierarchyNodeObject"></param>
        ///
        /// <returns>   True if it succeeds, false if it fails. </returns>

        public bool Process(EntityDomainModel entityDomainModel, BusinessModel businessModel, Guid projectType, string projectFolderRoot, IVSProject entitiesProject, IGeneratorConfiguration generatorConfiguration, out AppUIHierarchyNodeObject appUIHierarchyNodeObject)
        {
            var appSystemObject         = businessModel.GetDescendants().Single(a => a.IsApp && a.Name == generatorConfiguration.AppName);
            var topLevelObject          = businessModel.TopLevelObject;
            var topHierarchyNodeObjects = new List <UIHierarchyNodeObject>();
            var allHierarchyNodeObjects = new List <UIHierarchyNodeObject>();
            var appSettingsObjects      = new Dictionary <AppSettingsKind, BusinessModelObject>();
            IMemoryModuleBuilder  memoryModuleBuilder;
            ModuleBuilder         entititesModuleBuilder;
            UIHierarchyNodeObject topHierarchyNodeObject = null;
            string debugUIHierarchy;

            // create the UI hierarchy

            appUIHierarchyNodeObject = null;

            topLevelObject.GetDescendantsAndSelf <BusinessModelObject, UIHierarchyNodeObject>(o => o.Children, (o, n) =>
            {
                var hierarchyNodeObject = new UIHierarchyNodeObject(o);

                if (topHierarchyNodeObject == null)
                {
                    topHierarchyNodeObject = hierarchyNodeObject;
                }

                if (n != null)
                {
                    n.AddChild(hierarchyNodeObject);
                }

                return(hierarchyNodeObject);
            });

            // prune the tree

            topHierarchyNodeObject.GetDescendantsAndSelf(n => n.Children, n =>
            {
                if (n.Parent != null)
                {
                    var parent = n.Parent;

                    if (!parent.ShowInUI)
                    {
                        var newParent = parent.Parent;

                        if (newParent == null)
                        {
                            n.Parent = null;

                            if (n.ShowInUI)
                            {
                                topHierarchyNodeObjects.Add(n);
                            }
                        }
                        else
                        {
                            newParent.Children.Remove(parent);
                            newParent.AddChild(n);
                        }
                    }
                }
            });

            foreach (var hierarchyNodeObject in topHierarchyNodeObjects)
            {
                allHierarchyNodeObjects.AddRange(hierarchyNodeObject.GetDescendantsAndSelf());
            }

            // create the app UI Hierarchy

            appUIHierarchyNodeObject = allHierarchyNodeObjects.Single(n => n.Id == appSystemObject.Id).CreateCopy <AppUIHierarchyNodeObject>();

            foreach (var hierarchyNodeObject in topHierarchyNodeObjects)
            {
                hierarchyNodeObject.Name = "Home";

                appUIHierarchyNodeObject.TopUIHierarchyNodeObjects.Add(hierarchyNodeObject);
            }

            // attach entities

            foreach (var entity in entityDomainModel.Entities)
            {
                if (entity.IsInherentDataItem)
                {
                    appUIHierarchyNodeObject.InherentEntities.Add(entity);
                }
                else
                {
                    var hierarchyNodeObject = allHierarchyNodeObjects.Single(n => n.Id == entity.ParentDataItem);

                    foreach (var shadowHierarchyNodeObject in allHierarchyNodeObjects.Where(n => n.ShadowItem == hierarchyNodeObject.Id))
                    {
                        shadowHierarchyNodeObject.Entities.Add(entity);
                    }

                    hierarchyNodeObject.Entities.Add(entity);
                }

                appUIHierarchyNodeObject.AllEntities.Add(entity);
            }

            // create new entities from app settings kind

            foreach (var appSettingsObject in topLevelObject.GetDescendants().Where(o => o.AppSettingsKind != null))
            {
                var appSettingsKind = EnumUtils.GetValue <AppSettingsKind>(appSettingsObject.AppSettingsKind);

                appSettingsObjects.Add(appSettingsKind, appSettingsObject);
            }

            foreach (var pair in appSettingsObjects)
            {
                var appSettingsKind = pair.Key;
                var handler         = generatorConfiguration.GetAppSettingsKindHandler(appSettingsKind);

                if (handler != null)
                {
                    handler.Process(entityDomainModel, businessModel, appUIHierarchyNodeObject, appSettingsObjects, projectType, projectFolderRoot, generatorConfiguration);
                }
            }

            // create new entities from many-to-many containers

            foreach (var entity in appUIHierarchyNodeObject.AllEntities.ToList().Where(e => e.HasRelatedEntityAttributes()))
            {
                foreach (var containsManyToManyAttribute in entity.GetRelatedEntityAttributes().Where(a => a.Properties.Single(p => p.PropertyName == "RelatedEntity").ChildProperties.Any(p2 => p2.PropertyName == "RelationshipKind" && p2.PropertyValue == "ContainsManyToMany")))
                {
                    var relatedEntityProperty      = containsManyToManyAttribute.Properties.Single(p => p.PropertyName == "RelatedEntity");
                    var containsManyToManyProperty = relatedEntityProperty.ChildProperties.Single(p2 => p2.PropertyName == "RelationshipKind" && p2.PropertyValue == "ContainsManyToMany");
                    var existingEntityProperty     = containsManyToManyProperty.ChildProperties.Single(p3 => p3.PropertyName == "ExistingEntity");
                    var existingEntityName         = existingEntityProperty.PropertyValue;
                    var existingEntity             = appUIHierarchyNodeObject.AllEntities.Single(e => e.Name == existingEntityName);
                    var containerNameProperty      = containsManyToManyProperty.ChildProperties.Single(p3 => p3.PropertyName == "ContainerName");
                    var containerName         = containerNameProperty.PropertyValue;
                    var associateEntityObject = new EntityObject()
                    {
                        Name = containerName,
                        IsInherentDataItem = true,
                        Attributes         = new List <AttributeObject>()
                        {
                            new AttributeObject
                            {
                                Name          = entity.Name,
                                AttributeType = "related entity",
                                Properties    = new List <EntityPropertyItem>()
                                {
                                    new EntityPropertyItem()
                                    {
                                        PropertyName    = "RelatedEntity",
                                        PropertyValue   = "IsLookupOfManyToOne",
                                        ChildProperties = new List <EntityPropertyItem>()
                                        {
                                            new EntityPropertyItem()
                                            {
                                                PropertyName  = "ExistingEntity",
                                                PropertyValue = entity.Name
                                            }
                                        }
                                    }
                                }
                            },
                            new AttributeObject
                            {
                                Name          = existingEntityName,
                                AttributeType = "related entity",
                                Properties    = new List <EntityPropertyItem>()
                                {
                                    new EntityPropertyItem()
                                    {
                                        PropertyName    = "RelatedEntity",
                                        PropertyValue   = "IsLookupOfManyToOne",
                                        ChildProperties = new List <EntityPropertyItem>()
                                        {
                                            new EntityPropertyItem()
                                            {
                                                PropertyName  = "ExistingEntity",
                                                PropertyValue = existingEntityName
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    };

                    if (entity.HasIdentityEntityKind(IdentityEntityKind.User) && existingEntity.HasIdentityEntityKind(IdentityEntityKind.Role))
                    {
                        associateEntityObject.Properties = new List <EntityPropertyItem>()
                        {
                            new EntityPropertyItem()
                            {
                                PropertyName    = "IdentityEntity",
                                ChildProperties = new List <EntityPropertyItem>()
                                {
                                    new EntityPropertyItem()
                                    {
                                        PropertyName  = "IdentityEntityKind",
                                        PropertyValue = IdentityEntityKind.UserToRole.ToString()
                                    }
                                }
                            }
                        };
                    }

                    appUIHierarchyNodeObject.InherentEntities.Add(associateEntityObject);
                    appUIHierarchyNodeObject.AllEntities.Add(associateEntityObject);
                }
            }

            debugUIHierarchy = appUIHierarchyNodeObject.DebugPrintUIHierarchy();

            // build types

            memoryModuleBuilder    = generatorConfiguration.GetMemoryModuleBuilder();
            entititesModuleBuilder = memoryModuleBuilder.CreateMemoryModuleBuilder(entitiesProject);

            appUIHierarchyNodeObject.EntitiesModuleBuilder = entititesModuleBuilder;

            foreach (var entity in appUIHierarchyNodeObject.AllEntities)
            {
                generatorConfiguration.CreateTypeForEntity(entititesModuleBuilder, entity, appUIHierarchyNodeObject);
            }

            return(true);
        }
Example #6
0
        /// <summary>   Process this.  </summary>
        ///
        /// <remarks>   Ken, 10/4/2020. </remarks>
        ///
        /// <param name="entityDomainModel">        The entity domain model. </param>
        /// <param name="businessModel">            The business model. </param>
        /// <param name="appUIHierarchyNodeObject">   The application UI hierarchy node object. </param>
        /// <param name="appSettingsObjects">       The application settings objects. </param>
        /// <param name="projectType">              Type of the project. </param>
        /// <param name="projectFolderRoot">        The project folder root. </param>
        /// <param name="generatorConfiguration">   The generator configuration. </param>
        ///
        /// <returns>   True if it succeeds, false if it fails. </returns>

        public bool Process(EntityDomainModel entityDomainModel, BusinessModel businessModel, AppUIHierarchyNodeObject appUIHierarchyNodeObject, Dictionary <AppSettingsKind, BusinessModelObject> appSettingsObjects, Guid projectType, string projectFolderRoot, IGeneratorConfiguration generatorConfiguration)
        {
            var globalSettingsObject    = appSettingsObjects[AppSettingsKind.GlobalSettings];
            var userPreferencesObject   = appSettingsObjects[AppSettingsKind.UserPreferences];
            var appSettingsEntityObject = new EntityObject()
            {
                Name           = appUIHierarchyNodeObject.Name + "Settings",
                ParentDataItem = globalSettingsObject.Id,
                Attributes     = new List <AttributeObject>()
                {
                    new AttributeObject
                    {
                        Name          = "Setting",
                        AttributeType = "string",
                    },
                    new AttributeObject
                    {
                        Name          = "Setting Type",
                        AttributeType = "string",
                    },
                    new AttributeObject
                    {
                        Name          = "Setting Value",
                        AttributeType = "string",
                    },
                    new AttributeObject
                    {
                        Name          = "Allow User Customize",
                        AttributeType = "bool",
                    },
                    new AttributeObject
                    {
                        Name          = "Reset Customization",
                        AttributeType = "bool",
                    }
                },
                Properties = new List <EntityPropertyItem>()
                {
                    new EntityPropertyItem {
                        PropertyName = "AppSettingsKind", PropertyValue = AppSettingsKind.GlobalSettings.ToString()
                    }
                }
            };

            globalSettingsObject.UIHierarchyNodeObject.Entities.Add(appSettingsEntityObject);
            userPreferencesObject.UIHierarchyNodeObject.Entities.Add(appSettingsEntityObject.Shadow());
            appUIHierarchyNodeObject.AllEntities.Add(appSettingsEntityObject);

            return(true);
        }