diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/AbstractGenerateMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/AbstractGenerateMojo.java index ecbd891be..92f9e5f1e 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/AbstractGenerateMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/AbstractGenerateMojo.java @@ -1,15 +1,13 @@ package com.backbase.oss.boat; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - @Slf4j public abstract class AbstractGenerateMojo extends GenerateMojo { @@ -52,29 +50,13 @@ public void execute(String generatorName, String library, boolean isEmbedded, bo } log.debug("Using configOptions={}", this.configOptions); - Stream supportingFiles = Optional.ofNullable(getGeneratorSpecificSupportingFiles()) - .filter(CollectionUtils::isNotEmpty) - .map(Collection::stream) - .orElse(Stream.empty()); - if (isEmbedded) { - supportingFiles = Stream.concat(supportingFiles, EMBEDDED_SUPPORTING_FILES.stream()); + this.supportingFilesToGenerate = uniqueJoin(EMBEDDED_SUPPORTING_FILES); } - this.supportingFilesToGenerate = supportingFiles - .map(String::trim) - .filter(StringUtils::isNotEmpty) - .distinct() - .sorted() - .collect(Collectors.joining(",")); - super.execute(); } - protected Collection getGeneratorSpecificSupportingFiles() { - return Collections.emptySet(); - } - private static Map mergeOptions(Map defaultOptions, Map overrides) { var merged = new HashMap<>(); merged.putAll(defaultOptions); diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateMojo.java index 3179b42fc..b756102c1 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateMojo.java @@ -1,5 +1,28 @@ package com.backbase.oss.boat; +import static java.lang.String.format; +import static java.util.Arrays.stream; +import static java.util.Collections.emptyMap; +import static java.util.stream.Collectors.joining; +import static org.apache.commons.lang3.StringUtils.isNotEmpty; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyAdditionalPropertiesKvp; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyAdditionalPropertiesKvpList; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyImportMappingsKvp; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyImportMappingsKvpList; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyInstantiationTypesKvp; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyInstantiationTypesKvpList; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyLanguageSpecificPrimitivesCsv; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyLanguageSpecificPrimitivesCsvList; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyOpenAPINormalizerKvpList; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyReservedWordsMappingsKvp; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyReservedWordsMappingsKvpList; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applySchemaMappingsKvp; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applySchemaMappingsKvpList; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyServerVariablesKvp; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyServerVariablesKvpList; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyTypeMappingsKvp; +import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyTypeMappingsKvpList; + import com.backbase.oss.boat.transformers.Bundler; import com.backbase.oss.boat.transformers.DereferenceComponentsPropertiesTransformer; import com.backbase.oss.boat.transformers.UnAliasTransformer; @@ -24,13 +47,16 @@ import java.nio.channels.ReadableByteChannel; import java.nio.charset.StandardCharsets; import java.nio.file.StandardCopyOption; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; +import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import java.util.stream.Stream; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -51,29 +77,6 @@ import org.sonatype.plexus.build.incremental.BuildContext; import org.sonatype.plexus.build.incremental.DefaultBuildContext; -import static java.lang.String.format; -import static java.util.Arrays.stream; -import static java.util.Collections.emptyMap; -import static java.util.stream.Collectors.joining; -import static org.apache.commons.lang3.StringUtils.isNotEmpty; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyAdditionalPropertiesKvp; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyAdditionalPropertiesKvpList; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyImportMappingsKvp; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyImportMappingsKvpList; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyInstantiationTypesKvp; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyInstantiationTypesKvpList; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyLanguageSpecificPrimitivesCsv; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyLanguageSpecificPrimitivesCsvList; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyOpenAPINormalizerKvpList; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyReservedWordsMappingsKvp; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyReservedWordsMappingsKvpList; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applySchemaMappingsKvp; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applySchemaMappingsKvpList; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyServerVariablesKvp; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyServerVariablesKvpList; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyTypeMappingsKvp; -import static org.openapitools.codegen.config.CodegenConfiguratorUtils.applyTypeMappingsKvpList; - /** * Generates client/server code from an OpenAPI json/yaml definition. */ @@ -93,6 +96,15 @@ private static String trimCSV(String text) { } } + static String uniqueJoin(Collection values) { + return values.stream() + .map(String::trim) + .filter(StringUtils::isNotEmpty) + .distinct() + .sorted() + .collect(Collectors.joining(",")); + } + public static final String INSTANTIATION_TYPES = "instantiation-types"; public static final String IMPORT_MAPPINGS = "import-mappings"; public static final String TYPE_MAPPINGS = "type-mappings"; @@ -734,8 +746,17 @@ public void execute() throws MojoExecutionException, MojoFailureException { GlobalSettings.clearProperty(CodegenConstants.MODELS); } - if (null != generateSupportingFiles && generateSupportingFiles) { - GlobalSettings.setProperty(CodegenConstants.SUPPORTING_FILES, trimCSV(supportingFilesToGenerate)); + String generatorSupportingFilesToGenerate = Optional.ofNullable(getGeneratorSpecificSupportingFiles()) + .map(GenerateMojo::uniqueJoin) + .orElse(""); + + if (generateSupportingFiles != null && generateSupportingFiles) { + String allToGenerate = Stream.of(trimCSV(supportingFilesToGenerate), generatorSupportingFilesToGenerate) + .filter(StringUtils::isNotBlank) + .collect(joining(",")); + GlobalSettings.setProperty(CodegenConstants.SUPPORTING_FILES, allToGenerate); + } else if (StringUtils.isNotBlank(generatorSupportingFilesToGenerate)) { + GlobalSettings.setProperty(CodegenConstants.SUPPORTING_FILES, generatorSupportingFilesToGenerate); } else { GlobalSettings.clearProperty(CodegenConstants.SUPPORTING_FILES); } @@ -929,6 +950,10 @@ public void execute() throws MojoExecutionException, MojoFailureException { } } + protected Collection getGeneratorSpecificSupportingFiles() { + return Collections.emptySet(); + } + /** * Calculate openapi specification file hash. If specification is hosted on remote resource it is downloaded first * diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateRestTemplateEmbeddedMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateRestTemplateEmbeddedMojo.java index 53eb60342..d4b2d414e 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateRestTemplateEmbeddedMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateRestTemplateEmbeddedMojo.java @@ -1,5 +1,7 @@ package com.backbase.oss.boat; +import java.util.Collection; +import java.util.Set; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; @@ -15,4 +17,9 @@ public void execute() throws MojoExecutionException, MojoFailureException { getLog().info("Generating Client using Spring Rest Template"); execute("java", "resttemplate", true, false, true); } + + @Override + protected Collection getGeneratorSpecificSupportingFiles() { + return Set.of("BigDecimalCustomSerializer.java"); + } } diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateSpringBootEmbeddedMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateSpringBootEmbeddedMojo.java index 329b04107..71e53c875 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateSpringBootEmbeddedMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateSpringBootEmbeddedMojo.java @@ -1,12 +1,11 @@ package com.backbase.oss.boat; +import java.util.Collection; +import java.util.Set; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; -import java.util.Collection; -import java.util.Set; - /** * Generating Server Stubs using Spring Boot. */ diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateWebClientEmbeddedMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateWebClientEmbeddedMojo.java index bf8ad91fc..9430858ee 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateWebClientEmbeddedMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateWebClientEmbeddedMojo.java @@ -1,5 +1,7 @@ package com.backbase.oss.boat; +import java.util.Collection; +import java.util.Set; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; @@ -16,4 +18,8 @@ public void execute() throws MojoExecutionException, MojoFailureException { execute("java", "webclient", true, true, true); } + @Override + protected Collection getGeneratorSpecificSupportingFiles() { + return Set.of("BigDecimalCustomSerializer.java"); + } } diff --git a/boat-maven-plugin/src/test/java/com/backbase/oss/boat/GenerateMojoTests.java b/boat-maven-plugin/src/test/java/com/backbase/oss/boat/GenerateMojoTests.java index 424db0683..0b606443c 100644 --- a/boat-maven-plugin/src/test/java/com/backbase/oss/boat/GenerateMojoTests.java +++ b/boat-maven-plugin/src/test/java/com/backbase/oss/boat/GenerateMojoTests.java @@ -1,7 +1,19 @@ package com.backbase.oss.boat; +import static java.util.Collections.singletonMap; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.endsWith; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + import com.backbase.oss.codegen.java.BoatJavaCodeGen; import com.backbase.oss.codegen.java.BoatSpringCodeGen; +import java.io.File; +import java.util.HashMap; +import java.util.Map; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; @@ -11,16 +23,6 @@ import org.openapitools.codegen.DefaultCodegen; import org.sonatype.plexus.build.incremental.DefaultBuildContext; -import java.io.File; -import java.util.HashMap; -import java.util.Map; - -import static java.util.Collections.singletonMap; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - class GenerateMojoTests { private final DefaultBuildContext buildContext = new DefaultBuildContext(); private final MavenProject project = new MavenProject(); @@ -80,6 +82,10 @@ void useJavaBoatForRestTemplateEmbedded() throws MojoExecutionException, MojoFai "RFC3339DateFormat.java,ServerConfiguration.java,ServerVariable.java,StringUtil.java", mojo.supportingFilesToGenerate ); + assertThat( + mojo.getGeneratorSpecificSupportingFiles(), + containsInAnyOrder("BigDecimalCustomSerializer.java") + ); } @Test @@ -91,10 +97,14 @@ void useSpringBoatForSpringBootEmbedded() throws MojoExecutionException, MojoFai assertThat(mojo.generatorName, equalTo(BoatSpringCodeGen.NAME)); assertEquals( "ApiClient.java,ApiKeyAuth.java,Authentication.java,BeanValidationException.java," + - "BigDecimalCustomSerializer.java,HttpBasicAuth.java,HttpBearerAuth.java,JavaTimeFormatter.java," + + "HttpBasicAuth.java,HttpBearerAuth.java,JavaTimeFormatter.java," + "RFC3339DateFormat.java,ServerConfiguration.java,ServerVariable.java,StringUtil.java", mojo.supportingFilesToGenerate ); + assertThat( + mojo.getGeneratorSpecificSupportingFiles(), + containsInAnyOrder("BigDecimalCustomSerializer.java") + ); } @Test diff --git a/boat-scaffold/src/main/java/com/backbase/oss/codegen/java/BoatJavaCodeGen.java b/boat-scaffold/src/main/java/com/backbase/oss/codegen/java/BoatJavaCodeGen.java index 6fe96ff6a..13c38112d 100644 --- a/boat-scaffold/src/main/java/com/backbase/oss/codegen/java/BoatJavaCodeGen.java +++ b/boat-scaffold/src/main/java/com/backbase/oss/codegen/java/BoatJavaCodeGen.java @@ -4,10 +4,12 @@ import com.backbase.oss.codegen.java.BoatCodeGenUtils.CodegenValueType; import io.swagger.v3.oas.models.media.Schema; +import java.io.File; import lombok.Getter; import lombok.Setter; import org.openapitools.codegen.CliOption; import org.openapitools.codegen.CodegenProperty; +import org.openapitools.codegen.SupportingFile; import org.openapitools.codegen.languages.JavaClientCodegen; import org.openapitools.codegen.utils.ModelUtils; @@ -118,6 +120,17 @@ private void processRestTemplateOpts() { this.createApiComponent = convertPropertyToBoolean(CREATE_API_COMPONENT); } writePropertyBack(CREATE_API_COMPONENT, this.createApiComponent); + + if (useJacksonConversion) { + final var serializerTemplate = "BigDecimalCustomSerializer"; + String targetDir = (sourceFolder + File.separator + modelPackage).replace(".", java.io.File.separator); + String importPackage = targetDir.replace("\\", ".").replace("/", "."); + if (importPackage.length() > 0 && !importPackage.endsWith(".")) { + importPackage += "."; + } + this.supportingFiles.add(new SupportingFile(serializerTemplate + ".mustache", targetDir, serializerTemplate + ".java")); + this.importMapping.put(serializerTemplate, importPackage + serializerTemplate); + } } @Override diff --git a/boat-scaffold/src/main/java/com/backbase/oss/codegen/java/BoatSpringCodeGen.java b/boat-scaffold/src/main/java/com/backbase/oss/codegen/java/BoatSpringCodeGen.java index 504a6eedd..177837e28 100644 --- a/boat-scaffold/src/main/java/com/backbase/oss/codegen/java/BoatSpringCodeGen.java +++ b/boat-scaffold/src/main/java/com/backbase/oss/codegen/java/BoatSpringCodeGen.java @@ -1,5 +1,12 @@ package com.backbase.oss.codegen.java; +import static com.backbase.oss.codegen.java.BoatCodeGenUtils.getCollectionCodegenValue; +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.joining; +import static org.apache.commons.lang3.StringUtils.contains; +import static org.apache.commons.lang3.StringUtils.isEmpty; +import static org.openapitools.codegen.utils.StringUtils.camelize; + import com.backbase.oss.codegen.java.BoatCodeGenUtils.CodegenValueType; import com.samskivert.mustache.Mustache; import com.samskivert.mustache.Template.Fragment; @@ -7,16 +14,6 @@ import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.servers.Server; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.openapitools.codegen.*; -import org.openapitools.codegen.config.GlobalSettings; -import org.openapitools.codegen.languages.SpringCodegen; -import org.openapitools.codegen.templating.mustache.IndentedLambda; -import org.openapitools.codegen.utils.ModelUtils; - import java.io.File; import java.io.IOException; import java.io.Writer; @@ -27,13 +24,21 @@ import java.util.regex.Pattern; import java.util.stream.IntStream; import java.util.stream.Stream; - -import static com.backbase.oss.codegen.java.BoatCodeGenUtils.getCollectionCodegenValue; -import static java.util.Arrays.stream; -import static java.util.stream.Collectors.joining; -import static org.apache.commons.lang3.StringUtils.contains; -import static org.apache.commons.lang3.StringUtils.isEmpty; -import static org.openapitools.codegen.utils.StringUtils.camelize; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.openapitools.codegen.CliOption; +import org.openapitools.codegen.CodegenConstants; +import org.openapitools.codegen.CodegenModel; +import org.openapitools.codegen.CodegenOperation; +import org.openapitools.codegen.CodegenParameter; +import org.openapitools.codegen.CodegenProperty; +import org.openapitools.codegen.SupportingFile; +import org.openapitools.codegen.config.GlobalSettings; +import org.openapitools.codegen.languages.SpringCodegen; +import org.openapitools.codegen.templating.mustache.IndentedLambda; +import org.openapitools.codegen.utils.ModelUtils; @Slf4j public class BoatSpringCodeGen extends SpringCodegen { @@ -118,7 +123,7 @@ public void execute(Fragment frag, Writer out) throws IOException { return; } String formatted = text - .replaceAll("\\n", SINGLE_SPACE) + .replace("\\n", SINGLE_SPACE) .replaceAll(WHITESPACE_REGEX, SINGLE_SPACE) .replaceAll("\\< ", "<") .replaceAll(" >", ">") @@ -312,12 +317,13 @@ public void processOpts() { writePropertyBack("useApiUtil", useApiUtil); + final var serializerTemplate = "BigDecimalCustomSerializer"; this.supportingFiles.add(new SupportingFile( - "BigDecimalCustomSerializer.mustache", - new File(this.getSourceFolder(), basePackage.replaceAll("\\\\.", File.separator)).getPath(), - "BigDecimalCustomSerializer.java" + serializerTemplate + ".mustache", + (sourceFolder + File.separator + modelPackage).replace(".", java.io.File.separator), + serializerTemplate + ".java" )); - this.importMapping.put("BigDecimalCustomSerializer", basePackage + ".BigDecimalCustomSerializer"); + this.importMapping.put(serializerTemplate, modelPackage + "." + serializerTemplate); if (this.additionalProperties.containsKey(USE_CLASS_LEVEL_BEAN_VALIDATION)) { this.useClassLevelBeanValidation = convertPropertyToBoolean(USE_CLASS_LEVEL_BEAN_VALIDATION); @@ -359,11 +365,8 @@ public void processOpts() { @Override public void postProcessParameter(CodegenParameter p) { super.postProcessParameter(p); - - if (p.isContainer) { - if (!this.reactive) { - p.baseType = p.dataType.replaceAll("^([^<]+)<.+>$", "$1"); - } + if (p.isContainer && !this.reactive) { + p.baseType = p.dataType.replaceAll("^([^<]+)<.+>$", "$1"); } } diff --git a/boat-scaffold/src/main/templates/boat-java/BigDecimalCustomSerializer.mustache b/boat-scaffold/src/main/templates/boat-java/BigDecimalCustomSerializer.mustache new file mode 100644 index 000000000..199ce4c51 --- /dev/null +++ b/boat-scaffold/src/main/templates/boat-java/BigDecimalCustomSerializer.mustache @@ -0,0 +1,20 @@ +{{>licenseInfo}} +package {{package}}; + +import com.fasterxml.jackson.databind.ser.std.ToStringSerializerBase; +import java.math.BigDecimal; + +public class BigDecimalCustomSerializer extends ToStringSerializerBase { + + public BigDecimalCustomSerializer() { + super(BigDecimal.class); + } + + @Override + public String valueToString(Object value) { + if (value instanceof BigDecimal) { + return ((BigDecimal) value).toPlainString(); + } + return (value == null) ? null : value.toString(); + } +} diff --git a/boat-scaffold/src/main/templates/boat-spring/libraries/spring-boot/BigDecimalCustomSerializer.mustache b/boat-scaffold/src/main/templates/boat-spring/BigDecimalCustomSerializer.mustache similarity index 95% rename from boat-scaffold/src/main/templates/boat-spring/libraries/spring-boot/BigDecimalCustomSerializer.mustache rename to boat-scaffold/src/main/templates/boat-spring/BigDecimalCustomSerializer.mustache index 392797e64..a6dc40f30 100644 --- a/boat-scaffold/src/main/templates/boat-spring/libraries/spring-boot/BigDecimalCustomSerializer.mustache +++ b/boat-scaffold/src/main/templates/boat-spring/BigDecimalCustomSerializer.mustache @@ -1,4 +1,4 @@ -package {{basePackage}}; +package {{modelPackage}}; import com.fasterxml.jackson.databind.ser.std.ToStringSerializerBase; import java.math.BigDecimal;