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); }
public static string GenerateCustomQueryOptions(JToken method, JToken fields, string entityName, string returns, string rootFilePath, string entityGroup, Compilation compilation) { var optionsName = $"{TypeHelpers.GetListOptionsName(entityName, returns)}ListOptions"; var extraQueryParams = method["fields"].Where( q => q["in"].GetStringValue() == "query" && q["_key"].GetStringValue() != "after" && q["_key"].GetStringValue() != "include" && q["_key"].GetStringValue() != "limit" && q["_key"].GetStringValue() != "order" ).ToList(); var customQueryOptions = new ClassContainer(); // namespace customQueryOptions.Namespace = UsingKeys.FOUNDATION; // modifier (just public for now) customQueryOptions.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC); // name customQueryOptions.Name = optionsName; // base type customQueryOptions.AddBaseType("BASE_LIST_OPTIONS", "QueryOptions"); customQueryOptions.AddUsing(nameof(UsingKeys.SDK_COMMON), UsingKeys.SDK_COMMON); // interface customQueryOptions.AddBaseType("BASE_LIST_OPTIONS_INTERFACE", $"I{customQueryOptions.Name}"); // doc (just use the name for now) customQueryOptions.DocString = customQueryOptions.Name; // set the filepath root/groupId/Class/Class.cs customQueryOptions.FilePath = $"{rootFilePath}/{entityGroup}/{entityName}/"; customQueryOptions.FileName = $"{customQueryOptions.Name}.cs"; if (extraQueryParams.Count > 0) { extraQueryParams.ForEach(e => { var propContainer = new PropertyWithSummaryContainer { Name = e["_key"].GetStringValue().ToPascal(), PropertyType = "string", }; propContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC); customQueryOptions.AddProperty(propContainer.Name, propContainer); }); } var filter = method["x_filter"]; if (filter.Any()) { var filterPropertyContainer = new PropertyWithSummaryContainer { Name = "Filter", PropertyType = "Filter", DocString = "Filter object", }; filterPropertyContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC); customQueryOptions.AddUsing(nameof(UsingKeys.FILTERS), UsingKeys.FILTERS); customQueryOptions.AddProperty(filterPropertyContainer.Name, filterPropertyContainer); foreach (var filterValue in filter) { if (filterValue is JProperty filterValueProperty) { var filterValueName = filterValueProperty.Name; var filterType = "string"; var correspondingField = fields.FirstOrDefault(f => f["_key"].GetStringValue() == filterValueName); if (correspondingField != null) { filterType = TypeHelpers.GetPropertyType(correspondingField, customQueryOptions); if (filterType == "DateTime") { customQueryOptions.AddUsing(nameof(UsingKeys.SYSTEM), UsingKeys.SYSTEM); } // add usings for list if (filterType.Contains("List<") || filterType.Contains("Dictionary<")) { customQueryOptions.AddUsing(nameof(UsingKeys.GENERIC_COLLECTIONS), UsingKeys.GENERIC_COLLECTIONS); } } var filterOperators = filterValueProperty.Children().FirstOrDefault(); if (filterOperators != null) { filterOperators.Children().ToList().ForEach(f => { var filterOperator = f.GetStringValue(); string enumerableFilterType = null; if (filterOperator == "in" || filterOperator == "nin") { enumerableFilterType = $"{filterType}[]"; customQueryOptions.AddUsing(nameof(UsingKeys.GENERIC_COLLECTIONS), UsingKeys.GENERIC_COLLECTIONS); } var methodName = $"{filterValueName}{TypeHelpers.MapFilterName(filterOperator)}".ToPascal(); var filterMethodParams = new MethodParameterContainer { Parameters = new List <ParameterContainer>() { new ParameterContainer { Key = "value", ParamType = enumerableFilterType ?? filterType, Required = true, MyModifiers = !string.IsNullOrEmpty(enumerableFilterType) ? new Dictionary <string, SyntaxToken> { { nameof(Modifiers.PARAMS), Modifiers.PARAMS } } : new Dictionary <string, SyntaxToken>(), } } }; var filterMethodContainer = new FilterExtensionMethodContainer { Name = methodName, Returns = optionsName, MethodParams = filterMethodParams, FilterKey = filterValueName, FilterOperator = filterOperator, }; filterMethodContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC); customQueryOptions.AddMethod(methodName, filterMethodContainer); }); } } } var customQueryOptionsConstructor = new ListOptionsConstructor { Name = customQueryOptions.Name, }; customQueryOptionsConstructor.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC); customQueryOptions.AddConstructor(nameof(customQueryOptionsConstructor), customQueryOptionsConstructor); } compilation.AddClass($"{entityGroup}-{entityName}-{returns}", customQueryOptions); var customQueryOptionsInterface = customQueryOptions.Copy(); // entityRepositoryInterface.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC); customQueryOptionsInterface.Name = $"I{optionsName}"; customQueryOptionsInterface.FilePath = $"{rootFilePath}/{entityGroup}/{entityName}/"; customQueryOptionsInterface.FileName = $"I{customQueryOptions.FileName}"; customQueryOptionsInterface.IsInterface = true; customQueryOptionsInterface.BaseTypes.Clear(); customQueryOptionsInterface.AddBaseType("BASE_LIST_OPTIONS_INTERFACE", "IQueryOptions"); compilation.AddClass($"{entityGroup}-{entityName}-{returns}-interface", customQueryOptionsInterface); return(optionsName); }