From 870d81a7c5dc11053335c4f431635743f6500272 Mon Sep 17 00:00:00 2001 From: myznikov Date: Wed, 5 Feb 2025 16:05:59 +0300 Subject: [PATCH] feat: added templates for Java + Spring. added new params for generation --- .../OperationGenerationModel.swift | 6 +- .../CodeGenerator/Models/PropertyModel.swift | 20 ++++++- .../Models/ServiceMethod/OperationModel.swift | 8 ++- .../TreeParserStage/TreeParser/Resolver.swift | 16 ++++- .../TreeParser/TreeParser.swift | 7 ++- .../Builders/AnySchemaBuilder.swift | 58 ++++++++++++++----- .../Builders/AnyServiceBuilder.swift | 8 +-- Sources/GASTTree/PropertyNode.swift | 17 +++++- Sources/GASTTree/Services/OperationNode.swift | 7 ++- .../OperationGenerationModel.swift | 14 +++-- .../Parsers/OperationNodeParser.swift | 12 ++-- Templates/v2/Java/api.stencil | 25 ++++++++ Templates/v2/Java/config/java.config.yaml | 31 ++++++++++ Templates/v2/Java/controller.stencil | 45 ++++++++++++++ Templates/v2/Java/dto.stencil | 24 ++++++++ Templates/v2/Java/enum.stencil | 30 ++++++++++ 16 files changed, 287 insertions(+), 41 deletions(-) create mode 100644 Templates/v2/Java/api.stencil create mode 100644 Templates/v2/Java/config/java.config.yaml create mode 100644 Templates/v2/Java/controller.stencil create mode 100644 Templates/v2/Java/dto.stencil create mode 100644 Templates/v2/Java/enum.stencil diff --git a/Sources/CodeGenerator/Models/GenerationModels/OperationGenerationModel.swift b/Sources/CodeGenerator/Models/GenerationModels/OperationGenerationModel.swift index fc6ea8c8..56cd2209 100644 --- a/Sources/CodeGenerator/Models/GenerationModels/OperationGenerationModel.swift +++ b/Sources/CodeGenerator/Models/GenerationModels/OperationGenerationModel.swift @@ -1,6 +1,6 @@ // // OperationGenerationModel.swift -// +// // // Created by Александр Кравченков on 19.10.2021. // @@ -63,11 +63,13 @@ public struct OperationGenerationModel: Encodable { public let requestModel: Reference? public let pathParameters: [ParameterModel] + public let headerParameters: [ParameterModel] public let queryParameters: [ParameterModel] public let requestGenerationModel: DataGenerationModel? public let responseGenerationModel: Keyed? public let allGenerationResponses: [ResponseGenerationModel]? + public let id: String? init(operationModel: OperationModel) { self.httpMethod = operationModel.httpMethod @@ -82,6 +84,7 @@ public struct OperationGenerationModel: Encodable { .map { $0.value } .sorted { $0.name < $1.name } self.pathParameters = allParameters.filter { $0.location == .path } + self.headerParameters = allParameters.filter { $0.location == .header } self.queryParameters = allParameters.filter { $0.location == .query } let request = operationModel.requestModel?.value @@ -108,6 +111,7 @@ public struct OperationGenerationModel: Encodable { responses: response.values.map { DataGenerationModel(dataModel: $0) } ) } + self.id = operationModel.id } } diff --git a/Sources/CodeGenerator/Models/PropertyModel.swift b/Sources/CodeGenerator/Models/PropertyModel.swift index ddf0207a..e46382ec 100644 --- a/Sources/CodeGenerator/Models/PropertyModel.swift +++ b/Sources/CodeGenerator/Models/PropertyModel.swift @@ -80,6 +80,12 @@ public struct PropertyModel { public let type: PossibleType public let isNullable: Bool public let pattern: String? + public let example: Any? + public let format: String? + public let minimum: Double? + public let maximum: Double? + public let maxLength: Int? + public let minLength: Int? /// This value will be used as type for generation public let typeModel: ItemTypeModel @@ -88,7 +94,13 @@ public struct PropertyModel { description: String?, type: PropertyModel.PossibleType, isNullable: Bool, - pattern: String?) { + pattern: String?, + example: Any?, + format: String?, + minimum: Double?, + maximum: Double?, + minLength: Int?, + maxLength: Int?) { self.name = name self.description = description self.type = type @@ -99,6 +111,12 @@ public struct PropertyModel { enumTypeName: type.enumTypeName, aliasTypeName: type.aliasTypeName) self.pattern = pattern + self.example = example + self.format = format + self.minimum = minimum + self.maximum = maximum + self.minLength = minLength + self.maxLength = maxLength } } diff --git a/Sources/CodeGenerator/Models/ServiceMethod/OperationModel.swift b/Sources/CodeGenerator/Models/ServiceMethod/OperationModel.swift index 94fd48ac..381041b4 100644 --- a/Sources/CodeGenerator/Models/ServiceMethod/OperationModel.swift +++ b/Sources/CodeGenerator/Models/ServiceMethod/OperationModel.swift @@ -1,6 +1,6 @@ // // OperationModel.swift -// +// // // Created by Александр Кравченков on 17.12.2020. // @@ -56,19 +56,21 @@ public struct OperationModel: Encodable { public let parameters: [Reference]? public let responses: [Reference]? public let requestModel: Reference? + public let id: String? init(httpMethod: String, summary: String?, description: String?, parameters: [Reference]?, responses: [Reference]?, - requestModel: Reference?) { + requestModel: Reference?, + id: String?) { self.httpMethod = httpMethod self.summary = summary - self.description = description self.parameters = parameters self.responses = responses self.requestModel = requestModel + self.id = id } } diff --git a/Sources/CodeGenerator/Stages/TreeParserStage/TreeParser/Resolver.swift b/Sources/CodeGenerator/Stages/TreeParserStage/TreeParser/Resolver.swift index 4e1ca357..376df47b 100644 --- a/Sources/CodeGenerator/Stages/TreeParserStage/TreeParser/Resolver.swift +++ b/Sources/CodeGenerator/Stages/TreeParserStage/TreeParser/Resolver.swift @@ -191,13 +191,25 @@ public class Resolver { description: property.description, type: .array(.init(name: "", itemsType: try arrayItemTypeUnwrapper(arr.itemsType))), isNullable: property.nullable, - pattern: property.pattern) + pattern: property.pattern, + example: property.example, + format: property.format, + minimum: property.minimum, + maximum: property.maximum, + minLength: property.minLength, + maxLength: property.maxLength) case .simple(let val): return .init(name: property.name, description: property.description, type: try propertyTypeUnwrapper(val), isNullable: property.nullable, - pattern: property.pattern) + pattern: property.pattern, + example: property.example, + format: property.format, + minimum: property.minimum, + maximum: property.maximum, + minLength: property.minLength, + maxLength: property.maxLength) } } diff --git a/Sources/CodeGenerator/Stages/TreeParserStage/TreeParser/TreeParser.swift b/Sources/CodeGenerator/Stages/TreeParserStage/TreeParser/TreeParser.swift index 331fbf1b..01f774aa 100644 --- a/Sources/CodeGenerator/Stages/TreeParserStage/TreeParser/TreeParser.swift +++ b/Sources/CodeGenerator/Stages/TreeParserStage/TreeParser/TreeParser.swift @@ -1,6 +1,6 @@ // // File.swift -// +// // // Created by Александр Кравченков on 17.12.2020. // @@ -67,7 +67,7 @@ public struct TreeParser { func parse(operation: OperationNode, current: DependencyWithTree, other: [DependencyWithTree]) throws -> OperationModel { let params = try operation.parameters.map { parameter -> Reference in - + return try wrap( self.parametersParser.parse(parameter: parameter, current: current, other: other), message: "While parsing parameter \(parameter.view)") @@ -94,7 +94,8 @@ public struct TreeParser { description: operation.description, parameters: params, responses: responses, - requestModel: requestBody + requestModel: requestBody, + id: operation.id ) } } diff --git a/Sources/GASTBuilder/Builders/AnySchemaBuilder.swift b/Sources/GASTBuilder/Builders/AnySchemaBuilder.swift index 5d25b976..094d95ab 100644 --- a/Sources/GASTBuilder/Builders/AnySchemaBuilder.swift +++ b/Sources/GASTBuilder/Builders/AnySchemaBuilder.swift @@ -161,34 +161,66 @@ public struct AnySchemaBuilder: SchemaBuilder { func build(object: ObjectSchema, meta: Metadata, name: String, apiDefinitionFileRef: String) throws -> SchemaModelNode { let properties = try object.properties.map { property -> PropertyNode in - let type = try wrap(property.schema.extractType(), - message: "In object \(name), in property \(property.name)") - + let schema = property.schema + let type = try wrap( + schema.extractType(), + message: "In object \(name), in property \(property.name)" + ) var isNullable = property.isNullable - if self.useNewNullableDeterminationStrategy { - isNullable = property.schema.metadata.nullable + isNullable = schema.metadata.nullable } var pattern: String? + var format: String? + var minimum: Double? + var maximum: Double? + var minLength: Int? + var maxLength: Int? - switch property.schema.type { + switch schema.type { case .string(let stringSchema): pattern = stringSchema.pattern + format = stringSchema.format?.rawValue + minLength = stringSchema.minLength + maxLength = stringSchema.maxLength + + case .number(let numberSchema): + format = numberSchema.format?.rawValue + minimum = numberSchema.minimum + maximum = numberSchema.maximum + + case .integer(let integerSchema): + format = integerSchema.format?.rawValue + minimum = integerSchema.minimum.flatMap(Double.init) + maximum = integerSchema.maximum.flatMap(Double.init) + default: break } - return PropertyNode(name: property.name, - type: type, - description: property.schema.metadata.description, - example: property.schema.metadata.example, - nullable: isNullable, - pattern: pattern) + return PropertyNode( + name: property.name, + type: type, + description: schema.metadata.description, + example: schema.metadata.example, + nullable: isNullable, + pattern: pattern, + format: format, + minimum: minimum, + maximum: maximum, + maxLength: maxLength, + minLength: minLength + ) } - return SchemaModelNode(name: name, properties: properties, description: meta.description, apiDefinitionFileRef: apiDefinitionFileRef) + return SchemaModelNode( + name: name, + properties: properties, + description: meta.description, + apiDefinitionFileRef: apiDefinitionFileRef + ) } func build(array: ArraySchema, name: String, apiDefinitionFileRef: String) throws -> SchemaArrayNode { diff --git a/Sources/GASTBuilder/Builders/AnyServiceBuilder.swift b/Sources/GASTBuilder/Builders/AnyServiceBuilder.swift index 375a8ae8..b4105d2a 100644 --- a/Sources/GASTBuilder/Builders/AnyServiceBuilder.swift +++ b/Sources/GASTBuilder/Builders/AnyServiceBuilder.swift @@ -1,6 +1,6 @@ // // AnyServiceBuilder.swift -// +// // // Created by Александр Кравченков on 14.12.2020. // @@ -17,7 +17,7 @@ public protocol ServiceBuilder { } /// Default implementation for `ServiceBuilder` -/// +/// /// Builds `path` elements of Open-API spec /// /// **WARNING** @@ -34,7 +34,6 @@ public struct AnyServiceBuilder: ServiceBuilder { let schemaBuilder: SchemaBuilder let requestBodyBuilder: RequestBodyBuilder let responseBuilder: ResponseBuilder - public init(parameterBuilder: ParametersBuilder, schemaBuilder: SchemaBuilder, requestBodyBuilder: RequestBodyBuilder, @@ -93,7 +92,8 @@ extension AnyServiceBuilder { summary: operation.summary, parameters: params, requestBody: requestBody, - responses: responses) + responses: responses, + id: operation.generatedIdentifier) } } diff --git a/Sources/GASTTree/PropertyNode.swift b/Sources/GASTTree/PropertyNode.swift index e9d30922..ede3bedb 100644 --- a/Sources/GASTTree/PropertyNode.swift +++ b/Sources/GASTTree/PropertyNode.swift @@ -20,19 +20,34 @@ public struct PropertyNode { public let example: Any? public let nullable: Bool public let pattern: String? + public let format: String? + public let minimum: Double? + public let maximum: Double? + public let maxLength: Int? + public let minLength: Int? public init(name: String, type: PossibleType, description: String?, example: Any?, nullable: Bool, - pattern: String?) { + pattern: String?, + format: String?, + minimum: Double?, + maximum: Double?, + maxLength: Int?, + minLength: Int?) { self.name = name self.type = type self.description = description self.example = example self.nullable = nullable self.pattern = pattern + self.format = format + self.minimum = minimum + self.maximum = maximum + self.minLength = minLength + self.maxLength = maxLength } } diff --git a/Sources/GASTTree/Services/OperationNode.swift b/Sources/GASTTree/Services/OperationNode.swift index c5713fdd..ca0b5299 100644 --- a/Sources/GASTTree/Services/OperationNode.swift +++ b/Sources/GASTTree/Services/OperationNode.swift @@ -1,6 +1,6 @@ // // OperationNode.swift -// +// // // Created by Александр Кравченков on 14.12.2020. // @@ -27,18 +27,21 @@ public struct OperationNode { public let parameters: [Referenced] public let requestBody: Referenced? public let responses: [ResponseBody] + public let id: String? public init(method: String, description: String?, summary: String?, parameters: [Referenced], requestBody: Referenced?, - responses: [ResponseBody]) { + responses: [ResponseBody], + id: String?) { self.method = method self.description = description self.summary = summary self.parameters = parameters self.requestBody = requestBody self.responses = responses + self.id = id } } diff --git a/Sources/SurfGenKit/Models/GenerationModels/OperationGenerationModel.swift b/Sources/SurfGenKit/Models/GenerationModels/OperationGenerationModel.swift index 92841f42..c3335391 100644 --- a/Sources/SurfGenKit/Models/GenerationModels/OperationGenerationModel.swift +++ b/Sources/SurfGenKit/Models/GenerationModels/OperationGenerationModel.swift @@ -1,6 +1,6 @@ // // OperationGenerationModel.swift -// +// // // Created by Dmitry Demyanov on 04.11.2020. // @@ -11,7 +11,7 @@ enum HttpMethod: String { case patch case put case delete - + var name: String { switch self { case .get, .post, .delete: @@ -29,7 +29,7 @@ enum ResponseBody: Equatable { } public struct OperationGenerationModel { - + private enum Constants { static let multipartModel = "MultipartModel" } @@ -46,11 +46,12 @@ public struct OperationGenerationModel { let hasBody: Bool var requestBody: RequestBodyGenerationModel? + let id: String? private(set) var hasUndefinedResponseBody = false private(set) var hasResponseModel = false private(set) var responseModel: String? - + init(name: String, description: String?, path: PathGenerationModel, @@ -58,7 +59,8 @@ public struct OperationGenerationModel { pathParameters: [ParameterGenerationModel], queryParameters: [ParameterGenerationModel], requestBody: RequestBodyGenerationModel.BodyType?, - responseBody: ResponseBody) { + responseBody: ResponseBody, + id: String?) { self.name = name self.hasDescription = description != nil self.description = description @@ -70,7 +72,7 @@ public struct OperationGenerationModel { self.queryParameters = queryParameters self.hasBody = requestBody != nil self.requestBody = RequestBodyGenerationModel(type: requestBody) - + self.id = id switch responseBody { case .model(let modelName): self.hasResponseModel = true diff --git a/Sources/SurfGenKit/Parsers/OperationNodeParser.swift b/Sources/SurfGenKit/Parsers/OperationNodeParser.swift index 68746a0d..b4ad4d10 100644 --- a/Sources/SurfGenKit/Parsers/OperationNodeParser.swift +++ b/Sources/SurfGenKit/Parsers/OperationNodeParser.swift @@ -1,6 +1,6 @@ // // OperationNodeParser.swift -// +// // // Created by Dmitry Demyanov on 07.11.2020. // @@ -17,7 +17,7 @@ class OperationNodeParser { private let mediaContentParser: MediaContentNodeParser private let parametersParser: ParametersNodeParser - + public var logger: Loger = DefaultLogger.default private let platform: Platform init(mediaContentParser: MediaContentNodeParser, parametersParser: ParametersNodeParser, platform: Platform) { @@ -80,7 +80,7 @@ class OperationNodeParser { let responseBody = try wrap(mediaContentParser.parseResponseBody(node: operation.subNodes.responseBodyNode, forOperationName: name), with: ErrorMessages.errorMessage(for: name)) - + return OperationGenerationModel(name: name, description: description, @@ -88,8 +88,10 @@ class OperationNodeParser { httpMethod: method, pathParameters: parameters.filter { $0.location == .path }, queryParameters: parameters.filter { $0.location == .query }, + headerParameters: parameters.filter { $0.location == .header }, requestBody: requestBody, - responseBody: responseBody) + responseBody: responseBody, + id: name) } - + } diff --git a/Templates/v2/Java/api.stencil b/Templates/v2/Java/api.stencil new file mode 100644 index 00000000..527bdf98 --- /dev/null +++ b/Templates/v2/Java/api.stencil @@ -0,0 +1,25 @@ +package ru.surf.surfgen.api.contract; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +@Tag(name = "{{ service.name }} API") +public interface {{ service.name }}Api { + {%for path in service.paths%} + {%for operation in path.operations%} + @Operation(summary = "{{ operation.summary }}") + {%if operation.httpMethod|lowercase == "delete"%} + @ResponseStatus(HttpStatus.NO_CONTENT) + {%endif%} + @{{ operation.httpMethod|capitalizeFirstLetter }}Mapping("{{ path.path }}") + {%if operation.httpMethod|lowercase == "delete"%}void{%else%}ResponseEntity<{{ operation.responseGenerationModel.value.typeNames|join }}>{%endif%} {{operation.id}}({%for parameter in operation.pathParameters%} + @PathVariable("{{ parameter.name }}") {{ parameter.typeModel.name|capitalizeFirstLetter }} {{ parameter.name|snakeCaseToCamelCase }}{%endfor%} + {%for parameter in operation.headerParameters%} + @RequestHeader(name = "{{ parameter.name }}", required={{ parameter.isRequired }}) String {{ parameter.schema.type|capitalizeFirstLetter }} {{ parameter.name|snakeCaseToCamelCase }}{%endfor%} + {%for parameter in operation.queryParameters%}@RequestParam(name = "{{ parameter.name }}", required={{ parameter.isRequired }}) {{ parameter.typeModel.name|capitalizeFirstLetter }} {{ parameter.name|snakeCaseToCamelCase }}{%endfor%} + {%for requestModelName in operation.requestGenerationModel.typeNames%}@Valid @RequestBody {{ requestModelName|capitalizeFirstLetter }} {{ requestModelName|snakeCaseToCamelCase }}{%endfor%}); + {%endfor%} + {%endfor%} +} \ No newline at end of file diff --git a/Templates/v2/Java/config/java.config.yaml b/Templates/v2/Java/config/java.config.yaml new file mode 100644 index 00000000..78afcb1b --- /dev/null +++ b/Templates/v2/Java/config/java.config.yaml @@ -0,0 +1,31 @@ +useNewNullableDeterminationStrategy: false + +prefixesToCutDownInServiceNames: + - /api/v1.1 + - /api/1.1 + +analytcsConfig: + logstashEnpointURI: http://logs.ps.surfstudio.ru + payload: + project: TEST + +templates: + - type: service + nameSuffix: Api + fileExtension: java + templatePath: + destinationPath: + - type: service + nameSuffix: Controller + fileExtension: java + templatePath: + destinationPath: + - type: model + nameSuffix: + fileExtension: java + templatePath: + destinationPath: + - type: enum + fileExtension: java + templatePath: + destinationPath: \ No newline at end of file diff --git a/Templates/v2/Java/controller.stencil b/Templates/v2/Java/controller.stencil new file mode 100644 index 00000000..cf997484 --- /dev/null +++ b/Templates/v2/Java/controller.stencil @@ -0,0 +1,45 @@ +package ru.surf.surfgen.controller; + +import ru.surf.surfgen.api.contract.{{ service.name }}Api; +import ru.surf.surfgen.service.{{ service.name }}Service; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequiredArgsConstructor +public class {{ service.name }}Controller implements {{ service.name }}Api { + private final {{ service.name }}Service {{ service.name|lowercaseFirstLetter }}Service; + + {%for path in service.paths%} + {%for operation in path.operations%} + @Override + public {%if operation.responseGenerationModel.key == "204"%}void{%else%}ResponseEntity<{{ operation.responseGenerationModel.value.typeNames|join }}>{%endif%} {{ operation.id }}( + {%for parameter in operation.pathParameters%}{{ parameter.typeModel.name|capitalizeFirstLetter }} {{ parameter.name|snakeCaseToCamelCase }}{%endfor%} + {%for parameter in operation.headerParameters%}{{ parameter.typeModel.name|capitalizeFirstLetter }} {{ parameter.name|snakeCaseToCamelCase }}{%endfor%} + {%for parameter in operation.queryParameters%}{{ parameter.typeModel.name|capitalizeFirstLetter }} {{ parameter.name|snakeCaseToCamelCase }}{%endfor%} + {%for requestModelName in operation.requestGenerationModel.typeNames%} {{ requestModelName|capitalizeFirstLetter }} {{ requestModelName|snakeCaseToCamelCase }}{%endfor%}) { + {%if operation.responseGenerationModel.key == "204"%} + {{ service.name|lowercaseFirstLetter }}Service.{{ operation.id }}( + {%for parameter in operation.pathParameters%}{{ parameter.name|snakeCaseToCamelCase }}{%endfor%} + {%for parameter in operation.headerParameters%}{{ parameter.typeModel.name|capitalizeFirstLetter }} {{ parameter.name|snakeCaseToCamelCase }}{%endfor%} + {%for parameter in operation.queryParameters%}{{ parameter.name|snakeCaseToCamelCase }}{%endfor%} + {%for requestModelName in operation.requestGenerationModel.typeNames%}{{ requestModelName|snakeCaseToCamelCase }}{%endfor%}); + {%else%} + return {%if operation.responseGenerationModel.key == "201"%}new ResponseEntity<>({{ service.name|lowercaseFirstLetter }}Service.{{ operation.id }}( + {%for parameter in operation.pathParameters%}{{ parameter.name|snakeCaseToCamelCase }}{%endfor%} + {%for parameter in operation.queryParameters%}{{ parameter.name|snakeCaseToCamelCase }}{%endfor%} + {%for parameter in operation.headerParameters%}{{ parameter.name|snakeCaseToCamelCase }}{%endfor%} + {%for requestModelName in operation.requestGenerationModel.typeNames%}{{ requestModelName|snakeCaseToCamelCase }}{%endfor%}), HttpStatus.CREATED); + {%else%} + ResponseEntity.ok({{ service.name|lowercaseFirstLetter }}Service.{{ operation.id }}( + {%for parameter in operation.pathParameters%}{{ parameter.name|snakeCaseToCamelCase }}{%endfor%} + {%for parameter in operation.queryParameters%}{{ parameter.name|snakeCaseToCamelCase }}{%endfor%} + {%for parameter in operation.headerParameters%}{{ parameter.name|snakeCaseToCamelCase }}{%endfor%} + {%for requestModelName in operation.requestGenerationModel.typeNames%}{{ requestModelName|snakeCaseToCamelCase }}{%endfor%})); + {%endif%} + {%endif%} + } + {%endfor%} + {%endfor%} +} \ No newline at end of file diff --git a/Templates/v2/Java/dto.stencil b/Templates/v2/Java/dto.stencil new file mode 100644 index 00000000..fd3f4ce5 --- /dev/null +++ b/Templates/v2/Java/dto.stencil @@ -0,0 +1,24 @@ +package ru.surf.surfgen.api.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.NoArgsConstructor; +import javax.validation.constraints.*; +import java.util.List; +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Data +@NoArgsConstructor +public class {{ model.name }} { + {% for property in model.properties %} + @Schema( description = "{{ property.description }}"{% if property.example %}, example = "{{ property.example }}"{% else %}){% endif %}{% if not property.isNullable %} + @NotNull{% if property.typeModel.name == "string" %} + @NotBlank{% endif %}{% elif property.isNullable %} + @Nullable{% endif %}{% if property.typeModel.name == "string" %}{% if property.minLength or property.maxLength %} + @Size(min = {{ property.minLength }}, max = {{ property.maxLength }}){% endif %}{% elif property.typeModel.name == "integer" %}{% if property.minimum or property.maximum %} + @Min({{ property.minimum}}) + @Max({{ property.maximum }}){% endif %}{% endif %} + private {% if property.typeModel.isArray %}List<{{ property.typeModel.name|capitalizeFirstLetter }}>{% else %}{% if property.typeModel.name == "integer" %}{% if property.format == "int64" %}Long{% else %}Integer{% endif %}{% elif property.typeModel.name == "number" %}Double{% elif property.typeModel.name == "string" %}{% if property.format == "date-time" %}LocalDateTime{% elif property.format == "date" %}LocalDate{% else %}String{% endif %}{% else %}{{ property.typeModel.name|capitalizeFirstLetter }}{% endif %}{% endif %} {{ property.name|snakeCaseToCamelCase }}; + {% endfor %} +} \ No newline at end of file diff --git a/Templates/v2/Java/enum.stencil b/Templates/v2/Java/enum.stencil new file mode 100644 index 00000000..4ffdb749 --- /dev/null +++ b/Templates/v2/Java/enum.stencil @@ -0,0 +1,30 @@ +{% if enum.description %}/** + {% for line in enum.description|splitLines %}* {{ line }} + {% endfor %}*/ +{% endif %}public enum {{ enum.name }} { + {% for caseValue in enum.cases %}{# + #}{{ caseValue|uppercase }}("{{ caseValue }}"){% if not forloop.last %},{% else %};{% endif %} + {% endfor %} + + private final String value; + + {{ enum.name }}(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public static {{ enum.name }} getBy(String value) { + if (value == null) { + return null; + } + for ({{ enum.name }} item : values()) { + if (item.value.equals(value)) { + return item; + } + } + return null; + } +} \ No newline at end of file