From fe114852a52bb85b41679b3f59de0015d5b6cd77 Mon Sep 17 00:00:00 2001 From: Ivan Garcia Sainz-Aja Date: Tue, 28 Mar 2023 20:21:45 +0100 Subject: [PATCH] Backend: support for empty input suffix. --- .../jdl-backend-application-default/README.md | 17 +++++----- ...JDLBackendApplicationDefaultGenerator.java | 2 +- .../jpa/imperative/ServiceImpl.java.hbs | 13 ++------ .../mongodb/imperative/ServiceImpl.java.hbs | 12 ++----- ...ApplicationJpaImperativeGeneratorTest.java | 24 ++++++++++++++ ...plicationMongoImperativeGeneratorTest.java | 32 +++++++++++++++++-- .../templating/CustomHandlebarsHelpers.java | 12 +++++++ .../sdk/templates/HandlebarsEngineTest.java | 2 ++ .../sdk/templating/handlebars-test.hbs | 4 +++ 9 files changed, 87 insertions(+), 31 deletions(-) diff --git a/plugins/jdl-backend-application-default/README.md b/plugins/jdl-backend-application-default/README.md index dfcfae4d..7f65d993 100644 --- a/plugins/jdl-backend-application-default/README.md +++ b/plugins/jdl-backend-application-default/README.md @@ -21,14 +21,15 @@ This generator supports the following JDL extensions: - if any entity is annotated with @aggregate then the following table applies: -| **Annotation** | **Entity** | **@Persistence** | **Repository** | **Id** | -|:--------------------------------|------------|:-----------------|:---------------|:-------| -| **entity** | yes | yes | | yes | -| **@aggregate** | yes | yes | yes | yes | -| **@embedded** | yes | yes | | | -| **@vo** | yes | | | | -| **@searchCriteria(entityName)** | | | | | -| **@skip** | no | | | | +| **Annotation** | **Entity** | **Inbound DTO** | **@Persistence** | **Repository** | **Id** | +|:--------------------------------|------------|----------------------|:-----------------|:---------------|:---------| +| **entity** | yes | | yes | | yes | +| **@aggregate** | yes | | yes | yes | yes | +| **@embedded** | yes | | yes | | only jpa | +| **@vo** | yes | | | | | +| **@input** | no | yes | | | | +| **@searchCriteria(entityName)** | | yes (for entityName) | | | | +| **@skip** | no | | | | | - **@searchCriteria(entityName)** is used to specify the entity name for the search criteria, if empty will take the same fields as the actual entity. - **@skip** entities used as search criteria should be marked with @skip diff --git a/plugins/jdl-backend-application-default/src/main/java/io/zenwave360/sdk/plugins/JDLBackendApplicationDefaultGenerator.java b/plugins/jdl-backend-application-default/src/main/java/io/zenwave360/sdk/plugins/JDLBackendApplicationDefaultGenerator.java index e3464475..8cc02254 100644 --- a/plugins/jdl-backend-application-default/src/main/java/io/zenwave360/sdk/plugins/JDLBackendApplicationDefaultGenerator.java +++ b/plugins/jdl-backend-application-default/src/main/java/io/zenwave360/sdk/plugins/JDLBackendApplicationDefaultGenerator.java @@ -81,7 +81,7 @@ boolean is(Map model, String... annotations) { new Object[] {"src/main/java", "core/inbound/dtos/EntityCriteria.java", "core/inbound/dtos/{{criteriaClassName entity }}.java", JAVA, skipSearchCriteria}, new Object[] {"src/main/java", "core/inbound/dtos/EntityInput.java", "core/inbound/dtos/{{entity.className}}{{inputDTOSuffix entity}}.java", JAVA, skipEntityInput}, new Object[] {"src/main/java", "core/inbound/dtos/EntityInput.java", "core/inbound/dtos/{{entity.className}}{{inputDTOSuffix entity}}.java", JAVA, skipInput}, - new Object[] {"src/main/java", "core/implementation/mappers/EntityMapper.java", "core/implementation/mappers/{{entity.className}}Mapper.java", JAVA, skipEntityInput, true}, + new Object[] {"src/main/java", "core/implementation/mappers/EntityMapper.java", "core/implementation/mappers/{{entity.className}}Mapper.java", JAVA, skipEntity, true}, // new Object[] {"src/main/java", "adapters/web/{{webFlavor}}/EntityResource.java", "adapters/web/{{entity.className}}Resource.java", JAVA, skipEntityResource}, new Object[] {"src/main/java", "core/domain/search/EntityDocument.java", "core/domain/search/{{entity.className}}{{searchDTOSuffix}}.java", JAVA, skipElasticSearch}, new Object[] {"src/main/java", "core/outbound/search/EntitySearchRepository.java", "core/outbound/search/{{entity.className}}SearchRepository.java", JAVA, skipElasticSearch, true}, diff --git a/plugins/jdl-backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/JDLEntitiesGenerator/src/main/java/core/implementation/jpa/imperative/ServiceImpl.java.hbs b/plugins/jdl-backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/JDLEntitiesGenerator/src/main/java/core/implementation/jpa/imperative/ServiceImpl.java.hbs index 33e49c71..f4c20f55 100644 --- a/plugins/jdl-backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/JDLEntitiesGenerator/src/main/java/core/implementation/jpa/imperative/ServiceImpl.java.hbs +++ b/plugins/jdl-backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/JDLEntitiesGenerator/src/main/java/core/implementation/jpa/imperative/ServiceImpl.java.hbs @@ -28,9 +28,7 @@ public class {{service.name}}Impl implements {{service.name}} { private final Logger log = LoggerFactory.getLogger(getClass()); {{#each entities as |entity|}} - {{~#if (inputDTOSuffix entity)}} private final {{entity.className}}Mapper {{entity.instanceName}}Mapper = Mappers.getMapper({{entity.className}}Mapper.class); - {{~/if}} {{~#unless (skipEntityRepository this)}} private final {{entity.className}}Repository {{entity.instanceName}}Repository; {{~/unless}} @@ -53,25 +51,20 @@ public class {{service.name}}Impl implements {{service.name}} { // {{entity.name}} @Override - @Transactional(readOnly = false) public {{entity.className}} create{{entity.className}}({{entity.className}}{{inputDTOSuffix}} input) { log.debug("Request to save {{entity.className}}: {}", input); - var {{entity.instanceName}} = {{#if (inputDTOSuffix entity)}}{{entity.instanceName}}Mapper.update(new {{entity.className}}(), input); - {{entity.instanceName}} ={{/if}} {{entity.instanceName}}Repository.save({{entity.instanceName}}); + var {{entity.instanceName}} = {{entity.instanceName}}Mapper.update(new {{entity.className}}(), input); + {{entity.instanceName}} = {{entity.instanceName}}Repository.save({{entity.instanceName}}); // TODO: you may need to reload the entity here to fetch all the relationships return {{entity.instanceName}}; } @Override - @Transactional(readOnly = false) public Optional<{{entity.className}}> update{{entity.className}}({{idJavaType}} id, {{entity.className}}{{inputDTOSuffix}} input) { log.debug("Request to update {{entity.className}}: {}", input); var {{entity.instanceName}} = {{entity.instanceName}}Repository.findById(id); - {{~#if (inputDTOSuffix entity)}} {{entity.instanceName}} = {{entity.instanceName}}.map(existing{{entity.instanceName}} -> {{entity.instanceName}}Mapper.update(existing{{entity.instanceName}}, input)); - {{~/if}} - // saving is unnecessary (jpa save anti-pattern): https://vladmihalcea.com/best-spring-data-jparepository/ - // return {{entity.instanceName}}.map({{entity.instanceName}}Repository::save); + // saving is unnecessary: https://vladmihalcea.com/best-spring-data-jparepository/ return {{entity.instanceName}}; } diff --git a/plugins/jdl-backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/JDLEntitiesGenerator/src/main/java/core/implementation/mongodb/imperative/ServiceImpl.java.hbs b/plugins/jdl-backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/JDLEntitiesGenerator/src/main/java/core/implementation/mongodb/imperative/ServiceImpl.java.hbs index 81923b51..d9d9b315 100644 --- a/plugins/jdl-backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/JDLEntitiesGenerator/src/main/java/core/implementation/mongodb/imperative/ServiceImpl.java.hbs +++ b/plugins/jdl-backend-application-default/src/main/resources/io/zenwave360/sdk/plugins/JDLEntitiesGenerator/src/main/java/core/implementation/mongodb/imperative/ServiceImpl.java.hbs @@ -28,9 +28,7 @@ public class {{service.name}}Impl implements {{service.name}} { private final Logger log = LoggerFactory.getLogger(getClass()); {{#each entities as |entity|}} - {{~#if (inputDTOSuffix entity)}} private final {{entity.className}}Mapper {{entity.instanceName}}Mapper = Mappers.getMapper({{entity.className}}Mapper.class); - {{~/if}} {{~#unless (skipEntityRepository this)}} private final {{entity.className}}Repository {{entity.instanceName}}Repository; {{~/unless}} @@ -55,11 +53,7 @@ public class {{service.name}}Impl implements {{service.name}} { @Override public {{entity.className}} create{{entity.className}}({{entity.className}}{{inputDTOSuffix}} input) { log.debug("Request to save {{entity.className}}{{inputDTOSuffix}} : {}", input); - {{~#if (inputDTOSuffix entity)}} var {{entity.instanceName}} = {{entity.instanceName}}Repository.save({{entity.instanceName}}Mapper.update(new {{entity.className}}(), input)); - {{~else}} - var {{entity.instanceName}} = {{entity.instanceName}}Repository.save(input); - {{~/if}} return {{entity.instanceName}}; } @@ -69,9 +63,9 @@ public class {{service.name}}Impl implements {{service.name}} { var {{entity.instanceName}} = {{entity.instanceName}}Repository .findById(id) - {{~#if (inputDTOSuffix entity)}} - .map(existing{{entity.className}} -> {{entity.instanceName}}Mapper.update(existing{{entity.className}}, input)) - {{~/if}} + .map(existing{{entity.className}} -> { + return {{entity.instanceName}}Mapper.update(existing{{entity.className}}, input); + }) .map({{entity.instanceName}}Repository::save); return {{entity.instanceName}}; } diff --git a/plugins/jdl-backend-application-default/src/test/java/io/zenwave360/sdk/plugins/JDLBackendApplicationJpaImperativeGeneratorTest.java b/plugins/jdl-backend-application-default/src/test/java/io/zenwave360/sdk/plugins/JDLBackendApplicationJpaImperativeGeneratorTest.java index 35e38c07..102a434b 100644 --- a/plugins/jdl-backend-application-default/src/test/java/io/zenwave360/sdk/plugins/JDLBackendApplicationJpaImperativeGeneratorTest.java +++ b/plugins/jdl-backend-application-default/src/test/java/io/zenwave360/sdk/plugins/JDLBackendApplicationJpaImperativeGeneratorTest.java @@ -49,6 +49,30 @@ public void test_generator_hexagonal_jpa_imperative() throws Exception { .withOption("persistence", PersistenceType.jpa) .withOption("databaseType", DatabaseType.mariadb) .withOption("style", ProgrammingStyle.imperative) + .withOption("forceOverwrite", true) + .withOption("haltOnFailFormatting", false); + + new MainGenerator().generate(plugin); + + // Assertions.assertTrue(logs.contains("Writing template with targetFile: io/example/integration/test/api/provider_for_commands_reactive/DoCreateProductConsumer.java")); + // Assertions.assertTrue(logs.contains("Writing template with targetFile: io/example/integration/test/api/provider_for_commands_reactive/DoCreateProductService.java")); + + int exitCode = MavenCompiler.compile("src/test/resources/jpa-elasticsearch-scs3-pom.xml", targetFolder); + Assertions.assertEquals(0, exitCode); + } + + @Test + public void test_generator_hexagonal_jpa_imperative_no_dto() throws Exception { + String targetFolder = "target/test_generator_hexagonal_jpa_imperative"; + Plugin plugin = new JDLBackendApplicationDefaultPlugin() + .withSpecFile("classpath:io/zenwave360/sdk/resources/jdl/orders-model-relational.jdl") + .withTargetFolder(targetFolder) + .withOption("basePackage", "io.zenwave360.example") + .withOption("persistence", PersistenceType.jpa) + .withOption("databaseType", DatabaseType.mariadb) + .withOption("style", ProgrammingStyle.imperative) + .withOption("inputDTOSuffix", "") + .withOption("forceOverwrite", true) .withOption("haltOnFailFormatting", false); new MainGenerator().generate(plugin); diff --git a/plugins/jdl-backend-application-default/src/test/java/io/zenwave360/sdk/plugins/JDLBackendApplicationMongoImperativeGeneratorTest.java b/plugins/jdl-backend-application-default/src/test/java/io/zenwave360/sdk/plugins/JDLBackendApplicationMongoImperativeGeneratorTest.java index 0c293e4b..f42b1e3b 100644 --- a/plugins/jdl-backend-application-default/src/test/java/io/zenwave360/sdk/plugins/JDLBackendApplicationMongoImperativeGeneratorTest.java +++ b/plugins/jdl-backend-application-default/src/test/java/io/zenwave360/sdk/plugins/JDLBackendApplicationMongoImperativeGeneratorTest.java @@ -62,7 +62,30 @@ public void test_generator_hexagonal_mongodb_imperative() throws Exception { .withTargetFolder(targetFolder) .withOption("basePackage", "io.zenwave360.example") .withOption("persistence", PersistenceType.mongodb) - .withOption("style", ProgrammingStyle.imperative); + .withOption("style", ProgrammingStyle.imperative) + .withOption("forceOverwrite", true); + + new MainGenerator().generate(plugin); + + List logs = logCaptor.getLogs(); + // Assertions.assertTrue(logs.contains("Writing template with targetFile: io/example/integration/test/api/provider_for_commands_reactive/DoCreateProductConsumer.java")); + // Assertions.assertTrue(logs.contains("Writing template with targetFile: io/example/integration/test/api/provider_for_commands_reactive/DoCreateProductService.java")); + + int exitCode = MavenCompiler.compile("src/test/resources/mongodb-elasticsearch-scs3-pom.xml", targetFolder); + Assertions.assertEquals(0, exitCode); + } + + @Test + public void test_generator_hexagonal_mongodb_imperative_no_dtos() throws Exception { + String targetFolder = "target/test_generator_hexagonal_mongodb_imperative"; + Plugin plugin = new JDLBackendApplicationDefaultPlugin() + .withSpecFile("classpath:io/zenwave360/sdk/resources/jdl/orders-model.jdl") + .withTargetFolder(targetFolder) + .withOption("basePackage", "io.zenwave360.example") + .withOption("persistence", PersistenceType.mongodb) + .withOption("inputDTOSuffix", "") + .withOption("style", ProgrammingStyle.imperative) + .withOption("forceOverwrite", true); new MainGenerator().generate(plugin); @@ -74,6 +97,7 @@ public void test_generator_hexagonal_mongodb_imperative() throws Exception { Assertions.assertEquals(0, exitCode); } + @Test // @Disabled public void test_generator_hexagonal_mongodb_imperative_registry() throws Exception { @@ -83,7 +107,8 @@ public void test_generator_hexagonal_mongodb_imperative_registry() throws Except .withTargetFolder(targetFolder) .withOption("basePackage", "io.zenwave360.example") .withOption("persistence", PersistenceType.mongodb) - .withOption("style", ProgrammingStyle.imperative); + .withOption("style", ProgrammingStyle.imperative) + .withOption("forceOverwrite", true); new MainGenerator().generate(plugin); @@ -105,7 +130,8 @@ public void test_generator_hexagonal_mongodb_imperative_registry_only_some_entit .withOption("basePackage", "io.zenwave360.example") .withOption("persistence", PersistenceType.mongodb) .withOption("style", ProgrammingStyle.imperative) - .withOption("entities", List.of("BaseEntity", "Customer")); + .withOption("entities", List.of("BaseEntity", "Customer")) + .withOption("forceOverwrite", true); new MainGenerator().generate(plugin); diff --git a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/templating/CustomHandlebarsHelpers.java b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/templating/CustomHandlebarsHelpers.java index 5ff44988..79eaceac 100644 --- a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/templating/CustomHandlebarsHelpers.java +++ b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/templating/CustomHandlebarsHelpers.java @@ -9,6 +9,7 @@ import java.util.*; import java.util.stream.Collectors; +import com.github.jknack.handlebars.Handlebars; import io.zenwave360.sdk.parsers.JDLParser; import io.zenwave360.sdk.utils.JSONPath; import org.apache.commons.io.FilenameUtils; @@ -111,6 +112,14 @@ public static boolean endsWith(String first, Options options) throws IOException return StringUtils.endsWith(first, second); } + public static Object ifTruthy(final Object value, final Options options) + throws IOException { + if (isTruthy(value)) { + return options.param(0, ""); + } + return options.param(1, ""); + } + public static boolean not(Object value, Options options) throws IOException { if (value == null) { return true; @@ -130,6 +139,9 @@ private static boolean isTruthy(Object value) { if (value == null) { return false; } + if(value.toString().trim().equals("")) { + return false; + } if (value instanceof Boolean) { return (Boolean) value; } diff --git a/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/templates/HandlebarsEngineTest.java b/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/templates/HandlebarsEngineTest.java index cdf2b20e..d2bef9de 100644 --- a/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/templates/HandlebarsEngineTest.java +++ b/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/templates/HandlebarsEngineTest.java @@ -35,6 +35,8 @@ public void testHandlebarsEngine() throws IOException { Assertions.assertTrue(templateOutput.getContent().contains("kebabCase some-camel-case-with-spaces")); Assertions.assertTrue(templateOutput.getContent().contains("asPackageFolder io/zenwave360/sdk/templating")); Assertions.assertTrue(templateOutput.getContent().contains("Prefix2Suffix")); + Assertions.assertTrue(templateOutput.getContent().contains("ifTruthy true: true")); + Assertions.assertTrue(templateOutput.getContent().contains("ifTruthy false: false")); Assertions.assertTrue(templateOutput.getContent().contains("Inside if 1")); Assertions.assertTrue(templateOutput.getContent().contains("Inside else 2")); Assertions.assertTrue(templateOutput.getContent().contains("path: 'api/v1/users'")); diff --git a/zenwave-sdk-cli/src/test/resources/io/zenwave360/sdk/templating/handlebars-test.hbs b/zenwave-sdk-cli/src/test/resources/io/zenwave360/sdk/templating/handlebars-test.hbs index e0708613..e6d81401 100644 --- a/zenwave-sdk-cli/src/test/resources/io/zenwave360/sdk/templating/handlebars-test.hbs +++ b/zenwave-sdk-cli/src/test/resources/io/zenwave360/sdk/templating/handlebars-test.hbs @@ -7,6 +7,10 @@ asInstanceName {{asInstanceName "tratra-tratra"}} asJavaTypeName {{asJavaTypeName "tratra-tratra"}} kebabCase {{kebabCase "Some Camel Case with Spaces"}} asPackageFolder {{asPackageFolder "io.zenwave360.sdk.templating"}} + +ifTruthy true: {{ifTruthy "true" "true" "false"}} +ifTruthy false: {{ifTruthy "false" "true" "false"}} + {{#joinWithTemplate theList}} Prefix{{.}}Suffix {{/joinWithTemplate}}