Skip to content

Commit 7c78506

Browse files
committed
feat: add support for Kotlin+SpringBoot ProjectTemplates
1 parent b0571b8 commit 7c78506

File tree

10 files changed

+74
-11
lines changed

10 files changed

+74
-11
lines changed

plugins/customizations/kotlin-backend-application/src/main/java/io/zenwave360/sdk/plugins/kotlin/OpenAPIControllersKotlinHelpers.java

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package io.zenwave360.sdk.plugins.kotlin;
22

33
import com.github.jknack.handlebars.Options;
4+
import io.zenwave360.sdk.utils.JSONPath;
45
import io.zenwave360.sdk.zdl.utils.ZDLHttpUtils;
56
import io.zenwave360.sdk.zdl.utils.ZDLJavaSignatureUtils;
67

78
import java.io.IOException;
9+
import java.util.List;
810
import java.util.Map;
911
import java.util.stream.Collectors;
1012

@@ -21,7 +23,12 @@ public OpenAPIControllersKotlinHelpers(String openApiModelNamePrefix, String ope
2123
}
2224

2325
public String kotlinMethodParametersSignature(String methodParametersSignature, Options options) {
24-
return ZDLJavaSignatureUtils.toKotlinMethodSignature(methodParametersSignature);
26+
return ZDLJavaSignatureUtils.toKotlinMethodSignature(methodParametersSignature)
27+
.replaceAll(": Integer", ": Int");
28+
}
29+
30+
public String voidUnit(String returnType, Options options) {
31+
return returnType.replace("void", "Unit").replace("Void", "Unit");
2532
}
2633

2734
public CharSequence asMethodParametersInitializer(Object operation, Options options) throws IOException {
@@ -31,9 +38,46 @@ public CharSequence asMethodParametersInitializer(Object operation, Options opti
3138
return "";
3239
}
3340
return methodParams.stream()
34-
.map(param -> param.getValue() + ": " + param.getKey() + " = null;")
35-
.collect(Collectors.joining("\n"));
41+
.map(param -> "val " + param.getValue() + ": " + param.getKey() + " = " + instantiateParam((Map) operation, param.getValue(), param.getKey()))
42+
.collect(Collectors.joining("\n"))
43+
.replaceAll(" Integer ", " Int ");
3644
}
3745
return options.fn(operation);
3846
}
47+
48+
private String instantiateParam(Map operation, String paramName, String dtoName) {
49+
var params = JSONPath.get(operation, "parameters[?(@.name == '" + paramName + "')]", List.of());
50+
var param = params.isEmpty() ? null : params.get(0);
51+
var isArray = "array".equals(JSONPath.get(param, "schema.type"));
52+
var isEnum = JSONPath.get(param, "schema.enum") != null;
53+
if(isEnum) {
54+
return dtoName + "." + JSONPath.get(param, "schema.enum[0]");
55+
}
56+
if(isArray) {
57+
return "mutableListOf()";
58+
}
59+
var isNumber = "number".equals(JSONPath.get(param, "schema.type")) || "integer".equals(JSONPath.get(param, "schema.type"));
60+
var isBoolean = "boolean".equals(JSONPath.get(param, "schema.type"));
61+
var isString = "string".equals(JSONPath.get(param, "schema.type"));
62+
var isDate = "date".equals(JSONPath.get(param, "schema.format"));
63+
var isDateTime = "date-time".equals(JSONPath.get(param, "schema.format"));
64+
if(isNumber) {
65+
return "0";
66+
}
67+
if(isDate) {
68+
return "LocalDate.now()";
69+
}
70+
if(isDateTime) {
71+
return "Instant.now()";
72+
}
73+
if(isBoolean) {
74+
return "false";
75+
}
76+
if(isString) {
77+
return "\"\"";
78+
}
79+
var requiredFields = JSONPath.get(operation, "x--request-schema.required", List.<String>of()).stream()
80+
.map(it -> it + " = \"\"").collect(Collectors.joining(", "));
81+
return dtoName + "(" + requiredFields + ")";
82+
}
3983
}

plugins/customizations/kotlin-backend-application/src/main/resources/io/zenwave360/sdk/plugins/kotlin/BackendApplicationDefaultGenerator/src/main/kotlin/core/domain/jpa/Entity.kt.hbs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ data class {{entity.className}}(
166166
{{/each}}
167167

168168
{{#unless (skipEntityId entity)~}}
169+
override fun toString(): String {
170+
return this::class.java.name + "#" + id
171+
}
172+
169173
/* https://vladmihalcea.com/the-best-way-to-implement-equals-hashcode-and-tostring-with-jpa-and-hibernate/ */
170174
override fun equals(other: Any?): Boolean {
171175
if (this === other) return true
@@ -176,5 +180,9 @@ data class {{entity.className}}(
176180
override fun hashCode(): Int {
177181
return javaClass.hashCode()
178182
}
183+
{{else}}
184+
override fun toString(): String {
185+
return this::class.java.name + "@" + Integer.toHexString(hashCode())
186+
}
179187
{{~/unless}}
180188
}

plugins/customizations/kotlin-backend-application/src/main/resources/io/zenwave360/sdk/plugins/kotlin/BackendApplicationDefaultGenerator/src/main/kotlin/core/domain/mongodb/Entity.kt.hbs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ data class {{entity.className}}(
7272
{{/each}}
7373

7474
{{#unless (skipEntityId entity)~}}
75+
override fun toString(): String {
76+
return this::class.java.name + "#" + id
77+
}
78+
7579
/* https://vladmihalcea.com/the-best-way-to-implement-equals-hashcode-and-tostring-with-jpa-and-hibernate/ */
7680
override fun equals(other: Any?): Boolean {
7781
if (this === other) return true

plugins/customizations/kotlin-backend-application/src/main/resources/io/zenwave360/sdk/plugins/kotlin/BackendApplicationDefaultGenerator/src/main/kotlin/core/implementation/mappers/ServiceMapper.kt.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ interface {{service.name}}Mapper {
4646
{{~assign 'relationships' (findOwnedOneToManyRelationships entity)}}
4747
{{~#if relationships}}
4848
@AfterMapping
49-
fun manageRelationships(entity: {{entity.className}}) {
49+
fun manageRelationships(@MappingTarget entity: {{entity.className}}) {
5050
{{~#each relationships as |relationship|}}
5151
entity.{{relationship.fieldName}}?.forEach { {{relationship.fieldName}} ->
5252
{{relationship.fieldName}}.{{relationship.otherEntityFieldName}} = entity

plugins/customizations/kotlin-backend-application/src/main/resources/io/zenwave360/sdk/plugins/kotlin/BackendApplicationDefaultGenerator/src/test/kotlin/config/ServicesInMemoryConfig.kt.hbs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ open class ServicesInMemoryConfig : RepositoriesInMemoryConfig() {
5252

5353
{{~#each services as |service|}}
5454
@Bean
55-
fun <T : {{service.name}}> {{asInstanceName service.name}}(): T {
55+
open fun <T : {{service.name}}> {{asInstanceName service.name}}(): T {
5656
return {{asInstanceName service.name}} as T
5757
}
5858
{{~/each}}
@@ -79,9 +79,9 @@ open class ServicesInMemoryConfig : RepositoriesInMemoryConfig() {
7979

8080
{{~#if (includeEmitEventsImplementation service)}}
8181
{{~#if (needsEventsProducer service)}}
82-
fun getEventsProducerInMemoryContext(): EventsProducerInMemoryContext {
83-
return eventsProducerInMemoryContext
84-
}
82+
// fun getEventsProducerInMemoryContext(): EventsProducerInMemoryContext {
83+
// return eventsProducerInMemoryContext
84+
// }
8585
{{~/if}}
8686
{{~/if}}
8787
{{~#if (needsEventBus service)}}

plugins/customizations/kotlin-backend-application/src/main/resources/io/zenwave360/sdk/plugins/kotlin/OpenAPIControllersGenerator/src/main/kotlin/web/mappers/ServiceDTOsMapper.kt.hbs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {{layout.inboundDtosPackage}}.*
66
import {{openApiModelPackage}}.*
77

88
import org.mapstruct.Mapper
9+
import org.mapstruct.Mapping
910
import org.mapstruct.factory.Mappers
1011
import java.math.*
1112
import java.time.*
@@ -33,6 +34,7 @@ interface {{serviceName}}DTOsMapper {
3334
{{~#each mapperResponseDtoEntity as |entry|}}
3435
{{#if isResponsePaginated}}
3536
fun as{{responseDto}}List(entityList: List<{{outputType}}>): List<{{responseDto}}>
37+
@Mapping(target = "content", source = "content", conditionExpression = "java(page.getContent() != null)")
3638
fun as{{responseEntityName}}(page: Page<{{outputType}}>): {{responseEntityName}}
3739
fun as{{responseDto}}Page(page: Page<{{outputType}}>): Page<{{responseDto}}> {
3840
return page.map { this.as{{responseDto}}(it) }

plugins/customizations/kotlin-backend-application/src/main/resources/io/zenwave360/sdk/plugins/kotlin/OpenAPIControllersGenerator/src/main/kotlin/web/mvc/ServiceApiController.kt.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ open class {{serviceName}}ApiController(
5454
{{#each serviceOperations}}
5555
{{~#assign "TODO"}}{{#unless serviceMethod}}null // TODO: service{{/unless}}{{/assign}}
5656

57-
override fun {{operationId}}({{{kotlinMethodParametersSignature methodParameters}}}): ResponseEntity<{{{responseEntityExpression}}}> {
57+
override fun {{operationId}}({{{kotlinMethodParametersSignature methodParameters}}}): ResponseEntity<{{{voidUnit responseEntityExpression}}}> {
5858
log.debug("REST request to {{operationId}}: {{methodParameterPlaceholders}}"{{#if methodParameters}}, {{methodParameterInstances}}{{/if}})
5959
{{~#if (eq httpMethod 'patch')}}
6060
{{~else if requestBodySchema}}

plugins/customizations/kotlin-backend-application/src/test/java/io/zenwave360/sdk/plugins/kotlin/SpringWebTestClientKotlinGeneratorTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import io.zenwave360.sdk.writers.TemplateStdoutWriter;
1313
import io.zenwave360.sdk.writers.TemplateWriter;
1414
import org.junit.jupiter.api.Assertions;
15+
import org.junit.jupiter.api.Test;
1516
import org.junit.jupiter.params.ParameterizedTest;
1617
import org.junit.jupiter.params.provider.CsvSource;
1718

plugins/openapi-spring-webtestclient/src/main/java/io/zenwave360/sdk/plugins/SpringWebTestClientPlugin.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import io.zenwave360.sdk.Plugin;
44
import io.zenwave360.sdk.doc.DocumentedPlugin;
55
import io.zenwave360.sdk.parsers.DefaultYamlParser;
6+
import io.zenwave360.sdk.parsers.ZDLParser;
67
import io.zenwave360.sdk.processors.OpenApiProcessor;
8+
79
import io.zenwave360.sdk.writers.TemplateFileWriter;
810
import io.zenwave360.sdk.writers.TemplateStdoutWriter;
911
import org.apache.commons.lang3.StringUtils;
@@ -19,7 +21,7 @@ public class SpringWebTestClientPlugin extends Plugin {
1921
private Logger log = LoggerFactory.getLogger(getClass());
2022
public SpringWebTestClientPlugin() {
2123
super();
22-
withChain(DefaultYamlParser.class, OpenApiProcessor.class, SpringWebTestClientGenerator.class, /* JavaFormatter.class, */ TemplateFileWriter.class);
24+
withChain(ZDLParser.class, DefaultYamlParser.class, OpenApiProcessor.class, SpringWebTestClientGenerator.class, /* JavaFormatter.class, */ TemplateFileWriter.class);
2325
}
2426

2527
@Override

zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/generators/EntitiesToSchemasConverter.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ public Map<String, Object> convertEntityToSchema(Map<String, Object> entity, Map
7676
if (includeVersion) {
7777
properties.put("version", Maps.of(
7878
"type", "integer",
79-
"description", "Version of the document (required in PUT for concurrency control, should be null in POSTs)."));
79+
"default", "null",
80+
"description", "Version of the document (required in PUT for concurrency control, should be null in POSTs).")
81+
);
8082
}
8183
}
8284

0 commit comments

Comments
 (0)