Exemple #1
0
        public static void GenerateEntityFactory(JToken entities, string rootFilePath, Compilation compilation)
        {
            var entityFactory = new ClassContainer
            {
                Name      = "FoundationFactory",
                Namespace = UsingKeys.FOUNDATION_FACTORY_CLASS,
                FilePath  = $"{rootFilePath}/FoundationFactory.cs",
                DocString = "Foundation Factory",
            };

            entityFactory.AddUsing(nameof(UsingKeys.SDK_COMMON), UsingKeys.SDK_COMMON);
            entityFactory.AddUsing(nameof(UsingKeys.FOUNDATION), UsingKeys.FOUNDATION);

            entityFactory.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);
            entityFactory.AddModifier(nameof(Modifiers.PARTIAL), Modifiers.PARTIAL);

            foreach (var entity in entities.Where(e => e["methods"].Any()))
            {
                var factoryMethod = new EntityFactoryMethodContainer
                {
                    Name         = $"{entity["_key"].GetStringValue().ToPascal()}Repository",
                    Returns      = $"{entity["_key"].GetStringValue().ToPascal()}Repository",
                    MethodParams = new MethodParameterContainer(),
                };
                factoryMethod.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);
                entityFactory.AddMethod(entity["_key"].GetStringValue(), factoryMethod);
            }

            compilation.AddClass(nameof(entityFactory), entityFactory);
        }
        public static void GenerateRepository(JToken entity, string entityPascalName, string rootFilePath, string entityGroup, Compilation compilation)
        {
            var entityRepository = new ClassContainer();

            // namespace
            entityRepository.Namespace = UsingKeys.FOUNDATION;

            // modifier
            entityRepository.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);

            // name
            entityRepository.Name = $"{entityPascalName}Repository";

            // base type
            entityRepository.AddBaseType("BASE_ENTITY", "Repository");
            entityRepository.AddUsing(nameof(UsingKeys.SDK_COMMON), UsingKeys.SDK_COMMON);

            // add interface
            entityRepository.AddBaseType("INTERFACE", $"I{entityRepository.Name}");

            // doc (just use the name for now)
            entityRepository.DocString = entityRepository.Name;

            // set the filepath root/groupId/Class/Class.cs
            entityRepository.FilePath = $"{rootFilePath}/{entityGroup}/{entityPascalName}/";
            entityRepository.FileName = $"{entityRepository.Name}.cs";

            //default constructor
            var defaultConstructor = new ConstructorContainer
            {
                Name = entityRepository.Name,
            };

            defaultConstructor.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);
            entityRepository.AddConstructor("DEFAULT", defaultConstructor);

            // config constructor
            var configConstructor = new DefaultConfigConstructorContainer
            {
                Name = entityRepository.Name
            };

            configConstructor.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);
            entityRepository.AddConstructor("CONFIG", configConstructor);

            // get methods
            var methods = entity["methods"];

            foreach (var method in methods)
            {
                // gather common info
                var methodName = method["_key"].GetStringValue().ToPascal();
                // the http method
                var httpMethod = method["method"].GetStringValue()?.ToUpper() ?? "GET";

                // if method return type is void
                var isVoid = httpMethod == "DELETE" ? true : false;

                // the path
                var path = method["path"].GetStringValue();

                // is method paginated
                var isPaginated = method["pagination"].GetBoolValue();

                // is method private
                var isPrivateMethod = method["private_method"] != null;

                // is method a custom call
                var isCustomMethodCall = method["custom_method"] != null;

                // does method return a foreing key
                var foreignKey = method["return_info"]["self"].GetBoolValue() == false && TypeHelpers.MapType(method["return_info"]["type"].GetStringValue()) == null;

                // return type
                var returns = TypeHelpers.MapType(method["return_info"]["type"].GetStringValue()) ?? method["return_info"]["type"].GetStringValue().ToPascal();

                if (returns == "Void")
                {
                    returns = entityPascalName;
                    isVoid  = true;
                }

                // name of custom method
                var customMethodName = method["custom_method"].GetStringValue().ToPascal();

                if (isPaginated)
                {
                    // add usings for paginated
                }

                if (foreignKey)
                {
                    // add using for foreign key
                    entityRepository.AddUsing("FOREIGN_KEY", UsingKeys.FOUNDATION);
                }

                var hasRequest = false;

                // gather internal parameters
                var pathParams  = new List <MyParameterContainer>();
                var queryParams = new List <MyParameterContainer>();
                var bodyParams  = new List <MyParameterContainer>();
                var fileParams  = new List <MyParameterContainer>();
                var formParams  = new List <MyParameterContainer>();

                // does method need a request param
                if (method["fields"].Any(f => f["in"].GetStringValue() == "body"))
                {
                    var requestParam = new MyParameterContainer
                    {
                        Key       = "request",
                        ParamType = returns ?? "string",
                        External  = true,
                        Required  = true,
                        FieldName = "request",
                    };
                    bodyParams.Add(requestParam);
                    hasRequest = true;
                }

                foreach (var field in method["fields"])
                {
                    var _key                 = field["_key"].GetStringValue()?.ToPascal();
                    var _name                = field["name"].GetStringValue();
                    var _api_fieldname       = field["api_fieldname"].GetStringValue();
                    var _entity_fieldname    = field["entity_fieldname"].GetStringValue()?.ToPascal();
                    var _parameter_fieldname = field["parameter_fieldname"].GetStringValue();

                    // TODO remove as soon as fixed in generator. Truly awful hack
                    if (_name == "device_id" && entityPascalName == "Device")
                    {
                        _name = "id";
                    }

                    // where is parameter?
                    var paramIn = field["in"].GetStringValue();
                    // is it external?
                    var external = field["external_param"].GetBoolValue();
                    // is it required?
                    var required = field["required"].GetBoolValue();
                    // the type
                    string type = null;
                    // replace body with other type
                    var replaceBody = field["__REPLACE_BODY"] != null;

                    var defaultValue = field["minimum"].GetStringValue() ?? field["default"].GetStringValue();

                    var internalVal = field["items"] != null ? field["items"]["type"].GetStringValue() : null;
                    type = TypeHelpers.GetAdditionalProperties(field) ?? TypeHelpers.MapType(field["type"].GetStringValue(), internalVal) ?? "string";
                    if (type == "Stream")
                    {
                        entityRepository.AddUsing(nameof(UsingKeys.SYSTEM_IO), UsingKeys.SYSTEM_IO);
                    }

                    if (paramIn == "path")
                    {
                        var param = new MyParameterContainer
                        {
                            Key          = _entity_fieldname,
                            ParamType    = type,
                            External     = true,
                            Required     = required,
                            FieldName    = _name ?? _parameter_fieldname ?? _api_fieldname,
                            DefaultValue = defaultValue,
                        };
                        pathParams.Add(param);
                    }

                    if (paramIn == "query")
                    {
                        var param = new MyParameterContainer
                        {
                            Key          = _entity_fieldname,
                            ParamType    = type,
                            External     = true,
                            Required     = required,
                            FieldName    = _name ?? _api_fieldname,
                            DefaultValue = defaultValue,
                        };
                        queryParams.Add(param);
                    }

                    if (paramIn == "body")
                    {
                        var param = new MyParameterContainer
                        {
                            Key          = _name?.ToPascal() ?? _entity_fieldname,
                            ParamType    = type,
                            External     = external,
                            Required     = required,
                            ReplaceBody  = replaceBody,
                            FieldName    = _api_fieldname,
                            CallContext  = external ? null : "request",
                            DefaultValue = defaultValue,
                        };
                        bodyParams.Add(param);
                    }

                    if (paramIn == "stream")
                    {
                        if (field["type"].GetStringValue() == "file")
                        {
                            var param = new MyParameterContainer
                            {
                                Key          = _entity_fieldname,
                                ParamType    = type,
                                External     = true,
                                Required     = required,
                                FieldName    = _name ?? _api_fieldname,
                                DefaultValue = defaultValue,
                            };
                            fileParams.Add(param);
                        }
                        else
                        {
                            var param = new MyParameterContainer
                            {
                                Key          = _entity_fieldname,
                                ParamType    = type,
                                External     = true,
                                Required     = required,
                                FieldName    = _name ?? _api_fieldname,
                                DefaultValue = defaultValue,
                            };
                            formParams.Add(param);
                        }
                    }
                }

                var filter = method["x_filter"];

                if (filter.Any())
                {
                    foreach (var filterValue in filter)
                    {
                        if (filterValue is JProperty filterValueProperty)
                        {
                            var filterValueName = filterValueProperty.Name;
                            var apiFilterName   = filterValueName;

                            var correspondingField = entity["fields"].FirstOrDefault(f => f["_key"].GetStringValue() == filterValueName);
                            if (correspondingField != null)
                            {
                                apiFilterName = correspondingField["api_fieldname"].GetStringValue();
                            }

                            var filterOperators = filterValueProperty.Children().FirstOrDefault();
                            if (filterOperators != null)
                            {
                                filterOperators.Children().ToList().ForEach(f =>
                                {
                                    var filterOperator = f.GetStringValue();
                                    var filterQueryKey = $"{apiFilterName}__{filterOperator}";
                                    var filterParam    = new MyParameterContainer
                                    {
                                        Key       = $"Filter.GetEncodedValue(\"{filterValueName}\", \"${filterOperator}\")",
                                        ParamType = "string",
                                        Required  = false,
                                        FieldName = filterQueryKey,
                                        External  = false,
                                    };
                                    queryParams.Add(filterParam);
                                });
                            }
                        }
                    }
                }

                var methodParams = new MyMethodParameterContainer(pathParams, isPaginated ? new List <MyParameterContainer>() : queryParams, bodyParams, fileParams, formParams);

                // method is paginated, so create paginatedMethodContainer
                if (isPaginated == true)
                {
                    var listOptionsName = CustomQueryOptionsGenerator.GenerateCustomQueryOptions(method, entity["fields"], entityPascalName, returns, rootFilePath, entityGroup, compilation);

                    methodParams.Parameters.Insert(0, new MyParameterContainer
                    {
                        Key       = "options",
                        ParamType = $"I{listOptionsName}",
                        Required  = false,
                    });
                    var paginatedMethodContainer = new PaginatedMethodContainer
                    {
                        EntityName       = entityPascalName,
                        Name             = methodName,
                        HttpMethod       = httpMethod,
                        Path             = path,
                        Paginated        = isPaginated,
                        Returns          = returns,
                        PathParams       = pathParams,
                        QueryParams      = queryParams,
                        BodyParams       = bodyParams,
                        FileParams       = fileParams,
                        FormParams       = formParams,
                        MethodParams     = methodParams,
                        CustomMethodCall = isCustomMethodCall,
                        CustomMethodName = customMethodName,
                        privateMethod    = isPrivateMethod,
                        ListOptionsName  = $"I{listOptionsName}",
                    };

                    paginatedMethodContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);

                    entityRepository.AddMethod(paginatedMethodContainer.Name, paginatedMethodContainer);
                }
                else if (isCustomMethodCall)
                {
                    var customMethodParams = new MethodParameterContainer();
                    customMethodParams.Parameters = new List <ParameterContainer>()
                    {
                        new MyParameterContainer
                        {
                            Key       = "model",
                            ParamType = entityPascalName,
                            Required  = true,
                            External  = true,
                            FieldName = "model",
                        }
                    };
                    // custom method call
                    var customFunctionMethodContainer = new CustomFunctionMethodContainer
                    {
                        EntityName       = entityPascalName,
                        Name             = methodName,
                        Returns          = returns,
                        MethodParams     = customMethodParams,
                        CustomMethodCall = isCustomMethodCall,
                        CustomMethodName = customMethodName,
                        privateMethod    = isPrivateMethod,
                        IsAsync          = true,
                    };

                    customFunctionMethodContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);

                    entityRepository.AddMethod(customFunctionMethodContainer.Name, customFunctionMethodContainer);
                }
                else
                {
                    var methodContainer = new DefaultMethodContainer()
                    {
                        EntityName       = entityPascalName,
                        Name             = methodName,
                        HttpMethod       = httpMethod,
                        Path             = path,
                        Paginated        = isPaginated,
                        Returns          = returns,
                        PathParams       = pathParams,
                        QueryParams      = queryParams,
                        BodyParams       = bodyParams,
                        FileParams       = fileParams,
                        FormParams       = formParams,
                        MethodParams     = methodParams,
                        CustomMethodCall = isCustomMethodCall,
                        CustomMethodName = customMethodName,
                        privateMethod    = isPrivateMethod,
                        IsAsync          = true,
                        HasRequest       = hasRequest,
                        IsVoidTask       = isVoid,
                        UseAnnonBody     = ((methodName == "AddToGroup" || methodName == "RemoveFromGroup") && entityPascalName == "Device")
                    };

                    if (isPrivateMethod)
                    {
                        methodContainer.AddModifier(nameof(Modifiers.INTERNAL), Modifiers.INTERNAL);
                    }
                    else
                    {
                        methodContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);
                    }

                    entityRepository.AddMethod(methodContainer.Name, methodContainer);
                }
            }

            if (methods.Any())
            {
                entityRepository.AddUsing(nameof(UsingKeys.ASYNC), UsingKeys.ASYNC);
                entityRepository.AddUsing(nameof(UsingKeys.EXCEPTIONS), UsingKeys.EXCEPTIONS);
                entityRepository.AddUsing(nameof(UsingKeys.GENERIC_COLLECTIONS), UsingKeys.GENERIC_COLLECTIONS);
                entityRepository.AddUsing(nameof(UsingKeys.SYSTEM), UsingKeys.SYSTEM);
                entityRepository.AddUsing(nameof(UsingKeys.CLIENT), UsingKeys.CLIENT);
            }

            compilation.AddClass(entityRepository.Name, entityRepository);

            var entityRepositoryInterface = entityRepository.Copy();

            // entityRepositoryInterface.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);
            entityRepositoryInterface.Name     = $"I{entityRepository.Name}";
            entityRepositoryInterface.FilePath = $"{rootFilePath}/{entityGroup}/{entityPascalName}/";
            entityRepositoryInterface.FileName = $"I{entityRepository.FileName}";
            entityRepositoryInterface.BaseTypes.Clear();
            entityRepositoryInterface.IsInterface = true;

            compilation.AddClass(entityRepositoryInterface.Name, entityRepositoryInterface);
        }
Exemple #3
0
        public static void GenerateEntityClass(JToken entity, string entityPascalName, string rootFilePath, string entityGroup, Compilation compilation)
        {
            var entityClass = new ClassContainer();

            // namespace
            entityClass.Namespace = UsingKeys.FOUNDATION;

            // modifier (just public for now)
            entityClass.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);

            // name
            entityClass.Name = entityPascalName;

            // base type
            entityClass.AddBaseType("BASE_ENTITY", "Entity");
            entityClass.AddUsing(nameof(UsingKeys.SDK_COMMON), UsingKeys.SDK_COMMON);

            // add interface
            entityClass.AddBaseType("Interface", $"I{entityClass.Name}");

            // doc (just use the name for now)
            entityClass.DocString = entityClass.Name;

            // set the filepath root/groupId/Class/Class.cs
            entityClass.FilePath = $"{rootFilePath}/{entityGroup}/{entityClass.Name}/";
            entityClass.FileName = $"{entityClass.Name}.cs";

            // add rename dictionary if any
            if (entity["field_renames"].Count() > 0)
            {
                var renameContainer = new RenameContainer();
                foreach (var rename in entity["field_renames"])
                {
                    var left  = rename["_key"].GetStringValue().ToPascal();
                    var right = rename["api_fieldname"].GetStringValue();

                    renameContainer.AddRename(left, right);
                }

                entityClass.AddPrivateField("RENAMES", renameContainer);

                entityClass.AddUsing(nameof(UsingKeys.GENERIC_COLLECTIONS), UsingKeys.GENERIC_COLLECTIONS);
            }

            // get properties
            var properties = entity["fields"].Where(p => p["_key"].GetStringValue() != "id");

            foreach (var property in properties)
            {
                // extract info from config
                var name = property["_key"].GetStringValue().ToPascal();
                // docstring, fall back to name when no description is provided
                // TODO restore when multiline comment issue is solved
                // var docString = property["description"].GetStringValue() ?? property["_key"].GetStringValue();
                var docString = property["_key"].GetStringValue();

                var isReadOnly = property["readOnly"].GetBoolValue();

                // get type
                var propertyType = TypeHelpers.GetPropertyType(property, entityClass);

                var customGetter = property["getter_custom_method"] != null;
                var customSetter = property["setter_custom_method"] != null;

                var isNullable = isNullableType(propertyType, property);

                if (customGetter || customSetter)
                {
                    var overridePropContainer = new PropertyWithCustomGetterAndSetter
                    {
                        Name             = name,
                        DocString        = docString,
                        PropertyType     = propertyType,
                        GetAccessor      = customGetter,
                        SetAccessor      = customSetter,
                        CustomGetterName = property["getter_custom_method"].GetStringValue().ToPascal(),
                        CustomSetterName = property["setter_custom_method"].GetStringValue().ToPascal(),
                        IsNullable       = isNullable,
                    };

                    // can assume public
                    overridePropContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);

                    entityClass.AddProperty(name, overridePropContainer);
                    // need common for custom functions
                    entityClass.AddUsing(nameof(UsingKeys.SDK_COMMON), UsingKeys.SDK_COMMON);
                    entityClass.AddUsing(nameof(UsingKeys.JSON), UsingKeys.JSON);

                    var backingField = new PrivateFieldContainer
                    {
                        Name      = name.PascalToCamel(),
                        FieldType = propertyType,
                    };
                    backingField.AddModifier(nameof(Modifiers.INTERNAL), Modifiers.INTERNAL);

                    entityClass.AddPrivateField($"{name}_BACKING_FIELD", backingField);
                }
                else if (propertyType == "DateTime")
                {
                    var format = property["format"].GetStringValue();

                    var propContainer = new DateTimePropertyContainer()
                    {
                        Name                = name,
                        DocString           = docString,
                        PropertyType        = propertyType,
                        IsNullable          = isNullable,
                        SetAccessorModifier = isReadOnly ? Modifiers.INTERNAL : Modifiers.PUBLIC,
                        DateFormat          = format,
                    };

                    propContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);

                    entityClass.AddProperty(name, propContainer);
                    entityClass.AddUsing(nameof(UsingKeys.JSON), UsingKeys.JSON);
                }
                else
                {
                    var propContainer = new PropertyWithSummaryContainer()
                    {
                        Name                = name,
                        DocString           = docString,
                        PropertyType        = propertyType,
                        IsNullable          = isNullable,
                        SetAccessorModifier = isReadOnly ? Modifiers.INTERNAL : Modifiers.PUBLIC,
                    };

                    propContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);

                    entityClass.AddProperty(name, propContainer);
                }

                // add usings for foreign keys
                var foreignKey = property["items"] != null ? property["items"]["foreign_key"] : null;
                if (foreignKey != null)
                {
                    var foreignKeyName = foreignKey["entity"].GetStringValue().ToPascal();
                    entityClass.AddUsing("FOREIGN_KEY", UsingKeys.FOUNDATION);
                }

                // add usings for date time
                if (propertyType == "DateTime")
                {
                    entityClass.AddUsing(nameof(UsingKeys.SYSTEM), UsingKeys.SYSTEM);
                }

                // add usings for date time
                if (propertyType == "Filter")
                {
                    entityClass.AddUsing(nameof(UsingKeys.FILTERS), UsingKeys.FILTERS);
                }

                // add usings for list
                if (propertyType.Contains("List<") || propertyType.Contains("Dictionary<"))
                {
                    entityClass.AddUsing(nameof(UsingKeys.GENERIC_COLLECTIONS), UsingKeys.GENERIC_COLLECTIONS);
                }
            }

            compilation.AddClass(entityClass.Name, entityClass);

            var entityClassInterface = entityClass.Copy();

            // entityRepositoryInterface.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);
            entityClassInterface.Name     = $"I{entityClass.Name}";
            entityClassInterface.FilePath = $"{rootFilePath}/{entityGroup}/{entityPascalName}/";
            entityClassInterface.FileName = $"I{entityClass.FileName}";
            entityClassInterface.BaseTypes.Clear();
            entityClassInterface.IsInterface = true;

            compilation.AddClass(entityClassInterface.Name, entityClassInterface);
        }