From 5b084b197a72d7ff0c7efa6a03f2e4f9939ab37a Mon Sep 17 00:00:00 2001 From: Jose Enrique Date: Sat, 29 Nov 2025 23:56:26 +0100 Subject: [PATCH 1/9] Fix path handling for API files --- multiapi-engine/pom.xml | 2 +- .../api/generator/plugin/PluginConstants.java | 3 +- .../plugin/asyncapi/AsyncApiGenerator.java | 54 +- .../exception/InvalidAvroException.java | 10 +- .../asyncapi/handler/AsyncApi2Handler.java | 103 +- .../asyncapi/handler/AsyncApi3Handler.java | 142 ++- .../handler/AsyncApiHandlerFactory.java | 35 +- .../asyncapi/handler/BaseAsyncApiHandler.java | 143 ++- .../plugin/asyncapi/model/MethodObject.java | 1 + .../parameter/OperationParameterObject.java | 1 + .../asyncapi/template/ClassTemplate.java | 1 + .../template/ClasspathTemplateLoader.java | 20 +- .../asyncapi/template/TemplateFactory.java | 156 +-- .../plugin/asyncapi/util/AsyncApiUtil.java | 16 +- .../asyncapi/util/ReferenceProcessor.java | 16 +- .../common/files/ClasspathFileLocation.java | 30 +- .../common/files/DirectoryFileLocation.java | 19 +- .../plugin/common/files/FileLocation.java | 2 +- .../plugin/common/model/CommonSpecFile.java | 33 +- .../common/model/SchemaFieldObject.java | 19 +- .../model/SchemaFieldObjectProperties.java | 1 + .../common/model/SchemaFieldObjectType.java | 106 +- .../plugin/common/model/SchemaObject.java | 53 +- .../plugin/common/model/TypeConstants.java | 5 +- .../template/CommonTemplateFactory.java | 228 ++-- .../common/template/CommonTemplateLoader.java | 63 +- .../plugin/common/tools/ApiTool.java | 162 +-- .../common/tools/MapperContentUtil.java | 1 + .../plugin/common/tools/MapperUtil.java | 130 +- .../plugin/common/tools/ModelBuilder.java | 464 +++---- .../plugin/common/tools/PathUtil.java | 40 + .../plugin/common/tools/SchemaUtil.java | 29 +- .../plugin/common/tools/StringCaseUtils.java | 38 +- .../plugin/openapi/OpenApiGenerator.java | 111 +- .../plugin/openapi/model/AuthObject.java | 1 + .../plugin/openapi/model/GlobalObject.java | 1 + .../plugin/openapi/model/OperationObject.java | 1 + .../plugin/openapi/model/PathObject.java | 1 + .../plugin/openapi/model/RequestObject.java | 1 + .../plugin/openapi/model/ResponseObject.java | 1 + .../template/ClasspathTemplateLoader.java | 7 +- .../openapi/template/TemplateFactory.java | 39 +- .../plugin/openapi/utils/MapperAuthUtil.java | 18 +- .../plugin/openapi/utils/MapperPathUtil.java | 103 +- .../plugin/openapi/utils/OpenApiUtil.java | 91 +- .../v2/AsyncApiGeneratorFixtures.java | 1102 ++++++++--------- .../v2/AsyncApiGeneratorJakartaTest.java | 18 +- .../asyncapi/v2/AsyncApiGeneratorTest.java | 40 +- .../v3/AsyncApiGeneratorFixtures.java | 1100 ++++++++-------- .../v3/AsyncApiGeneratorJakartaTest.java | 18 +- .../asyncapi/v3/AsyncApiGeneratorTest.java | 42 +- .../openapi/OpenApiGeneratorFixtures.java | 132 +- .../openapi/OpenApiGeneratorJakartaTest.java | 10 +- .../plugin/openapi/OpenApiGeneratorTest.java | 104 +- .../api/generator/test/utils/TestUtils.java | 10 +- scs-multiapi-gradle-plugin/build.gradle | 6 +- scs-multiapi-maven-plugin/pom.xml | 4 +- 57 files changed, 2662 insertions(+), 2425 deletions(-) create mode 100644 multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/PathUtil.java diff --git a/multiapi-engine/pom.xml b/multiapi-engine/pom.xml index 8da9dfab..c531d740 100644 --- a/multiapi-engine/pom.xml +++ b/multiapi-engine/pom.xml @@ -4,7 +4,7 @@ com.sngular multiapi-engine - 6.2.1 + 6.3.0 jar diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/PluginConstants.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/PluginConstants.java index 338794d0..5ca22c42 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/PluginConstants.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/PluginConstants.java @@ -14,5 +14,6 @@ public class PluginConstants { public static final String GENERATED_SOURCES_API_GENERATOR_FOLDER = "apigenerator/"; - private PluginConstants() {} + private PluginConstants() { + } } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/AsyncApiGenerator.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/AsyncApiGenerator.java index 37b9c12a..fd3e49b5 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/AsyncApiGenerator.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/AsyncApiGenerator.java @@ -6,6 +6,17 @@ package com.sngular.api.generator.plugin.asyncapi; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; @@ -15,33 +26,34 @@ import com.sngular.api.generator.plugin.common.files.ClasspathFileLocation; import com.sngular.api.generator.plugin.common.files.DirectoryFileLocation; import com.sngular.api.generator.plugin.common.files.FileLocation; +import com.sngular.api.generator.plugin.common.tools.PathUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; -import java.io.*; -import java.net.URI; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - @Slf4j public class AsyncApiGenerator { private final Integer springBootVersion; + private final boolean overwriteModel; + private final File targetFolder; + private final String processedGeneratedSourcesFolder; + private final String groupId; + private final File baseDir; - public AsyncApiGenerator(final Integer springBootVersion, - boolean overwriteModel, - final File targetFolder, - final String processedGeneratedSourcesFolder, - final String groupId, - final File baseDir) { - log.debug("Initializing AsyncApiGenerator with Spring Boot version: {}", springBootVersion); + public AsyncApiGenerator( + final Integer springBootVersion, + boolean overwriteModel, + final File targetFolder, + final String processedGeneratedSourcesFolder, + final String groupId, + final File baseDir) { + log.debug("Initializing AsyncApiGenerator with Spring Boot version:{}", springBootVersion); this.springBootVersion = springBootVersion; this.overwriteModel = overwriteModel; this.targetFolder = targetFolder; @@ -61,10 +73,8 @@ public final void processFileSpec(final List specsListFile) { final ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); final JsonNode openApi = mapper.readTree(ymlLocation.getKey()); final String version = getAsyncApiVersion(openApi); - BaseAsyncApiHandler handler = AsyncApiHandlerFactory - .getHandler(version, springBootVersion, overwriteModel, targetFolder, processedGeneratedSourcesFolder, groupId, baseDir); - + .getHandler(version, springBootVersion, overwriteModel, targetFolder, processedGeneratedSourcesFolder, groupId, baseDir); handler.processFileSpec(Collections.singletonList(specFile)); } catch (IOException e) { log.error("Error processing spec file: {}", specFile.getFilePath(), e); @@ -74,10 +84,8 @@ public final void processFileSpec(final List specsListFile) { } private static Pair resolveYmlLocation(final String ymlFilePath) throws FileNotFoundException { - log.debug("Resolving YAML file location: {}", ymlFilePath); - + log.debug("Resolving YAML file location:{}", ymlFilePath); final InputStream classPathInput = AsyncApiGenerator.class.getClassLoader().getResourceAsStream(ymlFilePath); - final InputStream ymlFile; final FileLocation ymlParentPath; if (Objects.nonNull(classPathInput)) { @@ -88,9 +96,13 @@ private static Pair resolveYmlLocation(final String y log.debug("Looking for file in filesystem"); final File f = new File(ymlFilePath); ymlFile = new FileInputStream(f); - ymlParentPath = new DirectoryFileLocation(f.toPath().getParent()); + // For absolute paths, use the parent directly; otherwise, resolve relative to current directory + if (PathUtil.isAbsolutePath(ymlFilePath)) { + ymlParentPath = new DirectoryFileLocation(Paths.get(ymlFilePath).getParent()); + } else { + ymlParentPath = new DirectoryFileLocation(f.toPath().getParent()); + } } - return new ImmutablePair<>(ymlFile, ymlParentPath); } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/exception/InvalidAvroException.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/exception/InvalidAvroException.java index f35e3a20..f83784df 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/exception/InvalidAvroException.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/exception/InvalidAvroException.java @@ -7,8 +7,10 @@ package com.sngular.api.generator.plugin.asyncapi.exception; public class InvalidAvroException extends RuntimeException { - private static final String ERROR_MESSAGE = "AsyncApi -> Avro schema at path %s lacks a namespace."; - public InvalidAvroException(final String enumName) { - super(String.format(ERROR_MESSAGE, enumName)); - } + + private static final String ERROR_MESSAGE = "AsyncApi -> Avro schema at path %s lacks a namespace."; + + public InvalidAvroException(final String enumName) { + super(String.format(ERROR_MESSAGE, enumName)); + } } \ No newline at end of file diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/handler/AsyncApi2Handler.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/handler/AsyncApi2Handler.java index bb995b0e..922b4c71 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/handler/AsyncApi2Handler.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/handler/AsyncApi2Handler.java @@ -1,8 +1,26 @@ package com.sngular.api.generator.plugin.asyncapi.handler; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.sngular.api.generator.plugin.asyncapi.exception.*; +import com.sngular.api.generator.plugin.asyncapi.exception.ChannelNameException; +import com.sngular.api.generator.plugin.asyncapi.exception.DuplicatedOperationException; +import com.sngular.api.generator.plugin.asyncapi.exception.ExternalRefComponentNotFoundException; +import com.sngular.api.generator.plugin.asyncapi.exception.FileSystemException; +import com.sngular.api.generator.plugin.asyncapi.exception.InvalidAsyncAPIException; +import com.sngular.api.generator.plugin.asyncapi.exception.InvalidAvroException; import com.sngular.api.generator.plugin.asyncapi.model.ProcessBindingsResult; import com.sngular.api.generator.plugin.asyncapi.model.ProcessMethodResult; import com.sngular.api.generator.plugin.asyncapi.parameter.OperationParameterObject; @@ -20,21 +38,15 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URISyntaxException; -import java.util.*; -import java.util.Map.Entry; - public class AsyncApi2Handler extends BaseAsyncApiHandler { - public AsyncApi2Handler(final Integer springBootVersion, - boolean overwriteModel, - final File targetFolder, - final String processedGeneratedSourcesFolder, - final String groupId, - final File baseDir) { + public AsyncApi2Handler( + final Integer springBootVersion, + boolean overwriteModel, + final File targetFolder, + final String processedGeneratedSourcesFolder, + final String groupId, + final File baseDir) { super(springBootVersion, overwriteModel, targetFolder, processedGeneratedSourcesFolder, groupId, baseDir); } @@ -83,15 +95,15 @@ protected Map getAllSchemas(final FileLocation ymlParent, fina ApiTool.getComponent(node, SCHEMAS).forEachRemaining( schema -> totalSchemas.putIfAbsent(SCHEMAS.toUpperCase() + SLASH + MapperUtil.getSchemaKey(schema.getKey()), schema.getValue()) - ); + ); ApiTool.getComponent(node, MESSAGES).forEachRemaining( message -> getMessageSchemas(message.getKey(), message.getValue(), ymlParent, totalSchemas) - ); + ); getChannels(node).forEachRemaining( channel -> getChannelSchemas(channel.getValue(), totalSchemas, ymlParent) - ); + ); return totalSchemas; } @@ -132,7 +144,8 @@ protected void processSupplierMethod( @Override protected void processStreamBridgeMethod( - final String operationId, final JsonNode channel, final OperationParameterObject operationObject, final FileLocation ymlParent, final String channelName, final Map totalSchemas) + final String operationId, final JsonNode channel, final OperationParameterObject operationObject, final FileLocation ymlParent, final String channelName, + final Map totalSchemas) throws IOException { final ProcessMethodResult result = processMethod(operationId, channel, operationObject, ymlParent, totalSchemas); final String regex = "[a-zA-Z0-9.\\-]*"; @@ -153,7 +166,8 @@ protected void processSubscribeMethod( } @Override - protected void fillTemplateFactory(final String operationId, + protected void fillTemplateFactory( + final String operationId, final ProcessMethodResult processedMethod, final Map totalSchemas, final OperationParameterObject operationObject) throws IOException { final String classFullName = processedMethod.getNamespace(); @@ -238,7 +252,7 @@ protected String processMessageRef(final JsonNode messageBody, final String mode if (messageContent.startsWith("#")) { namespace = processModelPackage(MapperUtil.getLongRefClass(messageBody), modelPackage); } else if (messageContent.contains("#") || StringUtils.endsWith(messageContent, "yml") - || StringUtils.endsWith(messageContent, "yaml") || StringUtils.endsWith(messageContent, "json")) { + || StringUtils.endsWith(messageContent, "yaml") || StringUtils.endsWith(messageContent, "json")) { namespace = processExternalRef(modelPackage, ymlParent, messageBody); } else { namespace = processExternalAvro(ymlParent, messageContent); @@ -261,7 +275,9 @@ protected String processExternalAvro(final FileLocation ymlParent, final String final JsonNode fileTree = mapper.readTree(avroFile); final JsonNode avroNamespace = fileTree.get("namespace"); - if (avroNamespace == null) throw new InvalidAvroException(avroFilePath); + if (avroNamespace == null) { + throw new InvalidAvroException(avroFilePath); + } namespace = avroNamespace.asText() + PACKAGE_SEPARATOR + fileTree.get("name").asText(); } catch (final IOException e) { @@ -292,7 +308,8 @@ protected String processExternalRef(final String modelPackage, final FileLocatio } @Override - protected void processBindings(final ProcessBindingsResult.ProcessBindingsResultBuilder bindingsResult, final JsonNode message, + protected void processBindings( + final ProcessBindingsResult.ProcessBindingsResultBuilder bindingsResult, final JsonNode message, final CommonSpecFile commonSpecFile) { if (message.has(BINDINGS)) { final var bindingsNode = message.get(BINDINGS); @@ -335,6 +352,27 @@ protected String processModelPackage(final String extractedPackage, final String return processedPackage; } + @Override + protected JsonNode getChannelFromOperation(final JsonNode openApi, final JsonNode operation) { + return operation; + } + + @Override + protected String getOperationId(final JsonNode channel) { + final JsonNode channelDefinition = getChannelDefinition(channel); + if (!channelDefinition.has(OPERATION_ID)) { + throw new InvalidAsyncAPIException("Operation ID is required"); + } + + final String operationId = channelDefinition.get(OPERATION_ID).asText(); + if (processedOperationIds.contains(operationId)) { + throw new DuplicatedOperationException(operationId); + } + + processedOperationIds.add(operationId); + return operationId; + } + private Iterator> getChannels(final JsonNode node) { return ApiTool.hasNode(node, CHANNELS) ? ApiTool.getNode(node, CHANNELS).fields() : Collections.emptyIterator(); } @@ -408,25 +446,4 @@ private JsonNode getChannelDefinition(final JsonNode channel) { return channelDefinition; } - - @Override - protected String getOperationId(final JsonNode channel) { - final JsonNode channelDefinition = getChannelDefinition(channel); - if (!channelDefinition.has(OPERATION_ID)) { - throw new InvalidAsyncAPIException("Operation ID is required"); - } - - final String operationId = channelDefinition.get(OPERATION_ID).asText(); - if (processedOperationIds.contains(operationId)) { - throw new DuplicatedOperationException(operationId); - } - - processedOperationIds.add(operationId); - return operationId; - } - - @Override - protected JsonNode getChannelFromOperation(final JsonNode openApi, final JsonNode operation) { - return operation; - } } \ No newline at end of file diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/handler/AsyncApi3Handler.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/handler/AsyncApi3Handler.java index 3203a76a..e84d2707 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/handler/AsyncApi3Handler.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/handler/AsyncApi3Handler.java @@ -1,8 +1,26 @@ package com.sngular.api.generator.plugin.asyncapi.handler; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.sngular.api.generator.plugin.asyncapi.exception.*; +import com.sngular.api.generator.plugin.asyncapi.exception.ChannelNameException; +import com.sngular.api.generator.plugin.asyncapi.exception.DuplicatedOperationException; +import com.sngular.api.generator.plugin.asyncapi.exception.ExternalRefComponentNotFoundException; +import com.sngular.api.generator.plugin.asyncapi.exception.FileSystemException; +import com.sngular.api.generator.plugin.asyncapi.exception.InvalidAsyncAPIException; +import com.sngular.api.generator.plugin.asyncapi.exception.InvalidAvroException; import com.sngular.api.generator.plugin.asyncapi.model.ProcessBindingsResult; import com.sngular.api.generator.plugin.asyncapi.model.ProcessMethodResult; import com.sngular.api.generator.plugin.asyncapi.parameter.OperationParameterObject; @@ -21,21 +39,15 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URISyntaxException; -import java.util.*; -import java.util.Map.Entry; - public class AsyncApi3Handler extends BaseAsyncApiHandler { - public AsyncApi3Handler(final Integer springBootVersion, - boolean overwriteModel, - final File targetFolder, - final String processedGeneratedSourcesFolder, - final String groupId, - final File baseDir) { + public AsyncApi3Handler( + final Integer springBootVersion, + boolean overwriteModel, + final File targetFolder, + final String processedGeneratedSourcesFolder, + final String groupId, + final File baseDir) { super(springBootVersion, overwriteModel, targetFolder, processedGeneratedSourcesFolder, groupId, baseDir); } @@ -83,15 +95,15 @@ protected Map getAllSchemas(final FileLocation ymlParent, fina ApiTool.getComponent(node, SCHEMAS).forEachRemaining( schema -> totalSchemas.putIfAbsent(SCHEMAS.toUpperCase() + SLASH + MapperUtil.getSchemaKey(schema.getKey()), schema.getValue()) - ); + ); ApiTool.getComponent(node, MESSAGES).forEachRemaining( message -> getMessageSchemas(message.getKey(), message.getValue(), ymlParent, totalSchemas) - ); + ); getChannels(node).forEachRemaining( channel -> getChannelSchemas(channel.getValue(), totalSchemas, ymlParent) - ); + ); return totalSchemas; } @@ -101,7 +113,7 @@ protected void processOperation( final SpecFile fileParameter, final FileLocation ymlParent, final Entry entry, final JsonNode channel, final String operationId, final JsonNode operation, final Map totalSchemas) throws IOException, TemplateException { final String action = ApiTool.getNodeAsString(operation, "action"); - if (!StringUtils.endsWithIgnoreCase(action,"send") && !StringUtils.endsWithIgnoreCase(action,"receive")) { + if (!StringUtils.endsWithIgnoreCase(action, "send") && !StringUtils.endsWithIgnoreCase(action, "receive")) { throw new InvalidAsyncAPIException("Operation action must be either 'send' or 'receive'"); } @@ -137,7 +149,8 @@ protected void processSupplierMethod( @Override protected void processStreamBridgeMethod( - final String operationId, final JsonNode operation, final OperationParameterObject operationObject, final FileLocation ymlParent, final String channelName, final Map totalSchemas) + final String operationId, final JsonNode operation, final OperationParameterObject operationObject, final FileLocation ymlParent, final String channelName, + final Map totalSchemas) throws IOException { final ProcessMethodResult result = processMethod(operationId, operation, operationObject, ymlParent, totalSchemas); if (!channelName.matches("[a-zA-Z0-9.\\-]*")) { @@ -148,7 +161,8 @@ protected void processStreamBridgeMethod( } @Override - protected void processSubscribeMethod(final String operationId, + protected void processSubscribeMethod( + final String operationId, final JsonNode operation, final OperationParameterObject operationObject, final FileLocation ymlParent, final Map totalSchemas) throws IOException { final ProcessMethodResult result = processMethod(operationId, operation, operationObject, ymlParent, totalSchemas); @@ -157,7 +171,8 @@ protected void processSubscribeMethod(final String operationId, } @Override - protected void fillTemplateFactory(final String operationId, + protected void fillTemplateFactory( + final String operationId, final ProcessMethodResult processedMethod, final Map totalSchemas, final OperationParameterObject operationObject) throws IOException { final String classFullName = processedMethod.getNamespace(); @@ -235,19 +250,6 @@ protected Pair processMethodRef( return processPayload(operationObject, MapperUtil.getRefClass(method), solvePayload(message, totalSchemas, ymlParent), ymlParent); } - private JsonNode solvePayload(final JsonNode message, Map totalSchemas, FileLocation ymlParent) { - JsonNode payloadNode; - if (ApiTool.hasNode(message, PAYLOAD)) { - payloadNode = ApiTool.getNode(message, PAYLOAD); - } else if (ApiTool.hasRef(message)) { - final var solvedMessage = SchemaUtil.solveRef(ApiTool.getRefValue(message), totalSchemas, ymlParent.getPath()); - payloadNode = solvePayload(solvedMessage, totalSchemas, ymlParent); - } else { - payloadNode = message; - } - return payloadNode; - } - @Override protected String processMessageRef(final JsonNode messageBody, final String modelPackage, final FileLocation ymlParent) throws IOException { final String namespace; @@ -255,7 +257,7 @@ protected String processMessageRef(final JsonNode messageBody, final String mode if (messageContent.startsWith("#")) { namespace = processModelPackage(MapperUtil.getLongRefClass(messageBody), modelPackage); } else if (messageContent.contains("#") || StringUtils.endsWith(messageContent, "yml") - || StringUtils.endsWith(messageContent, "yaml") || StringUtils.endsWith(messageContent, "json")) { + || StringUtils.endsWith(messageContent, "yaml") || StringUtils.endsWith(messageContent, "json")) { namespace = processExternalRef(modelPackage, ymlParent, messageBody); } else { namespace = processExternalAvro(ymlParent, messageContent); @@ -278,7 +280,9 @@ protected String processExternalAvro(final FileLocation ymlParent, final String final JsonNode fileTree = mapper.readTree(avroFile); final JsonNode avroNamespace = fileTree.get("namespace"); - if (avroNamespace == null) throw new InvalidAvroException(avroFilePath); + if (avroNamespace == null) { + throw new InvalidAvroException(avroFilePath); + } namespace = avroNamespace.asText() + PACKAGE_SEPARATOR + fileTree.get("name").asText(); } catch (final IOException e) { @@ -306,7 +310,8 @@ protected String processExternalRef(final String modelPackage, final FileLocatio } @Override - protected void processBindings(final ProcessBindingsResult.ProcessBindingsResultBuilder bindingsResult, final JsonNode message, + protected void processBindings( + final ProcessBindingsResult.ProcessBindingsResultBuilder bindingsResult, final JsonNode message, final CommonSpecFile commonSpecFile) { if (message.has(BINDINGS)) { final var bindingsNode = message.get(BINDINGS); @@ -349,6 +354,44 @@ protected String processModelPackage(final String extractedPackage, final String return processedPackage; } + @Override + protected JsonNode getChannelFromOperation(final JsonNode openApi, final JsonNode operation) { + if (operation.has("channel")) { + final JsonNode channelRef = operation.get("channel"); + if (channelRef.has(REF)) { + final String channelPath = ApiTool.getRefValue(channelRef); + return ApiTool.getNode(openApi, channelPath.substring(1)); + } + } + throw new InvalidAsyncAPIException("Operation must have a channel reference"); + } + + @Override + protected String getOperationId(final JsonNode operation) { + if (!operation.has(OPERATION_ID)) { + throw new InvalidAsyncAPIException("Operation must have an operationId"); + } + final String operationId = operation.get(OPERATION_ID).asText(); + if (processedOperationIds.contains(operationId)) { + throw new DuplicatedOperationException(operationId); + } + processedOperationIds.add(operationId); + return operationId; + } + + private JsonNode solvePayload(final JsonNode message, Map totalSchemas, FileLocation ymlParent) { + JsonNode payloadNode; + if (ApiTool.hasNode(message, PAYLOAD)) { + payloadNode = ApiTool.getNode(message, PAYLOAD); + } else if (ApiTool.hasRef(message)) { + final var solvedMessage = SchemaUtil.solveRef(ApiTool.getRefValue(message), totalSchemas, ymlParent.path()); + payloadNode = solvePayload(solvedMessage, totalSchemas, ymlParent); + } else { + payloadNode = message; + } + return payloadNode; + } + private Iterator> getChannels(final JsonNode node) { return ApiTool.hasNode(node, CHANNELS) ? ApiTool.getFieldIterator(node, CHANNELS) : Collections.emptyIterator(); } @@ -401,29 +444,4 @@ private boolean isValidOperation( } return result; } - - @Override - protected JsonNode getChannelFromOperation(final JsonNode openApi, final JsonNode operation) { - if (operation.has("channel")) { - final JsonNode channelRef = operation.get("channel"); - if (channelRef.has(REF)) { - final String channelPath = ApiTool.getRefValue(channelRef); - return ApiTool.getNode(openApi, channelPath.substring(1)); - } - } - throw new InvalidAsyncAPIException("Operation must have a channel reference"); - } - - @Override - protected String getOperationId(final JsonNode operation) { - if (!operation.has(OPERATION_ID)) { - throw new InvalidAsyncAPIException("Operation must have an operationId"); - } - final String operationId = operation.get(OPERATION_ID).asText(); - if (processedOperationIds.contains(operationId)) { - throw new DuplicatedOperationException(operationId); - } - processedOperationIds.add(operationId); - return operationId; - } } \ No newline at end of file diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/handler/AsyncApiHandlerFactory.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/handler/AsyncApiHandlerFactory.java index 67b27d20..dafb2b5b 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/handler/AsyncApiHandlerFactory.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/handler/AsyncApiHandlerFactory.java @@ -1,27 +1,28 @@ package com.sngular.api.generator.plugin.asyncapi.handler; -import lombok.extern.slf4j.Slf4j; - import java.io.File; +import lombok.extern.slf4j.Slf4j; + @Slf4j public final class AsyncApiHandlerFactory { - private AsyncApiHandlerFactory() { - } + private AsyncApiHandlerFactory() { + } - public static BaseAsyncApiHandler getHandler(final String apiVersion, final Integer springBootVersion, - boolean overwriteModel, - final File targetFolder, - final String processedGeneratedSourcesFolder, - final String groupId, - final File baseDir) { - BaseAsyncApiHandler handler; - if (apiVersion.startsWith("3.")) { - handler = new AsyncApi3Handler(springBootVersion, overwriteModel, targetFolder, processedGeneratedSourcesFolder, groupId, baseDir); - } else { - handler = new AsyncApi2Handler(springBootVersion, overwriteModel, targetFolder, processedGeneratedSourcesFolder, groupId, baseDir); - } - return handler; + public static BaseAsyncApiHandler getHandler( + final String apiVersion, final Integer springBootVersion, + boolean overwriteModel, + final File targetFolder, + final String processedGeneratedSourcesFolder, + final String groupId, + final File baseDir) { + BaseAsyncApiHandler handler; + if (apiVersion.startsWith("3.")) { + handler = new AsyncApi3Handler(springBootVersion, overwriteModel, targetFolder, processedGeneratedSourcesFolder, groupId, baseDir); + } else { + handler = new AsyncApi2Handler(springBootVersion, overwriteModel, targetFolder, processedGeneratedSourcesFolder, groupId, baseDir); } + return handler; + } } \ No newline at end of file diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/handler/BaseAsyncApiHandler.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/handler/BaseAsyncApiHandler.java index fa3e445b..b3d314b6 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/handler/BaseAsyncApiHandler.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/handler/BaseAsyncApiHandler.java @@ -1,5 +1,18 @@ package com.sngular.api.generator.plugin.asyncapi.handler; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.regex.Pattern; + import com.fasterxml.jackson.databind.JsonNode; import com.sngular.api.generator.plugin.asyncapi.exception.DuplicateClassException; import com.sngular.api.generator.plugin.asyncapi.model.ProcessBindingsResult; @@ -20,59 +33,74 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.regex.Pattern; - @Slf4j public abstract class BaseAsyncApiHandler { protected static final String PACKAGE_SEPARATOR_STR = "."; + protected static final String SLASH = "/"; + protected static final Pattern PACKAGE_SEPARATOR = Pattern.compile(PACKAGE_SEPARATOR_STR); + protected static final String DEFAULT_ASYNCAPI_API_PACKAGE = "com.sngular.api.asyncapi"; + protected static final String DEFAULT_ASYNCAPI_MODEL_PACKAGE = DEFAULT_ASYNCAPI_API_PACKAGE + ".model"; + protected static final String CONSUMER_CLASS_NAME = "Subscriber"; + protected static final String SUPPLIER_CLASS_NAME = "Producer"; + protected static final String STREAM_BRIDGE_CLASS_NAME = "StreamBridgeProducer"; + protected static final String SUBSCRIBE = "subscribe"; + protected static final String PUBLISH = "publish"; + protected static final String OPERATION_ID = "operationId"; + protected static final String AVSC = "avsc"; + protected static final String PAYLOAD = "payload"; + protected static final String REF = "$ref"; + protected static final String MESSAGES = "messages"; + protected static final String EVENT = "event"; + protected static final String MESSAGE = "message"; + protected static final String SCHEMAS = "schemas"; + protected static final String CHANNELS = "channels"; + protected static final String BINDINGS = "bindings"; + protected static final String KAFKA = "kafka"; + protected static final String KEY = "key"; protected final List processedOperationIds = new ArrayList<>(); + protected final List processedClassnames = new ArrayList<>(); + protected final List processedApiPackages = new ArrayList<>(); + protected final Path baseDir; + protected final TemplateFactory templateFactory; + protected final String groupId; + protected final Integer springBootVersion; - protected BaseAsyncApiHandler(final Integer springBootVersion, - boolean overwriteModel, - final File targetFolder, - final String processedGeneratedSourcesFolder, - final String groupId, - final File baseDir) { + protected BaseAsyncApiHandler( + final Integer springBootVersion, + boolean overwriteModel, + final File targetFolder, + final String processedGeneratedSourcesFolder, + final String groupId, + final File baseDir) { this.groupId = groupId; this.baseDir = baseDir.toPath().toAbsolutePath(); this.templateFactory = new TemplateFactory(overwriteModel, targetFolder, processedGeneratedSourcesFolder, baseDir); @@ -135,22 +163,26 @@ protected abstract void processSupplierMethod( final Map totalSchemas) throws IOException, TemplateException; protected abstract void processStreamBridgeMethod( - final String operationId, final JsonNode channel, final OperationParameterObject operationObject, final FileLocation ymlParent, final String channelName, final Map totalSchemas) + final String operationId, final JsonNode channel, final OperationParameterObject operationObject, final FileLocation ymlParent, final String channelName, + final Map totalSchemas) throws IOException, TemplateException; protected abstract void processSubscribeMethod( final String operationId, final JsonNode channel, final OperationParameterObject operationObject, final FileLocation ymlParent, final Map totalSchemas) throws IOException, TemplateException; - protected abstract void fillTemplateFactory(final String operationId, + protected abstract void fillTemplateFactory( + final String operationId, final ProcessMethodResult processedMethod, final Map totalSchemas, final OperationParameterObject operationObject) throws IOException; - protected abstract ProcessMethodResult processMethod(final String operationId, + protected abstract ProcessMethodResult processMethod( + final String operationId, final JsonNode channel, final OperationParameterObject operationObject, final FileLocation ymlParent, final Map totalSchemas) throws IOException; - protected abstract Pair processPayload(final OperationParameterObject operationObject, final String messageName, final JsonNode payload, final FileLocation ymlParent) + protected abstract Pair processPayload( + final OperationParameterObject operationObject, final String messageName, final JsonNode payload, final FileLocation ymlParent) throws IOException; protected abstract Pair processMethodRef( @@ -163,10 +195,12 @@ protected abstract Pair processMethodRef( protected abstract String processExternalRef(final String modelPackage, final FileLocation ymlParent, final JsonNode message) throws IOException; - protected abstract void processBindings(final ProcessBindingsResult.ProcessBindingsResultBuilder bindingsResult, final JsonNode message, + protected abstract void processBindings( + final ProcessBindingsResult.ProcessBindingsResultBuilder bindingsResult, final JsonNode message, final CommonSpecFile commonSpecFile); - protected abstract void processKafkaBindings(final ProcessBindingsResult.ProcessBindingsResultBuilder bindingsResult, final JsonNode kafkaBindings, final CommonSpecFile specFile); + protected abstract void processKafkaBindings( + final ProcessBindingsResult.ProcessBindingsResultBuilder bindingsResult, final JsonNode kafkaBindings, final CommonSpecFile specFile); protected abstract String processModelPackage(final String extractedPackage, final String modelPackage); @@ -178,28 +212,16 @@ protected void setUpTemplate(final SpecFile fileParameter, final Integer springB processJavaEEPackage(springBootVersion); } - protected void processEntitiesSuffix(final SpecFile fileParameter) { - templateFactory.setSupplierEntitiesSuffix(fileParameter.getSupplier() != null && fileParameter.getSupplier().getModelNameSuffix() != null - ? fileParameter.getSupplier().getModelNameSuffix() : null); - templateFactory.setStreamBridgeEntitiesSuffix(fileParameter.getStreamBridge() != null && fileParameter.getStreamBridge().getModelNameSuffix() != null - ? fileParameter.getStreamBridge().getModelNameSuffix() : null); - templateFactory.setSubscribeEntitiesSuffix(fileParameter.getConsumer() != null && fileParameter.getConsumer().getModelNameSuffix() != null - ? fileParameter.getConsumer().getModelNameSuffix() : null); - } - - protected void checkClassPackageDuplicate(final String className, final String apiPackage) { - if (className != null && processedClassnames.contains(className) - && apiPackage != null && processedApiPackages.contains(apiPackage) - && processedClassnames.lastIndexOf(className) == processedApiPackages.lastIndexOf(apiPackage)) { - throw new DuplicateClassException(className, apiPackage); + protected void processPackage(final SpecFile fileParameter) { + if (ObjectUtils.anyNotNull(fileParameter.getSupplier(), fileParameter.getStreamBridge(), fileParameter.getConsumer())) { + templateFactory.setSupplierPackageName(evaluatePackage(fileParameter.getSupplier())); + templateFactory.setStreamBridgePackageName(evaluatePackage(fileParameter.getStreamBridge())); + templateFactory.setSubscribePackageName(evaluatePackage(fileParameter.getConsumer())); + } else { + throw new InvalidAPIException("No Configuration provided, nothing will be generated."); } } - protected void addProcessedClassesAndPackagesToGlobalVariables(final String className, final String apiPackage, final String defaultClassName) { - processedClassnames.add(className != null ? className : defaultClassName); - processedApiPackages.add(apiPackage != null ? apiPackage : DEFAULT_ASYNCAPI_API_PACKAGE); - } - protected void processClassNames(final SpecFile fileParameter) { templateFactory.setSupplierClassName(fileParameter.getSupplier() != null && fileParameter.getSupplier().getClassNamePostfix() != null ? fileParameter.getSupplier().getClassNamePostfix() : SUPPLIER_CLASS_NAME); @@ -209,18 +231,17 @@ protected void processClassNames(final SpecFile fileParameter) { ? fileParameter.getConsumer().getClassNamePostfix() : CONSUMER_CLASS_NAME); } - protected void processJavaEEPackage(final Integer springBootVersion) { - templateFactory.calculateJavaEEPackage(springBootVersion); + protected void processEntitiesSuffix(final SpecFile fileParameter) { + templateFactory.setSupplierEntitiesSuffix(fileParameter.getSupplier() != null && fileParameter.getSupplier().getModelNameSuffix() != null + ? fileParameter.getSupplier().getModelNameSuffix() : null); + templateFactory.setStreamBridgeEntitiesSuffix(fileParameter.getStreamBridge() != null && fileParameter.getStreamBridge().getModelNameSuffix() != null + ? fileParameter.getStreamBridge().getModelNameSuffix() : null); + templateFactory.setSubscribeEntitiesSuffix(fileParameter.getConsumer() != null && fileParameter.getConsumer().getModelNameSuffix() != null + ? fileParameter.getConsumer().getModelNameSuffix() : null); } - protected void processPackage(final SpecFile fileParameter) { - if (ObjectUtils.anyNotNull(fileParameter.getSupplier(), fileParameter.getStreamBridge(), fileParameter.getConsumer())) { - templateFactory.setSupplierPackageName(evaluatePackage(fileParameter.getSupplier())); - templateFactory.setStreamBridgePackageName(evaluatePackage(fileParameter.getStreamBridge())); - templateFactory.setSubscribePackageName(evaluatePackage(fileParameter.getConsumer())); - } else { - throw new InvalidAPIException("No Configuration provided, nothing will be generated."); - } + protected void processJavaEEPackage(final Integer springBootVersion) { + templateFactory.calculateJavaEEPackage(springBootVersion); } protected String evaluatePackage(final OperationParameterObject operation) { @@ -233,6 +254,19 @@ protected String evaluatePackage(final OperationParameterObject operation) { return evaluated; } + protected void checkClassPackageDuplicate(final String className, final String apiPackage) { + if (className != null && processedClassnames.contains(className) + && apiPackage != null && processedApiPackages.contains(apiPackage) + && processedClassnames.lastIndexOf(className) == processedApiPackages.lastIndexOf(apiPackage)) { + throw new DuplicateClassException(className, apiPackage); + } + } + + protected void addProcessedClassesAndPackagesToGlobalVariables(final String className, final String apiPackage, final String defaultClassName) { + processedClassnames.add(className != null ? className : defaultClassName); + processedApiPackages.add(apiPackage != null ? apiPackage : DEFAULT_ASYNCAPI_API_PACKAGE); + } + protected boolean shouldBuild(final JsonNode schemaToBuild) { boolean result = Boolean.FALSE; if (ApiTool.hasRef(schemaToBuild)) { @@ -252,5 +286,6 @@ protected void writeSchemaObject(final boolean usingLombok, final String modelPa } protected abstract JsonNode getChannelFromOperation(final JsonNode openApi, final JsonNode operation); + protected abstract String getOperationId(final JsonNode operation); } \ No newline at end of file diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/model/MethodObject.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/model/MethodObject.java index 6b2d2ae5..6222580f 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/model/MethodObject.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/model/MethodObject.java @@ -7,6 +7,7 @@ package com.sngular.api.generator.plugin.asyncapi.model; import java.util.Objects; + import com.sngular.api.generator.plugin.asyncapi.util.BindingTypeEnum; import com.sngular.api.generator.plugin.common.model.SchemaObject; import lombok.Builder; diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/parameter/OperationParameterObject.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/parameter/OperationParameterObject.java index f332414c..3d6e6228 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/parameter/OperationParameterObject.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/parameter/OperationParameterObject.java @@ -13,6 +13,7 @@ package com.sngular.api.generator.plugin.asyncapi.parameter; import java.util.List; + import com.sngular.api.generator.plugin.common.model.CommonSpecFile; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/template/ClassTemplate.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/template/ClassTemplate.java index 30a8ce46..811b2de2 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/template/ClassTemplate.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/template/ClassTemplate.java @@ -7,6 +7,7 @@ package com.sngular.api.generator.plugin.asyncapi.template; import java.nio.file.Path; + import com.sngular.api.generator.plugin.common.model.SchemaObject; import lombok.Builder; import lombok.Value; diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/template/ClasspathTemplateLoader.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/template/ClasspathTemplateLoader.java index fb7418e7..b75af53b 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/template/ClasspathTemplateLoader.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/template/ClasspathTemplateLoader.java @@ -6,9 +6,6 @@ package com.sngular.api.generator.plugin.asyncapi.template; -import com.sngular.api.generator.plugin.common.template.CommonTemplateLoader; -import com.sngular.api.generator.plugin.exception.GeneratorTemplateException; - import java.io.IOException; import java.io.InputStream; import java.util.HashMap; @@ -16,15 +13,18 @@ import java.util.Map; import java.util.Objects; -public class ClasspathTemplateLoader extends CommonTemplateLoader { +import com.sngular.api.generator.plugin.common.template.CommonTemplateLoader; +import com.sngular.api.generator.plugin.exception.GeneratorTemplateException; +public class ClasspathTemplateLoader extends CommonTemplateLoader { private static final List TEMPLATE_FILES = List.of( - "interfaceConsumer.ftlh", "interfaceConsumerWithKafkaBindings.ftlh", - "interfaceSupplier.ftlh", "interfaceSupplierWithKafkaBindings.ftlh", - "templateConsumers.ftlh", "templateConsumersWithKafkaBindings.ftlh", - "templateMessageWrapper.ftlh", "templateStreamBridge.ftlh", "templateStreamBridgeWithKafkaBindings.ftlh", - "templateSuppliers.ftlh", "templateSuppliersWithKafkaBindings.ftlh"); + "interfaceConsumer.ftlh", "interfaceConsumerWithKafkaBindings.ftlh", + "interfaceSupplier.ftlh", "interfaceSupplierWithKafkaBindings.ftlh", + "templateConsumers.ftlh", "templateConsumersWithKafkaBindings.ftlh", + "templateMessageWrapper.ftlh", "templateStreamBridge.ftlh", "templateStreamBridgeWithKafkaBindings.ftlh", + "templateSuppliers.ftlh", "templateSuppliersWithKafkaBindings.ftlh"); + public ClasspathTemplateLoader() { super(); init(getResourceFolderFiles()); @@ -35,7 +35,7 @@ private Map getResourceFolderFiles() { try { for (var templateFile : TEMPLATE_MODEL_FILES) { templates.put(templateFile, - readFile((InputStream) Objects.requireNonNull(LOADER.getResource("templates/model/" + templateFile)).getContent())); + readFile((InputStream) Objects.requireNonNull(LOADER.getResource("templates/model/" + templateFile)).getContent())); } for (var templateFile : TEMPLATE_FILES) { templates.put(templateFile, diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/template/TemplateFactory.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/template/TemplateFactory.java index ce8fe36a..c10d9ac7 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/template/TemplateFactory.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/template/TemplateFactory.java @@ -6,13 +6,6 @@ package com.sngular.api.generator.plugin.asyncapi.template; -import com.sngular.api.generator.plugin.asyncapi.exception.NonSupportedBindingException; -import com.sngular.api.generator.plugin.asyncapi.model.MethodObject; -import com.sngular.api.generator.plugin.asyncapi.parameter.SpecFile; -import com.sngular.api.generator.plugin.asyncapi.util.BindingTypeEnum; -import com.sngular.api.generator.plugin.common.template.CommonTemplateFactory; -import org.apache.commons.lang3.StringUtils; - import java.io.File; import java.io.IOException; import java.nio.file.Path; @@ -21,6 +14,13 @@ import java.util.Map; import java.util.Objects; +import com.sngular.api.generator.plugin.asyncapi.exception.NonSupportedBindingException; +import com.sngular.api.generator.plugin.asyncapi.model.MethodObject; +import com.sngular.api.generator.plugin.asyncapi.parameter.SpecFile; +import com.sngular.api.generator.plugin.asyncapi.util.BindingTypeEnum; +import com.sngular.api.generator.plugin.common.template.CommonTemplateFactory; +import org.apache.commons.lang3.StringUtils; + public class TemplateFactory extends CommonTemplateFactory { private static final String SUBSCRIBE_PACKAGE = "subscribePackage"; @@ -55,10 +55,11 @@ public class TemplateFactory extends CommonTemplateFactory { private String subscribeClassName = null; - public TemplateFactory(boolean enableOverwrite, - final File targetFolder, - final String processedGeneratedSourcesFolder, - final File baseDir) { + public TemplateFactory( + boolean enableOverwrite, + final File targetFolder, + final String processedGeneratedSourcesFolder, + final File baseDir) { super(enableOverwrite, targetFolder, processedGeneratedSourcesFolder, baseDir, new ClasspathTemplateLoader()); } @@ -84,6 +85,39 @@ public final void fillTemplates() throws IOException { this.generateInterfaces(); } + private String checkTemplate(final String bindingType, final String defaultTemplate) { + final String templateName; + switch (BindingTypeEnum.valueOf(bindingType)) { + case NONBINDING: + templateName = defaultTemplate; + break; + case KAFKA: + templateName = StringUtils.remove(defaultTemplate, ".ftlh") + TemplateIndexConstants.KAFKA_BINDINGS_FTLH; + break; + default: + throw new NonSupportedBindingException(bindingType); + } + return templateName; + } + + private void generateInterfaces() throws IOException { + final ArrayList allMethods = new ArrayList<>(subscribeMethods); + allMethods.addAll(publishMethods); + + for (MethodObject method : allMethods) { + addToRoot("method", method); + + if (Objects.equals(method.getType(), "publish")) { + fillTemplate(supplierFilePath, "I" + method.getOperationId().substring(0, 1).toUpperCase() + method.getOperationId().substring(1), + checkTemplate(method.getBindingType(), TemplateIndexConstants.TEMPLATE_INTERFACE_SUPPLIERS)); + } else if (Objects.equals(method.getType(), "subscribe")) { + fillTemplate(subscribeFilePath, "I" + method.getOperationId().substring(0, 1).toUpperCase() + method.getOperationId().substring(1), + checkTemplate(method.getBindingType(), TemplateIndexConstants.TEMPLATE_INTERFACE_CONSUMERS)); + } + } + cleanData(); + } + public final void setSubscribePackageName(final String packageName) { addToRoot(SUBSCRIBE_PACKAGE, packageName); } @@ -115,50 +149,38 @@ public final void setStreamBridgeClassName(final String className) { this.streamBridgeClassName = className; } - public final void setSubscribeFilePath(final Path path) { - this.subscribeFilePath = path.toString(); - } - - public final void setSupplierFilePath(final Path path) { - this.supplierFilePath = path.toString(); - } - - public final void setStreamBridgeFilePath(final Path path) { - this.streamBridgeFilePath = path.toString(); - } - public final void addSupplierMethod(final String operationId, final String classNamespace, final String bindings, final String bindingType) { publishMethods.add(MethodObject - .builder() - .operationId(operationId) - .classNamespace(classNamespace) - .type("publish") - .keyClassNamespace(bindings) - .bindingType(bindingType) - .build()); + .builder() + .operationId(operationId) + .classNamespace(classNamespace) + .type("publish") + .keyClassNamespace(bindings) + .bindingType(bindingType) + .build()); } public final void addStreamBridgeMethod(final String operationId, final String classNamespace, final String channelName, final String bindings, final String bindingType) { streamBridgeMethods.add(MethodObject - .builder() - .operationId(operationId) - .channelName(channelName) - .classNamespace(classNamespace) - .type("streamBridge") - .keyClassNamespace(bindings) - .bindingType(bindingType) - .build()); + .builder() + .operationId(operationId) + .channelName(channelName) + .classNamespace(classNamespace) + .type("streamBridge") + .keyClassNamespace(bindings) + .bindingType(bindingType) + .build()); } public final void addSubscribeMethod(final String operationId, final String classNamespace, final String bindings, final String bindingType) { subscribeMethods.add(MethodObject - .builder() - .operationId(operationId) - .classNamespace(classNamespace) - .type("subscribe") - .keyClassNamespace(bindings) - .bindingType(bindingType) - .build()); + .builder() + .operationId(operationId) + .classNamespace(classNamespace) + .type("subscribe") + .keyClassNamespace(bindings) + .bindingType(bindingType) + .build()); } public final void setSupplierEntitiesSuffix(final String suffix) { @@ -204,13 +226,13 @@ public final void fillTemplateWrapper( final String className, final String keyClassFullName, final String keyClassName - ) throws IOException { + ) throws IOException { final var filePath = processPath(getPath(modelPackage)); addToRoot(Map.of(WRAPPER_PACKAGE, modelPackage, - "classNamespace", classFullName, - "className", className, - "keyNamespace", keyClassFullName, - "keyClassName", keyClassName)); + "classNamespace", classFullName, + "className", className, + "keyNamespace", keyClassFullName, + "keyClassName", keyClassName)); writeTemplateToFile(TemplateIndexConstants.TEMPLATE_MESSAGE_WRAPPER, filePath, "MessageWrapper"); } @@ -228,36 +250,16 @@ public void processFilePaths(final SpecFile fileParameter, final String defaultA setSubscribeFilePath(processPath(pathToCreate)); } } - private void generateInterfaces() throws IOException { - final ArrayList allMethods = new ArrayList<>(subscribeMethods); - allMethods.addAll(publishMethods); - for (MethodObject method : allMethods) { - addToRoot("method", method); + public final void setSupplierFilePath(final Path path) { + this.supplierFilePath = path.toString(); + } - if (Objects.equals(method.getType(), "publish")) { - fillTemplate(supplierFilePath, "I" + method.getOperationId().substring(0, 1).toUpperCase() + method.getOperationId().substring(1), - checkTemplate(method.getBindingType(), TemplateIndexConstants.TEMPLATE_INTERFACE_SUPPLIERS)); - } else if (Objects.equals(method.getType(), "subscribe")) { - fillTemplate(subscribeFilePath, "I" + method.getOperationId().substring(0, 1).toUpperCase() + method.getOperationId().substring(1), - checkTemplate(method.getBindingType(), TemplateIndexConstants.TEMPLATE_INTERFACE_CONSUMERS)); - } - } - cleanData(); + public final void setStreamBridgeFilePath(final Path path) { + this.streamBridgeFilePath = path.toString(); } - private String checkTemplate(final String bindingType, final String defaultTemplate) { - final String templateName; - switch (BindingTypeEnum.valueOf(bindingType)) { - case NONBINDING: - templateName = defaultTemplate; - break; - case KAFKA: - templateName = StringUtils.remove(defaultTemplate, ".ftlh") + TemplateIndexConstants.KAFKA_BINDINGS_FTLH; - break; - default: - throw new NonSupportedBindingException(bindingType); - } - return templateName; + public final void setSubscribeFilePath(final Path path) { + this.subscribeFilePath = path.toString(); } } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/util/AsyncApiUtil.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/util/AsyncApiUtil.java index 7a43e668..f057bff7 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/util/AsyncApiUtil.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/util/AsyncApiUtil.java @@ -1,19 +1,19 @@ package com.sngular.api.generator.plugin.asyncapi.util; +import java.nio.file.Path; + import com.fasterxml.jackson.databind.JsonNode; import com.sngular.api.generator.plugin.asyncapi.parameter.SpecFile; import com.sngular.api.generator.plugin.common.tools.SchemaUtil; -import java.nio.file.Path; - public final class AsyncApiUtil { - private AsyncApiUtil() { - throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); - } + private AsyncApiUtil() { + throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); + } - public static JsonNode getPojoFromSpecFile(final Path baseDir, final SpecFile specFile) { + public static JsonNode getPojoFromSpecFile(final Path baseDir, final SpecFile specFile) { - return SchemaUtil.getPojoFromRef(baseDir.toUri(), specFile.getFilePath()); - } + return SchemaUtil.getPojoFromRef(baseDir.toUri(), specFile.getFilePath()); + } } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/util/ReferenceProcessor.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/util/ReferenceProcessor.java index b9adb143..903712ba 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/util/ReferenceProcessor.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/asyncapi/util/ReferenceProcessor.java @@ -1,5 +1,11 @@ package com.sngular.api.generator.plugin.asyncapi.util; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + import com.fasterxml.jackson.databind.JsonNode; import com.sngular.api.generator.plugin.asyncapi.exception.FileSystemException; import com.sngular.api.generator.plugin.common.files.FileLocation; @@ -8,12 +14,6 @@ import lombok.Builder; import org.apache.commons.lang3.StringUtils; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; - public final class ReferenceProcessor { private static final String JSON = "json"; @@ -26,12 +26,12 @@ public final class ReferenceProcessor { private static final String AVSC = "avsc"; - private List alreadyProcessed; - private final FileLocation ymlParent; private final Map totalSchemas; + private List alreadyProcessed; + @Builder public ReferenceProcessor(final FileLocation ymlParent, final Map totalSchemas) { this.ymlParent = ymlParent; diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/files/ClasspathFileLocation.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/files/ClasspathFileLocation.java index 1272526f..cb362a7f 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/files/ClasspathFileLocation.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/files/ClasspathFileLocation.java @@ -6,44 +6,35 @@ package com.sngular.api.generator.plugin.common.files; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.nio.file.Path; import java.nio.file.Paths; -@RequiredArgsConstructor -@Getter -public class ClasspathFileLocation implements FileLocation { +import com.sngular.api.generator.plugin.common.tools.PathUtil; - private final URI path; +public record ClasspathFileLocation(URI path) implements FileLocation { @Override - public final InputStream getFileAtLocation(final String filename) throws IOException { + public InputStream getFileAtLocation(final String filename) throws IOException { return resolveInUri(path, filename).toURL().openStream(); } - - @Override - public final URI getPath() { - return URI.create(path.toString()); - } - private static URI resolveInUri(URI parentUri, String relativePath) { + // Check if the path is absolute, and if so, use it directly + if (PathUtil.isAbsolutePath(relativePath)) { + return Paths.get(relativePath).toUri(); + } if ("jar".equals(parentUri.getScheme())) { String[] parts = parentUri.getSchemeSpecificPart().split("!", 2); if (parts.length != 2) { throw new IllegalArgumentException("Invalid JAR URI: " + parentUri); } - String jarPath = parts[0]; Path parentInsideJar = Paths.get(parts[1]); Path resolvedPath = parentInsideJar.resolve(relativePath).normalize(); - - return URI.create("jar:" + jarPath + "!" + resolvedPath.toString().replace("\\", "/")); + return URI.create("jar:" + jarPath + "!" + resolvedPath.toString().replace("\\\\", "/")); } else if ("file".equals(parentUri.getScheme())) { Path parentPath = Paths.get(parentUri); Path resolved = parentPath.resolve(relativePath).normalize(); @@ -52,4 +43,9 @@ private static URI resolveInUri(URI parentUri, String relativePath) { throw new IllegalArgumentException("Unsupported URI scheme: " + parentUri.getScheme()); } } + + @Override + public URI path() { + return URI.create(path.toString()); + } } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/files/DirectoryFileLocation.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/files/DirectoryFileLocation.java index fa4afadf..a67ea8c4 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/files/DirectoryFileLocation.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/files/DirectoryFileLocation.java @@ -6,15 +6,17 @@ package com.sngular.api.generator.plugin.common.files; -import com.sngular.api.generator.plugin.asyncapi.exception.FileSystemException; -import lombok.Getter; - +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.nio.file.Path; +import com.sngular.api.generator.plugin.asyncapi.exception.FileSystemException; +import com.sngular.api.generator.plugin.common.tools.PathUtil; +import lombok.Getter; + @Getter public class DirectoryFileLocation implements FileLocation { @@ -27,14 +29,21 @@ public DirectoryFileLocation(final Path directoryPath) { @Override public final InputStream getFileAtLocation(final String filename) { try { - return new FileInputStream(path.resolve(filename).toFile()); + // Check if filename is an absolute path + if (PathUtil.isAbsolutePath(filename)) { + // For absolute paths, open directly without resolving against parent + return new FileInputStream(new File(filename)); + } else { + // For relative paths, resolve against the parent directory + return new FileInputStream(path.resolve(filename).toFile()); + } } catch (final IOException e) { throw new FileSystemException(e.getMessage()); } } @Override - public final URI getPath() { + public final URI path() { return path.toUri(); } } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/files/FileLocation.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/files/FileLocation.java index 66f726f5..f9dc8b96 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/files/FileLocation.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/files/FileLocation.java @@ -14,5 +14,5 @@ public interface FileLocation { InputStream getFileAtLocation(String filename) throws IOException; - URI getPath(); + URI path(); } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/CommonSpecFile.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/CommonSpecFile.java index 19361ff7..64fb292c 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/CommonSpecFile.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/CommonSpecFile.java @@ -1,6 +1,7 @@ package com.sngular.api.generator.plugin.common.model; import java.util.Map; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -13,30 +14,30 @@ @AllArgsConstructor public class CommonSpecFile { - private String filePath; + private String filePath; - private String apiPackage; + private String apiPackage; - private String modelPackage; + private String modelPackage; - private String modelNamePrefix; + private String modelNamePrefix; - private String modelNameSuffix; + private String modelNameSuffix; - private String classNamePostfix; + private String classNamePostfix; - private boolean useLombokModelAnnotation; + private boolean useLombokModelAnnotation; - @Builder.Default - private String dateTimeFormat = "yyyy-MM-dd'T'HH:mm:ss"; + @Builder.Default + private String dateTimeFormat = "yyyy-MM-dd'T'HH:mm:ss"; - @Builder.Default - private String dateFormat = "yyyy-MM-dd"; + @Builder.Default + private String dateFormat = "yyyy-MM-dd"; - @Builder.Default - private TypeConstants.TimeType useTimeType = TypeConstants.TimeType.LOCAL; + @Builder.Default + private TypeConstants.TimeType useTimeType = TypeConstants.TimeType.LOCAL; - public Map getFormats() { - return Map.of("DATE_TIME", dateTimeFormat, "DATE", dateFormat); - } + public Map getFormats() { + return Map.of("DATE_TIME", dateTimeFormat, "DATE", dateFormat); + } } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaFieldObject.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaFieldObject.java index 601b17ba..4d546b85 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaFieldObject.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaFieldObject.java @@ -1,6 +1,7 @@ package com.sngular.api.generator.plugin.common.model; import java.util.Map; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -12,19 +13,19 @@ @EqualsAndHashCode(of = "baseName") public class SchemaFieldObject { - private String baseName; + private String baseName; - @Builder.Default - private SchemaFieldObjectType dataType = new SchemaFieldObjectType(TypeConstants.OBJECT); + @Builder.Default + private SchemaFieldObjectType dataType = new SchemaFieldObjectType(TypeConstants.OBJECT); - @Builder.Default - private SchemaFieldObjectProperties restrictions = new SchemaFieldObjectProperties(); + @Builder.Default + private SchemaFieldObjectProperties restrictions = new SchemaFieldObjectProperties(); - private String importClass; + private String importClass; - private boolean required; + private boolean required; - private Map enumValues; + private Map enumValues; - private Object constValue; + private Object constValue; } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaFieldObjectProperties.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaFieldObjectProperties.java index e644f6f3..0e961b52 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaFieldObjectProperties.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaFieldObjectProperties.java @@ -3,6 +3,7 @@ import java.util.HashSet; import java.util.Objects; import java.util.Set; + import lombok.Data; @Data diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaFieldObjectType.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaFieldObjectType.java index 61f91c70..f1b5bc0d 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaFieldObjectType.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaFieldObjectType.java @@ -6,38 +6,40 @@ package com.sngular.api.generator.plugin.common.model; -import com.sngular.api.generator.plugin.openapi.exception.CodeGenerationException; -import lombok.Data; -import org.apache.commons.lang3.StringUtils; - import java.util.AbstractMap.SimpleImmutableEntry; import java.util.Map; import java.util.Objects; +import com.sngular.api.generator.plugin.openapi.exception.CodeGenerationException; +import lombok.Data; +import org.apache.commons.lang3.StringUtils; + @Data public class SchemaFieldObjectType { public static final String ZONED_DATE_TIME = "ZonedDateTime"; + public static final String OFFSET_DATE_TIME = "OffsetDateTime"; + private static final Map TYPE_MAPPINGS = Map.ofEntries( - new SimpleImmutableEntry<>(TypeConstants.OBJECT, "Object"), - new SimpleImmutableEntry<>(TypeConstants.ARRAY, "List"), - new SimpleImmutableEntry<>(TypeConstants.MAP, "Map"), - new SimpleImmutableEntry<>(TypeConstants.BIG_DECIMAL, "BigDecimal"), - new SimpleImmutableEntry<>(TypeConstants.INTEGER, "Integer"), - new SimpleImmutableEntry<>(TypeConstants.DOUBLE, "Double"), - new SimpleImmutableEntry<>(TypeConstants.FLOAT, "Float"), - new SimpleImmutableEntry<>(TypeConstants.LONG, "Long"), - new SimpleImmutableEntry<>(TypeConstants.STRING, "String"), - new SimpleImmutableEntry<>(TypeConstants.ENUM, "Enum"), - new SimpleImmutableEntry<>(TypeConstants.LOCALDATE, "LocalDate"), - new SimpleImmutableEntry<>(TypeConstants.LOCALDATETIME, "LocalDateTime"), - new SimpleImmutableEntry<>(TypeConstants.ZONEDDATE, ZONED_DATE_TIME), - new SimpleImmutableEntry<>(TypeConstants.ZONEDDATETIME, ZONED_DATE_TIME), - new SimpleImmutableEntry<>(TypeConstants.OFFSETDATE, OFFSET_DATE_TIME), - new SimpleImmutableEntry<>(TypeConstants.OFFSETDATETIME, OFFSET_DATE_TIME), - new SimpleImmutableEntry<>(TypeConstants.MULTIPART_FILE, "MultipartFile") - ); + new SimpleImmutableEntry<>(TypeConstants.OBJECT, "Object"), + new SimpleImmutableEntry<>(TypeConstants.ARRAY, "List"), + new SimpleImmutableEntry<>(TypeConstants.MAP, "Map"), + new SimpleImmutableEntry<>(TypeConstants.BIG_DECIMAL, "BigDecimal"), + new SimpleImmutableEntry<>(TypeConstants.INTEGER, "Integer"), + new SimpleImmutableEntry<>(TypeConstants.DOUBLE, "Double"), + new SimpleImmutableEntry<>(TypeConstants.FLOAT, "Float"), + new SimpleImmutableEntry<>(TypeConstants.LONG, "Long"), + new SimpleImmutableEntry<>(TypeConstants.STRING, "String"), + new SimpleImmutableEntry<>(TypeConstants.ENUM, "Enum"), + new SimpleImmutableEntry<>(TypeConstants.LOCALDATE, "LocalDate"), + new SimpleImmutableEntry<>(TypeConstants.LOCALDATETIME, "LocalDateTime"), + new SimpleImmutableEntry<>(TypeConstants.ZONEDDATE, ZONED_DATE_TIME), + new SimpleImmutableEntry<>(TypeConstants.ZONEDDATETIME, ZONED_DATE_TIME), + new SimpleImmutableEntry<>(TypeConstants.OFFSETDATE, OFFSET_DATE_TIME), + new SimpleImmutableEntry<>(TypeConstants.OFFSETDATETIME, OFFSET_DATE_TIME), + new SimpleImmutableEntry<>(TypeConstants.MULTIPART_FILE, "MultipartFile") + ); private static final Map IMPORT_TYPE_MAPPINGS = Map.ofEntries( new SimpleImmutableEntry<>(TypeConstants.OBJECT, "java.util.Object"), @@ -52,32 +54,32 @@ public class SchemaFieldObjectType { new SimpleImmutableEntry<>(TypeConstants.OFFSETDATE, "java.time." + OFFSET_DATE_TIME), new SimpleImmutableEntry<>(TypeConstants.OFFSETDATETIME, "java.time." + OFFSET_DATE_TIME), new SimpleImmutableEntry<>(TypeConstants.MULTIPART_FILE, "MultipartFile") - ); + ); private static final Map IMPL_TYPE_MAPPINGS = Map.ofEntries( - new SimpleImmutableEntry<>(TypeConstants.OBJECT, "Object"), - new SimpleImmutableEntry<>(TypeConstants.ARRAY, "ArrayList"), - new SimpleImmutableEntry<>(TypeConstants.MAP, "HashMap"), - new SimpleImmutableEntry<>(TypeConstants.BIG_DECIMAL, "BigDecimal"), - new SimpleImmutableEntry<>(TypeConstants.INTEGER, "Integer"), - new SimpleImmutableEntry<>(TypeConstants.DOUBLE, "Double"), - new SimpleImmutableEntry<>(TypeConstants.FLOAT, "Float"), - new SimpleImmutableEntry<>(TypeConstants.LONG, "Long"), - new SimpleImmutableEntry<>(TypeConstants.STRING, "String"), - new SimpleImmutableEntry<>(TypeConstants.ENUM, "Enum"), - new SimpleImmutableEntry<>(TypeConstants.LOCALDATE, "LocalDate"), - new SimpleImmutableEntry<>(TypeConstants.LOCALDATETIME, "LocalDateTime"), - new SimpleImmutableEntry<>(TypeConstants.ZONEDDATE, ZONED_DATE_TIME), - new SimpleImmutableEntry<>(TypeConstants.ZONEDDATETIME, ZONED_DATE_TIME), - new SimpleImmutableEntry<>(TypeConstants.OFFSETDATE, OFFSET_DATE_TIME), - new SimpleImmutableEntry<>(TypeConstants.OFFSETDATETIME, OFFSET_DATE_TIME), - new SimpleImmutableEntry<>(TypeConstants.MULTIPART_FILE, "MultipartFile") - ); - - private SchemaFieldObjectType innerType; + new SimpleImmutableEntry<>(TypeConstants.OBJECT, "Object"), + new SimpleImmutableEntry<>(TypeConstants.ARRAY, "ArrayList"), + new SimpleImmutableEntry<>(TypeConstants.MAP, "HashMap"), + new SimpleImmutableEntry<>(TypeConstants.BIG_DECIMAL, "BigDecimal"), + new SimpleImmutableEntry<>(TypeConstants.INTEGER, "Integer"), + new SimpleImmutableEntry<>(TypeConstants.DOUBLE, "Double"), + new SimpleImmutableEntry<>(TypeConstants.FLOAT, "Float"), + new SimpleImmutableEntry<>(TypeConstants.LONG, "Long"), + new SimpleImmutableEntry<>(TypeConstants.STRING, "String"), + new SimpleImmutableEntry<>(TypeConstants.ENUM, "Enum"), + new SimpleImmutableEntry<>(TypeConstants.LOCALDATE, "LocalDate"), + new SimpleImmutableEntry<>(TypeConstants.LOCALDATETIME, "LocalDateTime"), + new SimpleImmutableEntry<>(TypeConstants.ZONEDDATE, ZONED_DATE_TIME), + new SimpleImmutableEntry<>(TypeConstants.ZONEDDATETIME, ZONED_DATE_TIME), + new SimpleImmutableEntry<>(TypeConstants.OFFSETDATE, OFFSET_DATE_TIME), + new SimpleImmutableEntry<>(TypeConstants.OFFSETDATETIME, OFFSET_DATE_TIME), + new SimpleImmutableEntry<>(TypeConstants.MULTIPART_FILE, "MultipartFile") + ); private final String baseType; + private SchemaFieldObjectType innerType; + public SchemaFieldObjectType(final String baseType, final SchemaFieldObjectType innerType) { this.innerType = innerType; this.baseType = baseType; @@ -100,6 +102,10 @@ public static SchemaFieldObjectType fromTypeList(final String... types) { return result; } + public void setDeepType(final String type) { + setDeepType(new SchemaFieldObjectType(type)); + } + public void setDeepType(final SchemaFieldObjectType type) { SchemaFieldObjectType parentType = this; while (Objects.nonNull(parentType.innerType)) { @@ -109,10 +115,6 @@ public void setDeepType(final SchemaFieldObjectType type) { parentType.innerType = type; } - public void setDeepType(final String type) { - setDeepType(new SchemaFieldObjectType(type)); - } - public boolean containsType(final String type) { return type.equalsIgnoreCase(baseType) || Objects.nonNull(innerType) && innerType.containsType(type); } @@ -135,7 +137,7 @@ public String getImplementationTypeString() { private String innerGetClassString() { final String baseString = TypeConstants.OBJECT.equals(baseType) && Objects.nonNull(innerType) ? innerType.innerGetClassString() - : TYPE_MAPPINGS.getOrDefault(baseType, baseType); + : TYPE_MAPPINGS.getOrDefault(baseType, baseType); return baseString.split("<")[0]; } @@ -150,8 +152,8 @@ public String getVariableNameString() { } @Override - public String toString() { - return mapIntoString(TYPE_MAPPINGS); + public int hashCode() { + return Objects.hash(Objects.isNull(innerType) ? 0 : innerType.hashCode(), baseType); } @Override @@ -167,8 +169,8 @@ public boolean equals(final Object obj) { } @Override - public int hashCode() { - return Objects.hash(Objects.isNull(innerType) ? 0 : innerType.hashCode(), baseType); + public String toString() { + return mapIntoString(TYPE_MAPPINGS); } public String getImportName() { diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaObject.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaObject.java index a3ddc3f2..a8576ef1 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaObject.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaObject.java @@ -4,6 +4,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -17,44 +18,44 @@ @EqualsAndHashCode(of = {"schemaName", "className"}) public class SchemaObject { - private boolean isEnum; + private boolean isEnum; - private String schemaName; + private String schemaName; - private String className; + private String className; - private List importList; + private List importList; - private Set fieldObjectList; + private Set fieldObjectList; - private String schemaCombinator; + private String schemaCombinator; - private String parentPackage; + private String parentPackage; - public static final class SchemaObjectBuilder { + public static final class SchemaObjectBuilder { - private final List importList = new ArrayList<>(); + private final List importList = new ArrayList<>(); - private final Set fieldObjectList = new HashSet<>(); + private final Set fieldObjectList = new HashSet<>(); - public SchemaObjectBuilder importList(final List importList) { - this.importList.addAll(importList); - return this; - } + public SchemaObjectBuilder importList(final List importList) { + this.importList.addAll(importList); + return this; + } - public SchemaObjectBuilder importItem(final String importItem) { - this.importList.add(importItem); - return this; - } + public SchemaObjectBuilder importItem(final String importItem) { + this.importList.add(importItem); + return this; + } - public SchemaObjectBuilder fieldObjectList(final Set fieldObjectList) { - this.fieldObjectList.addAll(fieldObjectList); - return this; - } + public SchemaObjectBuilder fieldObjectList(final Set fieldObjectList) { + this.fieldObjectList.addAll(fieldObjectList); + return this; + } - public SchemaObjectBuilder fieldObject(final SchemaFieldObject fieldObject) { - this.fieldObjectList.add(fieldObject); - return this; - } + public SchemaObjectBuilder fieldObject(final SchemaFieldObject fieldObject) { + this.fieldObjectList.add(fieldObject); + return this; } + } } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/TypeConstants.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/TypeConstants.java index e713f6d3..a4fd82a7 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/TypeConstants.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/TypeConstants.java @@ -73,6 +73,7 @@ public final class TypeConstants { ZONEDDATETIME, OFFSETDATE, OFFSETDATETIME); + public static final Set ALL_TYPES = Set.of( NUMBER, BOOLEAN, @@ -91,8 +92,8 @@ public final class TypeConstants { ZONEDDATETIME, OFFSETDATE, OFFSETDATETIME, - MULTIPART_FILE - ); + MULTIPART_FILE + ); private TypeConstants() { } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/template/CommonTemplateFactory.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/template/CommonTemplateFactory.java index e5895ac1..9b4c4dd4 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/template/CommonTemplateFactory.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/template/CommonTemplateFactory.java @@ -1,5 +1,20 @@ package com.sngular.api.generator.plugin.common.template; +import java.io.File; +import java.io.FileWriter; +import java.io.FilenameFilter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + import com.sngular.api.generator.plugin.asyncapi.exception.FileSystemException; import com.sngular.api.generator.plugin.asyncapi.parameter.OperationParameterObject; import com.sngular.api.generator.plugin.asyncapi.template.ClassTemplate; @@ -14,15 +29,6 @@ import freemarker.template.TemplateExceptionHandler; import org.apache.commons.lang3.StringUtils; -import java.io.File; -import java.io.FileWriter; -import java.io.FilenameFilter; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.*; - public abstract class CommonTemplateFactory { private static final List BASIC_DATA_TYPES = List.of("Integer", "Long", "Float", "Double", "Boolean", "String", "Char", "Byte", "Short"); @@ -35,6 +41,8 @@ public abstract class CommonTemplateFactory { private static final String FILE_TYPE_JAVA = ".java"; + protected boolean generateExceptionTemplate; + private final Configuration cfg = new Configuration(Configuration.VERSION_2_3_32); private final Map root = new HashMap<>(); @@ -51,13 +59,12 @@ public abstract class CommonTemplateFactory { private final File baseDir; - protected boolean generateExceptionTemplate; - - protected CommonTemplateFactory(boolean checkOverwrite, - final File targetFolder, - final String processedGeneratedSourcesFolder, - final File baseDir, - final CommonTemplateLoader classpathTemplateLoader) { + protected CommonTemplateFactory( + boolean checkOverwrite, + final File targetFolder, + final String processedGeneratedSourcesFolder, + final File baseDir, + final CommonTemplateLoader classpathTemplateLoader) { this.checkOverwrite = checkOverwrite; cfg.setTemplateLoader(classpathTemplateLoader); cfg.setDefaultEncoding("UTF-8"); @@ -66,41 +73,19 @@ protected CommonTemplateFactory(boolean checkOverwrite, cfg.setAPIBuiltinEnabled(true); addToRoot("checkBasicTypes", BASIC_DATA_TYPES); this.targetFolder = targetFolder; - this.targetFileFilter = (dir, name) -> name.toLowerCase().contains(targetFolder.toPath().getFileName().toString()); + this.targetFileFilter = (dir, name) -> name.toLowerCase().contains(targetFolder.toPath().getFileName().toString()); this.processedGeneratedSourcesFolder = processedGeneratedSourcesFolder; this.baseDir = baseDir; } - private static String getTemplateName(ClassTemplate classTemplate) { - String templateName; - if (classTemplate.getClassSchema().isEnum()) { - templateName = CommonTemplateIndexConstants.TEMPLATE_CONTENT_ENUM; - } else { - templateName = classTemplate.isUseLombok() ? CommonTemplateIndexConstants.TEMPLATE_CONTENT_SCHEMA_LOMBOK : CommonTemplateIndexConstants.TEMPLATE_CONTENT_SCHEMA; - } - return templateName; - } - - private ClassTemplate getClassTemplate() { - ClassTemplate ourClassTemplate = null; - final var classTemplateListIt = classTemplateList.iterator(); - while (Objects.isNull(ourClassTemplate) && classTemplateListIt.hasNext()) { - final var classTemplate = classTemplateListIt.next(); - if (classTemplate.getFilePath().endsWith("schemas")) { - ourClassTemplate = classTemplate; - } - } - if (ourClassTemplate == null) { - ourClassTemplate = classTemplateList.get(0); - } - - return ourClassTemplate; + protected void addToRoot(final String key, final Object value) { + root.put(key, value); } protected void generateTemplates() { final String exceptionPackage; - if (Boolean.TRUE.equals(generateExceptionTemplate)) { + if (generateExceptionTemplate) { exceptionPackage = getClassTemplate().getModelPackage(); } else { exceptionPackage = null; @@ -109,7 +94,7 @@ protected void generateTemplates() { classTemplateList.forEach(classTemplate -> { try { fillTemplates(classTemplate.getPropertiesPath(), classTemplate.getModelPackage(), - fillTemplateSchema(classTemplate, exceptionPackage)); + fillTemplateSchema(classTemplate, exceptionPackage)); if (generateExceptionTemplate) { fillTemplateModelClassException(classTemplate.getModelPackage()); } @@ -119,10 +104,20 @@ protected void generateTemplates() { }); } - protected void fillTemplate(final String filePathToSave, final String className, final String templateName) throws IOException { - final var fileToSave = Paths.get(filePathToSave); - fileToSave.toFile().mkdirs(); - writeTemplateToFile(templateName, fileToSave, className); + private ClassTemplate getClassTemplate() { + ClassTemplate ourClassTemplate = null; + final var classTemplateListIt = classTemplateList.iterator(); + while (Objects.isNull(ourClassTemplate) && classTemplateListIt.hasNext()) { + final var classTemplate = classTemplateListIt.next(); + if (classTemplate.getFilePath().endsWith("schemas")) { + ourClassTemplate = classTemplate; + } + } + if (ourClassTemplate == null) { + ourClassTemplate = classTemplateList.get(0); + } + + return ourClassTemplate; } @SuppressWarnings("checkstyle:CyclomaticComplexity") @@ -131,51 +126,51 @@ protected void fillTemplates(final Path filePathToSave, final String modelPackag switch (current) { case "Size": fillTemplateCustom(filePathToSave, modelPackage, "Size", CommonTemplateIndexConstants.TEMPLATE_SIZE_ANNOTATION, "SizeValidator", - CommonTemplateIndexConstants.TEMPLATE_SIZE_VALIDATOR_ANNOTATION); + CommonTemplateIndexConstants.TEMPLATE_SIZE_VALIDATOR_ANNOTATION); break; case "Pattern": fillTemplateCustom(filePathToSave, modelPackage, "Pattern", CommonTemplateIndexConstants.TEMPLATE_PATTERN_ANNOTATION, - "PatternValidator", CommonTemplateIndexConstants.TEMPLATE_PATTERN_VALIDATOR_ANNOTATION); + "PatternValidator", CommonTemplateIndexConstants.TEMPLATE_PATTERN_VALIDATOR_ANNOTATION); break; case "MultipleOf": fillTemplateCustom(filePathToSave, modelPackage, "MultipleOf", CommonTemplateIndexConstants.TEMPLATE_MULTIPLEOF_ANNOTATION, - "MultipleOfValidator", CommonTemplateIndexConstants.TEMPLATE_MULTIPLEOF_VALIDATOR_ANNOTATION); + "MultipleOfValidator", CommonTemplateIndexConstants.TEMPLATE_MULTIPLEOF_VALIDATOR_ANNOTATION); break; case "Maximum": fillTemplateCustom(filePathToSave, modelPackage, "MaxInteger", CommonTemplateIndexConstants.TEMPLATE_MAX_INTEGER_ANNOTATION, - "MaxIntegerValidator", CommonTemplateIndexConstants.TEMPLATE_MAX_INTEGER_VALIDATOR_ANNOTATION); + "MaxIntegerValidator", CommonTemplateIndexConstants.TEMPLATE_MAX_INTEGER_VALIDATOR_ANNOTATION); fillTemplateCustom(filePathToSave, modelPackage, "MaxBigDecimal", CommonTemplateIndexConstants.TEMPLATE_MAX_BIG_DECIMAL_ANNOTATION, - "MaxBigDecimalValidator", CommonTemplateIndexConstants.TEMPLATE_MAX_BIG_DECIMAL_VALIDATOR_ANNOTATION); + "MaxBigDecimalValidator", CommonTemplateIndexConstants.TEMPLATE_MAX_BIG_DECIMAL_VALIDATOR_ANNOTATION); fillTemplateCustom(filePathToSave, modelPackage, "MaxDouble", CommonTemplateIndexConstants.TEMPLATE_MAX_DOUBLE_ANNOTATION, - "MaxDoubleValidator", CommonTemplateIndexConstants.TEMPLATE_MAX_DOUBLE_VALIDATOR_ANNOTATION); + "MaxDoubleValidator", CommonTemplateIndexConstants.TEMPLATE_MAX_DOUBLE_VALIDATOR_ANNOTATION); fillTemplateCustom(filePathToSave, modelPackage, "MaxFloat", CommonTemplateIndexConstants.TEMPLATE_MAX_FLOAT_ANNOTATION, - "MaxFloatValidator", CommonTemplateIndexConstants.TEMPLATE_MAX_FLOAT_VALIDATOR_ANNOTATION); + "MaxFloatValidator", CommonTemplateIndexConstants.TEMPLATE_MAX_FLOAT_VALIDATOR_ANNOTATION); break; case "Minimum": fillTemplateCustom(filePathToSave, modelPackage, "MinInteger", CommonTemplateIndexConstants.TEMPLATE_MIN_INTEGER_ANNOTATION, - "MinIntegerValidator", CommonTemplateIndexConstants.TEMPLATE_MIN_INTEGER_VALIDATOR_ANNOTATION); + "MinIntegerValidator", CommonTemplateIndexConstants.TEMPLATE_MIN_INTEGER_VALIDATOR_ANNOTATION); fillTemplateCustom(filePathToSave, modelPackage, "MinDouble", CommonTemplateIndexConstants.TEMPLATE_MIN_DOUBLE_ANNOTATION, - "MinDoubleValidator", CommonTemplateIndexConstants.TEMPLATE_MIN_DOUBLE_VALIDATOR_ANNOTATION); + "MinDoubleValidator", CommonTemplateIndexConstants.TEMPLATE_MIN_DOUBLE_VALIDATOR_ANNOTATION); fillTemplateCustom(filePathToSave, modelPackage, "MinFloat", CommonTemplateIndexConstants.TEMPLATE_MIN_FLOAT_ANNOTATION, - "MinFloatValidator", CommonTemplateIndexConstants.TEMPLATE_MIN_FLOAT_VALIDATOR_ANNOTATION); + "MinFloatValidator", CommonTemplateIndexConstants.TEMPLATE_MIN_FLOAT_VALIDATOR_ANNOTATION); fillTemplateCustom(filePathToSave, modelPackage, "MinBigDecimal", CommonTemplateIndexConstants.TEMPLATE_MIN_BIG_DECIMAL_ANNOTATION, - "MinBigDecimalValidator", CommonTemplateIndexConstants.TEMPLATE_MIN_BIG_DECIMAL_VALIDATOR_ANNOTATION); + "MinBigDecimalValidator", CommonTemplateIndexConstants.TEMPLATE_MIN_BIG_DECIMAL_VALIDATOR_ANNOTATION); break; case "MaxItems": fillTemplateCustom(filePathToSave, modelPackage, "MaxItems", CommonTemplateIndexConstants.TEMPLATE_MAX_ITEMS_ANNOTATION, - "MaxItemsValidator", CommonTemplateIndexConstants.TEMPLATE_MAX_ITEMS_VALIDATOR_ANNOTATION); + "MaxItemsValidator", CommonTemplateIndexConstants.TEMPLATE_MAX_ITEMS_VALIDATOR_ANNOTATION); break; case "MinItems": fillTemplateCustom(filePathToSave, modelPackage, "MinItems", CommonTemplateIndexConstants.TEMPLATE_MIN_ITEMS_ANNOTATION, - "MinItemsValidator", CommonTemplateIndexConstants.TEMPLATE_MIN_ITEMS_VALIDATOR_ANNOTATION); + "MinItemsValidator", CommonTemplateIndexConstants.TEMPLATE_MIN_ITEMS_VALIDATOR_ANNOTATION); break; case "NotNull": fillTemplateCustom(filePathToSave, modelPackage, "NotNull", CommonTemplateIndexConstants.TEMPLATE_NOT_NULL_ANNOTATION, - "NotNullValidator", CommonTemplateIndexConstants.TEMPLATE_NOT_NULL_VALIDATOR_ANNOTATION); + "NotNullValidator", CommonTemplateIndexConstants.TEMPLATE_NOT_NULL_VALIDATOR_ANNOTATION); break; case "UniqueItems": fillTemplateCustom(filePathToSave, modelPackage, "UniqueItems", CommonTemplateIndexConstants.TEMPLATE_UNIQUE_ITEMS_ANNOTATION, - "UniqueItemsValidator", CommonTemplateIndexConstants.TEMPLATE_UNIQUE_ITEMS_VALIDATOR_ANNOTATION); + "UniqueItemsValidator", CommonTemplateIndexConstants.TEMPLATE_UNIQUE_ITEMS_VALIDATOR_ANNOTATION); break; default: break; @@ -185,7 +180,7 @@ protected void fillTemplates(final Path filePathToSave, final String modelPackag @SuppressWarnings("checkstyle:CyclomaticComplexity") private Set fillTemplateSchema(final ClassTemplate classTemplate, final String exceptionPackage) - throws IOException { + throws IOException { final var propertiesSet = new HashSet(); final var schemaObject = classTemplate.getClassSchema(); final var filePath = classTemplate.getFilePath(); @@ -201,7 +196,7 @@ private Set fillTemplateSchema(final ClassTemplate classTemplate, final fillTemplate(filePath.toString(), schemaObject.getClassName(), templateName); for (SchemaFieldObject fieldObject : schemaObject.getFieldObjectList()) { propertiesSet.addAll(fieldObject.getRestrictions().getProperties()); - if (fieldObject.isRequired() && Boolean.FALSE.equals(classTemplate.isUseLombok())) { + if (fieldObject.isRequired() && !classTemplate.isUseLombok()) { propertiesSet.add("NotNull"); } } @@ -214,10 +209,6 @@ public final void fillTemplateModelClassException(final String modelPackage) thr writeTemplateToFile(CommonTemplateIndexConstants.TEMPLATE_MODEL_EXCEPTION, MapperUtil.packageToFolder(modelPackage) + SLASH + "exception", "ModelClassException"); } - public void setNotGenerateTemplate() { - this.generateExceptionTemplate = false; - } - private void fillTemplateCustom( final Path filePathToSave, final String modelPackage, final String fileNameAnnotation, final String templateAnnotation, final String fileNameValidator, final String templateValidator) throws IOException { @@ -230,46 +221,20 @@ private void fillTemplateCustom( writeTemplateToFile(templateValidator, pathToCustomValidatorPackage, fileNameValidator); } - protected void addToRoot(final String key, final Object value) { - root.put(key, value); - } - - protected void delFromRoot(final String key) { - root.remove(key); - } - - protected void addToRoot(final Map propertiesSet) { - root.putAll(propertiesSet); - } - - protected void cleanData() { - clearRoot(); - addToRoot("checkBasicTypes", BASIC_DATA_TYPES); - classTemplateList.clear(); - generateExceptionTemplate = false; + private static String getTemplateName(ClassTemplate classTemplate) { + String templateName; + if (classTemplate.getClassSchema().isEnum()) { + templateName = CommonTemplateIndexConstants.TEMPLATE_CONTENT_ENUM; + } else { + templateName = classTemplate.isUseLombok() ? CommonTemplateIndexConstants.TEMPLATE_CONTENT_SCHEMA_LOMBOK : CommonTemplateIndexConstants.TEMPLATE_CONTENT_SCHEMA; + } + return templateName; } - protected abstract void clearRoot(); - - public final void addSchemaObject(final String modelPackage, - final String keyClassName, - final SchemaObject schemaObject, - final String destinationPackage, - final boolean useLombok) { - final var filePath = processPath(getPath(destinationPackage)); - final var propertiesPath = processPath(getPath(modelPackage)); - final var builder = ClassTemplate - .builder() - .filePath(filePath) - .modelPackage(modelPackage) - .className(schemaObject.getClassName()) - .classSchema(schemaObject) - .propertiesPath(propertiesPath) - .useLombok(useLombok); - if (Objects.nonNull(keyClassName)) { - builder.keyClassName(keyClassName); - } - classTemplateList.add(builder.build()); + protected void fillTemplate(final String filePathToSave, final String className, final String templateName) throws IOException { + final var fileToSave = Paths.get(filePathToSave); + fileToSave.toFile().mkdirs(); + writeTemplateToFile(templateName, fileToSave, className); } protected void writeTemplateToFile(final String templateName, final String apiPackage, final String partialPath) throws IOException { @@ -313,6 +278,53 @@ public Path processPath(final String packagePath) { return path; } + protected String getPath(final String pathName) { + return processedGeneratedSourcesFolder + SLASH + pathName.replace(PACKAGE_SEPARATOR_STR, SLASH); + } + + public void setNotGenerateTemplate() { + this.generateExceptionTemplate = false; + } + + protected void delFromRoot(final String key) { + root.remove(key); + } + + protected void addToRoot(final Map propertiesSet) { + root.putAll(propertiesSet); + } + + protected void cleanData() { + clearRoot(); + addToRoot("checkBasicTypes", BASIC_DATA_TYPES); + classTemplateList.clear(); + generateExceptionTemplate = false; + } + + protected abstract void clearRoot(); + + public final void addSchemaObject( + final String modelPackage, + final String keyClassName, + final SchemaObject schemaObject, + final String destinationPackage, + final boolean useLombok) { + final var filePath = processPath(getPath(destinationPackage)); + final var propertiesPath = processPath(getPath(modelPackage)); + final var builder = ClassTemplate + .builder() + .filePath(filePath) + .modelPackage(modelPackage) + .className(schemaObject.getClassName()) + .classSchema(schemaObject) + .propertiesPath(propertiesPath) + .useLombok(useLombok); + if (Objects.nonNull(keyClassName)) { + builder.keyClassName(keyClassName); + } + classTemplateList.add(builder.build()); + } + protected String convertPackageToTargetPath(final OperationParameterObject operationParameter, final String defaultApiPackage) { String path = null; if (Objects.nonNull(operationParameter)) { @@ -325,10 +337,6 @@ protected String convertPackageToTargetPath(final OperationParameterObject opera return StringUtils.replace(path, "//", SLASH); } - protected String getPath(final String pathName) { - return processedGeneratedSourcesFolder + SLASH + pathName.replace(PACKAGE_SEPARATOR_STR, SLASH); - } - public void checkRequiredOrCombinatorExists(final SchemaObject schema, final boolean useLombok) { if ("anyOf".equals(schema.getSchemaCombinator()) || "oneOf".equals(schema.getSchemaCombinator())) { generateExceptionTemplate = true; diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/template/CommonTemplateLoader.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/template/CommonTemplateLoader.java index c92b96c5..5deb6de9 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/template/CommonTemplateLoader.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/template/CommonTemplateLoader.java @@ -1,8 +1,5 @@ package com.sngular.api.generator.plugin.common.template; -import com.sngular.api.generator.plugin.openapi.template.ClasspathTemplateLoader; -import freemarker.cache.TemplateLoader; - import java.io.IOException; import java.io.InputStream; import java.io.Reader; @@ -11,37 +8,50 @@ import java.util.List; import java.util.Map; +import com.sngular.api.generator.plugin.openapi.template.ClasspathTemplateLoader; +import freemarker.cache.TemplateLoader; public abstract class CommonTemplateLoader implements TemplateLoader { - private final Map templatesMap = new HashMap<>(); - protected static final ClassLoader LOADER = ClasspathTemplateLoader.class.getClassLoader(); protected static final List TEMPLATE_MODEL_FILES = List.of(CommonTemplateIndexConstants.TEMPLATE_CONTENT_SCHEMA, - CommonTemplateIndexConstants.TEMPLATE_CONTENT_ENUM, CommonTemplateIndexConstants.TEMPLATE_CONTENT_SCHEMA_LOMBOK, CommonTemplateIndexConstants.TEMPLATE_MODEL_EXCEPTION); + CommonTemplateIndexConstants.TEMPLATE_CONTENT_ENUM, + CommonTemplateIndexConstants.TEMPLATE_CONTENT_SCHEMA_LOMBOK, + CommonTemplateIndexConstants.TEMPLATE_MODEL_EXCEPTION); protected static final List TEMPLATE_ANNOTATION_FILES = List.of(CommonTemplateIndexConstants.TEMPLATE_NOT_NULL_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_NOT_NULL_VALIDATOR_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_MAX_INTEGER_ANNOTATION, CommonTemplateIndexConstants.TEMPLATE_MAX_INTEGER_VALIDATOR_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_MAX_BIG_DECIMAL_ANNOTATION, CommonTemplateIndexConstants.TEMPLATE_MAX_BIG_DECIMAL_VALIDATOR_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_MAX_DOUBLE_ANNOTATION, CommonTemplateIndexConstants.TEMPLATE_MAX_DOUBLE_VALIDATOR_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_MAX_FLOAT_ANNOTATION, CommonTemplateIndexConstants.TEMPLATE_MAX_FLOAT_VALIDATOR_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_MIN_INTEGER_ANNOTATION, CommonTemplateIndexConstants.TEMPLATE_MIN_INTEGER_VALIDATOR_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_MIN_DOUBLE_ANNOTATION, CommonTemplateIndexConstants.TEMPLATE_MIN_DOUBLE_VALIDATOR_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_MIN_FLOAT_ANNOTATION, CommonTemplateIndexConstants.TEMPLATE_MIN_FLOAT_VALIDATOR_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_MIN_BIG_DECIMAL_ANNOTATION, CommonTemplateIndexConstants.TEMPLATE_MIN_BIG_DECIMAL_VALIDATOR_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_SIZE_ANNOTATION, CommonTemplateIndexConstants.TEMPLATE_SIZE_VALIDATOR_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_PATTERN_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_PATTERN_VALIDATOR_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_MULTIPLEOF_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_MULTIPLEOF_VALIDATOR_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_MAX_ITEMS_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_MAX_ITEMS_VALIDATOR_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_MIN_ITEMS_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_MIN_ITEMS_VALIDATOR_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_UNIQUE_ITEMS_ANNOTATION, - CommonTemplateIndexConstants.TEMPLATE_UNIQUE_ITEMS_VALIDATOR_ANNOTATION); + CommonTemplateIndexConstants.TEMPLATE_NOT_NULL_VALIDATOR_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MAX_INTEGER_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MAX_INTEGER_VALIDATOR_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MAX_BIG_DECIMAL_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MAX_BIG_DECIMAL_VALIDATOR_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MAX_DOUBLE_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MAX_DOUBLE_VALIDATOR_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MAX_FLOAT_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MAX_FLOAT_VALIDATOR_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MIN_INTEGER_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MIN_INTEGER_VALIDATOR_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MIN_DOUBLE_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MIN_DOUBLE_VALIDATOR_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MIN_FLOAT_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MIN_FLOAT_VALIDATOR_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MIN_BIG_DECIMAL_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MIN_BIG_DECIMAL_VALIDATOR_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_SIZE_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_SIZE_VALIDATOR_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_PATTERN_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_PATTERN_VALIDATOR_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MULTIPLEOF_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MULTIPLEOF_VALIDATOR_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MAX_ITEMS_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MAX_ITEMS_VALIDATOR_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MIN_ITEMS_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_MIN_ITEMS_VALIDATOR_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_UNIQUE_ITEMS_ANNOTATION, + CommonTemplateIndexConstants.TEMPLATE_UNIQUE_ITEMS_VALIDATOR_ANNOTATION); + + private final Map templatesMap = new HashMap<>(); protected CommonTemplateLoader() { @@ -55,7 +65,6 @@ protected void init(final Map resourceFiles) { templatesMap.putAll(resourceFiles); } - @Override public final Object findTemplateSource(final String templateName) { return templatesMap.get(templateName); diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ApiTool.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ApiTool.java index 112544d6..11333ecf 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ApiTool.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ApiTool.java @@ -1,5 +1,20 @@ package com.sngular.api.generator.plugin.common.tools; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; @@ -11,14 +26,6 @@ import org.apache.commons.collections4.Transformer; import org.apache.commons.lang3.StringUtils; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.*; -import java.util.Map.Entry; - public final class ApiTool { public static final String FORMAT = "format"; @@ -28,6 +35,7 @@ public final class ApiTool { public static final String ANY_OF = "anyOf"; public static final String ONE_OF = "oneOf"; + public static final String COMPONENTS = "components"; public static final String SCHEMAS = "schemas"; @@ -45,14 +53,14 @@ public final class ApiTool { private ApiTool() { } - public static String getType(final JsonNode schema) { - return hasType(schema) ? StringUtils.defaultIfEmpty(getNodeAsString(schema, "type"), "") : ""; - } - public static Iterator> getProperties(final JsonNode schema) { return getNode(schema, "properties").fields(); } + public static JsonNode getNode(final JsonNode schema, final String nodeName) { + return schema.get(nodeName); + } + public static String getRefValue(final JsonNode schema) { return getNode(schema, "$ref").textValue(); } @@ -65,6 +73,14 @@ public static String getFormat(final JsonNode schema) { return getNodeAsString(schema, FORMAT); } + public static String getNodeAsString(final JsonNode schema, final String nodeName) { + return hasNode(schema, nodeName) ? getNode(schema, nodeName).textValue() : null; + } + + public static boolean hasNode(final JsonNode schema, final String nodeName) { + return Objects.nonNull(schema) && schema.has(nodeName); + } + public static JsonNode getAllOf(final JsonNode schema) { return getNode(schema, ALL_OF); } @@ -77,10 +93,6 @@ public static JsonNode getOneOf(final JsonNode schema) { return getNode(schema, ONE_OF); } - public static JsonNode getNode(final JsonNode schema, final String nodeName) { - return schema.get(nodeName); - } - public static boolean getNodeAsBoolean(final JsonNode schema, final String nodeName) { return hasNode(schema, nodeName) && getNode(schema, nodeName).booleanValue(); } @@ -89,8 +101,22 @@ public static Object getNodeAsObject(final JsonNode schema, final String nodeNam return hasNode(schema, nodeName) ? getNodeAsType(getNode(schema, nodeName)) : null; } - public static String getNodeAsString(final JsonNode schema, final String nodeName) { - return hasNode(schema, nodeName) ? getNode(schema, nodeName).textValue() : null; + private static Object getNodeAsType(final JsonNode node) { + final Object result; + if (node.isBigDecimal()) { + result = BigDecimal.valueOf(node.asDouble()); + } else if (node.isBigInteger()) { + result = BigInteger.valueOf(node.asLong()); + } else if (node.isBoolean()) { + result = node.asBoolean(); + } else if (node.isFloat() || node.isDouble()) { + result = node.asDouble(); + } else if (node.isInt() || node.isNumber()) { + result = node.asInt(); + } else { + result = node.asText(); + } + return result; } public static String getNodeAsString(final JsonNode schema) { @@ -103,7 +129,7 @@ public static Iterator> getFieldIterator(final JsonNode public static Iterator> getFieldIterator(final JsonNode schema, final String nodeName) { return Objects.isNull(schema) || !hasNode(schema, nodeName) ? - IteratorUtils.emptyIterator() : getNode(schema, nodeName).fields(); + IteratorUtils.emptyIterator() : getNode(schema, nodeName).fields(); } public static String getName(final JsonNode node) { @@ -112,8 +138,12 @@ public static String getName(final JsonNode node) { public static List getEnumValues(final JsonNode schema) { return new ArrayList<>(CollectionUtils.collect( - IteratorUtils.toList(schema.get("enum").elements()), - getTextValue())); + IteratorUtils.toList(schema.get("enum").elements()), + getTextValue())); + } + + private static Transformer getTextValue() { + return JsonNode::asText; } public static JsonNode getItems(final JsonNode schema) { @@ -124,18 +154,6 @@ public static Map getComponentSchemas(final JsonNode openApi) return getComponentSchemasByType(openApi, SCHEMAS); } - public static Map getParameterSchemas(final JsonNode openApi) { - return getComponentSchemasByType(openApi, PARAMETERS); - } - - public static Map getResponseSchemas(final JsonNode openApi) { - return getComponentSchemasByType(openApi, RESPONSES); - } - - public static Map getRequestBodySchemas(final JsonNode openApi) { - return getComponentSchemasByType(openApi, REQUEST_BODIES); - } - private static Map getComponentSchemasByType(final JsonNode openApi, final String schemaType) { final var schemasMap = new HashMap(); @@ -144,14 +162,26 @@ private static Map getComponentSchemasByType(final JsonNode op if (hasNode(components, schemaType)) { final var schemas = getNode(components, schemaType); final var schemasIt = schemas.fieldNames(); - schemasIt.forEachRemaining(name -> schemasMap.put(schemaType.toUpperCase() + "/"+ StringCaseUtils.titleToSnakeCase(name), - getNode(schemas, name))); + schemasIt.forEachRemaining(name -> schemasMap.put(schemaType.toUpperCase() + "/" + StringCaseUtils.titleToSnakeCase(name), + getNode(schemas, name))); } } return schemasMap; } + public static Map getParameterSchemas(final JsonNode openApi) { + return getComponentSchemasByType(openApi, PARAMETERS); + } + + public static Map getResponseSchemas(final JsonNode openApi) { + return getComponentSchemasByType(openApi, RESPONSES); + } + + public static Map getRequestBodySchemas(final JsonNode openApi) { + return getComponentSchemasByType(openApi, REQUEST_BODIES); + } + public static Map getComponentSecuritySchemes(final JsonNode openApi) { return getComponentSchemasByType(openApi, "securitySchemes"); } @@ -185,17 +215,16 @@ public static String getNumberType(final JsonNode schema) { return type; } - public static boolean hasItems(final JsonNode schema) { - return hasNode(schema, "items"); + public static boolean hasType(final JsonNode schema) { + return hasNode(schema, "type"); } - public static boolean hasNode(final JsonNode schema, final String nodeName) { - return Objects.nonNull(schema) && schema.has(nodeName); + public static String getType(final JsonNode schema) { + return hasType(schema) ? StringUtils.defaultIfEmpty(getNodeAsString(schema, "type"), "") : ""; } - public static boolean hasField(final JsonNode schema, final String... fieldNameArray) { - final var nodeNamesList = Arrays.asList(fieldNameArray); - return StringUtils.isNotEmpty(IteratorUtils.find(schema.fieldNames(), nodeNamesList::contains)); + public static boolean hasItems(final JsonNode schema) { + return hasNode(schema, "items"); } public static boolean hasRequired(final JsonNode schema) { @@ -206,10 +235,6 @@ public static boolean hasName(JsonNode message) { return hasNode(message, "name"); } - public static boolean hasType(final JsonNode schema) { - return hasNode(schema, "type"); - } - public static boolean hasRef(final JsonNode schema) { return (hasNode(schema, "$ref") || schema.fieldNames().hasNext()) && schema.fieldNames().next().equals("$ref"); } @@ -238,6 +263,11 @@ public static boolean isComposed(final JsonNode schema) { return ApiTool.hasField(schema, ANY_OF, ALL_OF, ONE_OF); } + public static boolean hasField(final JsonNode schema, final String... fieldNameArray) { + final var nodeNamesList = Arrays.asList(fieldNameArray); + return StringUtils.isNotEmpty(IteratorUtils.find(schema.fieldNames(), nodeNamesList::contains)); + } + public static boolean isString(final JsonNode schema) { return hasType(schema) && TypeConstants.STRING.equalsIgnoreCase(getType(schema)); } @@ -299,7 +329,6 @@ public static boolean isBinary(final JsonNode schema) { return isMultipartFile; } - public static List findContentSchemas(final JsonNode schema) { return hasNode(schema, "content") ? schema.findValues("schema") : Collections.emptyList(); } @@ -315,14 +344,6 @@ public static boolean checkIfRequired(final JsonNode schema, final String fieldN return isRequired; } - private static Transformer getTextValue() { - return JsonNode::asText; - } - - public static boolean hasComponents(final JsonNode node) { - return hasNode(node, COMPONENTS); - } - public static Iterator> getComponent(final JsonNode node, final String componentType) { Iterator> result = Collections.emptyIterator(); if (hasComponents(node) && hasNode(getNode(node, "components"), componentType)) { @@ -331,15 +352,25 @@ public static Iterator> getComponent(final JsonNode node return result; } + public static boolean hasComponents(final JsonNode node) { + return hasNode(node, COMPONENTS); + } + public static JsonNode nodeFromFile(final FileLocation ymlParent, final String filePath, final FactoryTypeEnum factoryTypeEnum) throws IOException { final InputStream file; - if (filePath.startsWith(PACKAGE_SEPARATOR_STR) || filePath.matches("^\\w.*$")) { + // Check if path is absolute first + if (PathUtil.isAbsolutePath(filePath)) { + // For absolute paths, open directly + file = new FileInputStream(filePath); + } else if (filePath.startsWith(PACKAGE_SEPARATOR_STR) || filePath.matches("^\\w.*$")) { + // For relative paths starting with . or alphanumeric (package-like paths) file = ymlParent.getFileAtLocation(filePath); } else { if (filePath.contains(".jar!")) { var resource = filePath.substring(filePath.indexOf(".jar!") + 1); file = ApiTool.class.getClassLoader().getResourceAsStream(resource); } else { + // Other paths - try as file path file = new FileInputStream(filePath); } } @@ -354,24 +385,6 @@ public static JsonNode nodeFromFile(final FileLocation ymlParent, final String f return om.readTree(file); } - private static Object getNodeAsType(final JsonNode node) { - final Object result; - if (node.isBigDecimal()) { - result = BigDecimal.valueOf(node.asDouble()); - } else if (node.isBigInteger()) { - result = BigInteger.valueOf(node.asLong()); - } else if (node.isBoolean()) { - result = node.asBoolean(); - } else if (node.isFloat() || node.isDouble()) { - result = node.asDouble(); - } else if (node.isInt() || node.isNumber()) { - result = node.asInt(); - } else { - result = node.asText(); - } - return result; - } - public static boolean hasConst(final JsonNode fieldBody) { return hasNode(fieldBody, "const"); } @@ -404,3 +417,4 @@ private static Object getValue(final JsonNode aConst) { return value; } } + diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/MapperContentUtil.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/MapperContentUtil.java index bf119fcc..76a63b15 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/MapperContentUtil.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/MapperContentUtil.java @@ -13,6 +13,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; + import com.fasterxml.jackson.databind.JsonNode; import com.sngular.api.generator.plugin.common.model.CommonSpecFile; import com.sngular.api.generator.plugin.common.model.SchemaObject; diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/MapperUtil.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/MapperUtil.java index 7906d124..b7734089 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/MapperUtil.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/MapperUtil.java @@ -15,6 +15,8 @@ public class MapperUtil { + public static final String JAVA_TIME = "java.time."; + private static final String REF = "$ref"; private static final String[] DIVISOR = {"/", "-", "_"}; @@ -22,9 +24,9 @@ public class MapperUtil { private static final String SLASH = "/"; private static final String PACKAGE_SEPARATOR_STR = "."; - public static final String JAVA_TIME = "java.time."; - private MapperUtil() {} + private MapperUtil() { + } public static String getSimpleType(final JsonNode schema, final CommonSpecFile specFile) { final String type; @@ -41,22 +43,38 @@ public static String getSimpleType(final JsonNode schema, final CommonSpecFile s return type; } - public static String[] splitName(final String name) { - return ArrayUtils.removeAllOccurrences(name.split("\\W+"), ""); + private static boolean checkIfNumber(final String nodeType) { + return TypeConstants.NUMBER.equalsIgnoreCase(nodeType) || TypeConstants.INTEGER.equalsIgnoreCase(nodeType) + || TypeConstants.INT_32.equalsIgnoreCase(nodeType) || TypeConstants.INT_64.equalsIgnoreCase(nodeType); } - public static String[] splitReference(final String name) { - if (0 < StringUtils.indexOf(name, "#")) { - return StringUtils.split(name, "#"); - } else if (0 == StringUtils.indexOf(name, "#")) { - return StringUtils.split(name, "#"); - } else { - return ArrayUtils.addAll(new String[] {}, name, ""); + private static String processNumber(final JsonNode schema) { + + final var nodeType = schema.get("type").asText(); + final var formatType = schema.has("format") ? schema.get("format").asText() : null; + String type = TypeConstants.INTEGER; + if (TypeConstants.NUMBER.equalsIgnoreCase(nodeType)) { + if (TypeConstants.FLOAT.equalsIgnoreCase(formatType)) { + type = TypeConstants.FLOAT; + } else if (TypeConstants.DOUBLE.equalsIgnoreCase(formatType)) { + type = TypeConstants.DOUBLE; + } else { + type = TypeConstants.BIG_DECIMAL; + } + } else if (TypeConstants.INTEGER.equalsIgnoreCase(nodeType)) { + if (TypeConstants.INT_64.equalsIgnoreCase(formatType)) { + type = TypeConstants.LONG; + } else { + type = TypeConstants.INTEGER; + } } + return type; } - public static String packageToFolder(final String packageName) { - return StringUtils.replace(packageName, ".", SLASH); + public static String getPojoName(final String namePojo, final CommonSpecFile specFile) { + return (StringUtils.isNotBlank(specFile.getModelNamePrefix()) ? specFile.getModelNamePrefix() : "") + + StringUtils.capitalize(namePojo) + + (StringUtils.isNotBlank(specFile.getModelNameSuffix()) ? specFile.getModelNameSuffix() : ""); } public static String getRefSchemaName(final JsonNode parameter, String defaultSchemaName) { @@ -72,6 +90,20 @@ public static String getRefSchemaName(final JsonNode parameter, String defaultSc return schemaName; } + public static String[] splitReference(final String name) { + if (0 < StringUtils.indexOf(name, "#")) { + return StringUtils.split(name, "#"); + } else if (0 == StringUtils.indexOf(name, "#")) { + return StringUtils.split(name, "#"); + } else { + return ArrayUtils.addAll(new String[]{}, name, ""); + } + } + + public static String packageToFolder(final String packageName) { + return StringUtils.replace(packageName, ".", SLASH); + } + public static String getRefSchemaKey(final JsonNode parameter) { final String[] pathObjectRef = ApiTool.getRefValue(parameter).split("/"); return StringUtils.upperCase(pathObjectRef[pathObjectRef.length - 2] + "/" + StringCaseUtils.titleToSnakeCase(pathObjectRef[pathObjectRef.length - 1])); @@ -82,6 +114,10 @@ public static String getRefSchemaKey(final String parameter) { return StringUtils.upperCase(pathObjectRef[pathObjectRef.length - 2] + "/" + getSchemaKey(pathObjectRef[pathObjectRef.length - 1])); } + public static String getSchemaKey(final String schemaName) { + return StringCaseUtils.titleToSnakeCase(schemaName); + } + public static String getKeySchemaName(final String parameter) { return StringCaseUtils.toCamelCase(getKey(parameter)); } @@ -91,38 +127,6 @@ public static String getKey(final String keyString) { return pathObjectRef[pathObjectRef.length - 1]; } - public static String getSchemaKey(final String schemaName) { - return StringCaseUtils.titleToSnakeCase(schemaName); - } - - private static boolean checkIfNumber(final String nodeType) { - return TypeConstants.NUMBER.equalsIgnoreCase(nodeType) || TypeConstants.INTEGER.equalsIgnoreCase(nodeType) - || TypeConstants.INT_32.equalsIgnoreCase(nodeType) || TypeConstants.INT_64.equalsIgnoreCase(nodeType); - } - - private static String processNumber(final JsonNode schema) { - - final var nodeType = schema.get("type").asText(); - final var formatType = schema.has("format") ? schema.get("format").asText() : null; - String type = TypeConstants.INTEGER; - if (TypeConstants.NUMBER.equalsIgnoreCase(nodeType)) { - if (TypeConstants.FLOAT.equalsIgnoreCase(formatType)) { - type = TypeConstants.FLOAT; - } else if (TypeConstants.DOUBLE.equalsIgnoreCase(formatType)) { - type = TypeConstants.DOUBLE; - } else { - type = TypeConstants.BIG_DECIMAL; - } - } else if (TypeConstants.INTEGER.equalsIgnoreCase(nodeType)) { - if (TypeConstants.INT_64.equalsIgnoreCase(formatType)) { - type = TypeConstants.LONG; - } else { - type = TypeConstants.INTEGER; - } - } - return type; - } - public static String getTypeArray(final JsonNode array, final CommonSpecFile specFile) { var typeArray = ""; if (ApiTool.isString(ApiTool.getItems(array))) { @@ -135,15 +139,9 @@ public static String getTypeArray(final JsonNode array, final CommonSpecFile spe return typeArray; } - public static String getPojoName(final String namePojo, final CommonSpecFile specFile) { - return (StringUtils.isNotBlank(specFile.getModelNamePrefix()) ? specFile.getModelNamePrefix() : "") - + StringUtils.capitalize(namePojo) - + (StringUtils.isNotBlank(specFile.getModelNameSuffix()) ? specFile.getModelNameSuffix() : ""); - } - public static String calculatePrefixName(final String namePojo, final CommonSpecFile specFile) { return (StringUtils.isNotBlank(specFile.getModelNamePrefix()) ? specFile.getModelNamePrefix() : "") - + StringUtils.capitalize(namePojo); + + StringUtils.capitalize(namePojo); } public static String getPojoNameFromRef(final JsonNode schema, final CommonSpecFile specFile, String defaultPojoName) { @@ -179,6 +177,10 @@ private static String[] getStrings(final JsonNode schema) { return splitName(schema.get(REF).textValue()); } + public static String[] splitName(final String name) { + return ArrayUtils.removeAllOccurrences(name.split("\\W+"), ""); + } + public static String getLongRefClass(final JsonNode schema) { final String[] pathObjectRef = getStrings(schema); return pathObjectRef[pathObjectRef.length - 2] + "/" + pathObjectRef[pathObjectRef.length - 1]; @@ -186,39 +188,39 @@ public static String getLongRefClass(final JsonNode schema) { public static String getNameFromFile(final String filePath) { return capitalizeFileName(StringUtils - .removeStart(filePath, "./") - .substring(0, filePath.lastIndexOf('.') - 2) - .replace("\\/", ".")); + .removeStart(filePath, "./") + .substring(0, filePath.lastIndexOf('.') - 2) + .replace("\\/", ".")); } - public static String capitalizeWithPrefix(final String name) { + public static String capitalizeFileName(final String name) { final StringBuilder response = new StringBuilder(); if (StringUtils.containsAny(name, DIVISOR)) { final var splitPackage = MapperUtil.splitName(name); - for (int i = 0; i < splitPackage.length; i++) { - response.append(PACKAGE_SEPARATOR_STR).append(i < splitPackage.length - 1 ? splitPackage[i] : StringUtils.capitalize(splitPackage[i])); + for (String s : splitPackage) { + response.append(StringUtils.capitalize(s)); } } else { - response.append(PACKAGE_SEPARATOR_STR).append(StringUtils.capitalize(name)); + response.append(StringUtils.capitalize(name)); } return response.toString(); } - public static String capitalizeFileName(final String name) { + public static String capitalizeWithPrefix(final String name) { final StringBuilder response = new StringBuilder(); if (StringUtils.containsAny(name, DIVISOR)) { final var splitPackage = MapperUtil.splitName(name); - for (String s : splitPackage) { - response.append(StringUtils.capitalize(s)); + for (int i = 0; i < splitPackage.length; i++) { + response.append(PACKAGE_SEPARATOR_STR).append(i < splitPackage.length - 1 ? splitPackage[i] : StringUtils.capitalize(splitPackage[i])); } } else { - response.append(StringUtils.capitalize(name)); + response.append(PACKAGE_SEPARATOR_STR).append(StringUtils.capitalize(name)); } return response.toString(); } public static String getModel(String reference) { - return reference.substring(reference.lastIndexOf("/")+1); + return reference.substring(reference.lastIndexOf("/") + 1); } public static String getPathToModel(String reference) { diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ModelBuilder.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ModelBuilder.java index f7c88565..b1d46b3f 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ModelBuilder.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ModelBuilder.java @@ -6,17 +6,29 @@ package com.sngular.api.generator.plugin.common.tools; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Consumer; + import com.fasterxml.jackson.databind.JsonNode; -import com.sngular.api.generator.plugin.common.model.*; +import com.sngular.api.generator.plugin.common.model.CommonSpecFile; +import com.sngular.api.generator.plugin.common.model.SchemaFieldObject; +import com.sngular.api.generator.plugin.common.model.SchemaFieldObjectType; +import com.sngular.api.generator.plugin.common.model.SchemaObject; +import com.sngular.api.generator.plugin.common.model.TypeConstants; import com.sngular.api.generator.plugin.openapi.exception.BadDefinedEnumException; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.text.WordUtils; -import java.nio.file.Path; -import java.util.*; -import java.util.function.Consumer; - public final class ModelBuilder { private static final String ADDITIONAL_PROPERTY_NAME = "AdditionalProperty"; @@ -35,13 +47,13 @@ private ModelBuilder() { } public static SchemaObject buildSchemaObject( - final Map totalSchemas, final String className, final JsonNode model, - final Set antiLoopList, final Map compositedSchemas, final String parentPackage, - final CommonSpecFile specFile, final Path baseDir) { + final Map totalSchemas, final String className, final JsonNode model, + final Set antiLoopList, final Map compositedSchemas, final String parentPackage, + final CommonSpecFile specFile, final Path baseDir) { antiLoopList.add(WordUtils.capitalizeFully(className)); final var schemaBuilder = SchemaObject.builder() - .schemaName(WordUtils.capitalizeFully(className)); + .schemaName(WordUtils.capitalizeFully(className)); final var calculatedInlinePrefix = MapperUtil.calculatePrefixName("Inline", specFile); if (!StringUtils.startsWith(className, calculatedInlinePrefix)) { schemaBuilder.className(MapperUtil.getPojoName(className, specFile)); @@ -64,13 +76,13 @@ public static SchemaObject buildSchemaObject( schemaBuilder.schemaCombinator(""); } - schemaBuilder - .fieldObjectList(listSchema) - .parentPackage(parentPackage.toLowerCase()); + schemaBuilder + .fieldObjectList(listSchema) + .parentPackage(parentPackage.toLowerCase()); } else { schemaBuilder - .isEnum(true) - .fieldObject(processEnumField(className, model, specFile, ApiTool.getEnumValues(model), model)); + .isEnum(true) + .fieldObject(processEnumField(className, model, specFile, ApiTool.getEnumValues(model), model)); } cachedSchemas.putAll(compositedSchemas); return schemaBuilder.build(); @@ -83,10 +95,10 @@ private static List getImportList(final Set fieldObje for (final var fieldObject : fieldObjectList) { getTypeImports(listHashMap, fieldObject); if (StringUtils.isNotBlank(fieldObject.getImportClass()) - && !listHashMap.containsKey(fieldObject.getImportClass()) - && !fieldObject.getDataType().containsType("enum")) { + && !listHashMap.containsKey(fieldObject.getImportClass()) + && !fieldObject.getDataType().containsType("enum")) { listHashMap.put(StringUtils.capitalize(fieldObject.getImportClass()), - List.of(modelPackage + "." + StringUtils.capitalize(fieldObject.getImportClass()))); + List.of(modelPackage + "." + StringUtils.capitalize(fieldObject.getImportClass()))); } } if (!listHashMap.isEmpty()) { @@ -96,8 +108,8 @@ private static List getImportList(final Set fieldObje } private static void getTypeImports( - final HashMap> listHashMap, - final SchemaFieldObject fieldObject) { + final HashMap> listHashMap, + final SchemaFieldObject fieldObject) { final SchemaFieldObjectType type = fieldObject.getDataType(); if (type.containsType(TypeConstants.ARRAY)) { listHashMap.computeIfAbsent(TypeConstants.ARRAY, key -> List.of("java.util.List", "java.util.ArrayList")); @@ -140,27 +152,29 @@ private static void getTypeImports( } } - private static Set getFields(final String buildingSchema, - final Map totalSchemas, final JsonNode schema, final CommonSpecFile specFile, - final Map compositedSchemas, final Set antiLoopList, final String nameSchema, - final Path baseDir) { + private static Set getFields( + final String buildingSchema, + final Map totalSchemas, final JsonNode schema, final CommonSpecFile specFile, + final Map compositedSchemas, final Set antiLoopList, final String nameSchema, + final Path baseDir) { final Set fieldObjectArrayList = new HashSet<>(); if (ApiTool.hasProperties(schema)) { if (ApiTool.hasAdditionalProperties(schema)) { ApiTool.getProperties(schema).forEachRemaining(processProperties(buildingSchema, totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, schema, antiLoopList, - baseDir)); + baseDir)); fieldObjectArrayList.addAll(processAdditionalProperties(ADDITIONAL_PROPERTIES, schema, specFile, totalSchemas, compositedSchemas, antiLoopList, nameSchema, baseDir)); } else { ApiTool.getProperties(schema).forEachRemaining(processProperties(nameSchema, totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, schema, antiLoopList, - baseDir)); + baseDir)); } } else if (TypeConstants.ARRAY.equalsIgnoreCase(ApiTool.getType(schema))) { - final String itemType = ApiTool.hasRef(ApiTool.getItems(schema)) ? MapperUtil.getPojoNameFromRef(ApiTool.getItems(schema), specFile, null) : ApiTool.getType(ApiTool.getItems(schema)); + final String itemType = ApiTool.hasRef(ApiTool.getItems(schema)) ? MapperUtil.getPojoNameFromRef(ApiTool.getItems(schema), specFile, null) + : ApiTool.getType(ApiTool.getItems(schema)); fieldObjectArrayList.add(SchemaFieldObject.builder() - .baseName("items") - .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.ARRAY, itemType)) - .build()); + .baseName("items") + .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.ARRAY, itemType)) + .build()); } else if (ApiTool.isAllOf(schema)) { fieldObjectArrayList.addAll(processAllOf(totalSchemas, ApiTool.getAllOf(schema), specFile, compositedSchemas, antiLoopList, baseDir)); } else if (ApiTool.isAnyOf(schema)) { @@ -172,23 +186,23 @@ private static Set getFields(final String buildingSchema, } else if (ApiTool.hasRef(schema)) { final var refSchema = totalSchemas.get(MapperUtil.getRefSchemaKey(schema)); ApiTool.getProperties(refSchema).forEachRemaining(processProperties(buildingSchema, totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, refSchema, antiLoopList, - baseDir)); + baseDir)); } else { fieldObjectArrayList.add(SchemaFieldObject.builder() - .baseName(ApiTool.getName(schema)) - .dataType(new SchemaFieldObjectType(MapperUtil.getSimpleType(schema, specFile))) - .build()); + .baseName(ApiTool.getName(schema)) + .dataType(new SchemaFieldObjectType(MapperUtil.getSimpleType(schema, specFile))) + .build()); } return fieldObjectArrayList; } - @SuppressWarnings("checkstyle:CyclomaticComplexity") - private static List processFieldObjectList(final String buildingSchema, - final String fieldName, final String className, final JsonNode schema, final CommonSpecFile specFile, - final Map totalSchemas, final Map compositedSchemas, - final Set antiLoopList, final Path baseDir) { + private static List processFieldObjectList( + final String buildingSchema, + final String fieldName, final String className, final JsonNode schema, final CommonSpecFile specFile, + final Map totalSchemas, final Map compositedSchemas, + final Set antiLoopList, final Path baseDir) { final var fieldObjectArrayList = new ArrayList(); if (TypeConstants.ARRAY.equalsIgnoreCase(ApiTool.getType(schema))) { @@ -197,21 +211,21 @@ private static List processFieldObjectList(final String build fieldObjectArrayList.addAll(processMap(fieldName, schema, specFile, totalSchemas, compositedSchemas, antiLoopList, baseDir)); } else if (ApiTool.hasRef(schema)) { fieldObjectArrayList.add( - processRef(fieldName, schema, new SchemaFieldObjectType(MapperUtil.getSimpleType(schema, specFile)), totalSchemas, compositedSchemas, antiLoopList, specFile, baseDir)); + processRef(fieldName, schema, new SchemaFieldObjectType(MapperUtil.getSimpleType(schema, specFile)), totalSchemas, compositedSchemas, antiLoopList, specFile, baseDir)); } else if (ApiTool.isObject(schema) && !ApiTool.hasProperties(schema)) { fieldObjectArrayList.add(SchemaFieldObject - .builder() - .baseName(fieldName) - .dataType(new SchemaFieldObjectType(TypeConstants.OBJECT)) - .build()); + .builder() + .baseName(fieldName) + .dataType(new SchemaFieldObjectType(TypeConstants.OBJECT)) + .build()); } else if (ApiTool.isEnum(schema)) { fieldObjectArrayList.add(processEnumField(fieldName, schema, specFile, ApiTool.getEnumValues(schema), schema)); } else if (!ApiTool.hasProperties(schema) && !ApiTool.isComposed(schema)) { fieldObjectArrayList.add(SchemaFieldObject - .builder() - .baseName(fieldName) - .dataType(new SchemaFieldObjectType(TypeConstants.OBJECT)) - .build()); + .builder() + .baseName(fieldName) + .dataType(new SchemaFieldObjectType(TypeConstants.OBJECT)) + .build()); } else if (ApiTool.isObject(schema)) { fieldObjectArrayList.addAll(processObject(fieldName, className, schema, specFile, totalSchemas, compositedSchemas, antiLoopList, baseDir)); } else { @@ -219,23 +233,24 @@ private static List processFieldObjectList(final String build var schemaObjectComposed = compositedSchemas.get(composedSchemaName); if (Objects.isNull(schemaObjectComposed)) { schemaObjectComposed = createComposedSchema(buildingSchema, StringUtils.defaultIfBlank(className, fieldName), schema, specFile, - totalSchemas, compositedSchemas, antiLoopList, baseDir); + totalSchemas, compositedSchemas, antiLoopList, baseDir); compositedSchemas.put(composedSchemaName, schemaObjectComposed); } fieldObjectArrayList.add(SchemaFieldObject - .builder() - .baseName(fieldName) - .dataType(SchemaFieldObjectType.fromTypeList(schemaObjectComposed.getClassName(), schemaObjectComposed.getClassName())) - .build()); + .builder() + .baseName(fieldName) + .dataType(SchemaFieldObjectType.fromTypeList(schemaObjectComposed.getClassName(), schemaObjectComposed.getClassName())) + .build()); } return fieldObjectArrayList; } - private static Consumer> processProperties(final String buildingSchema, - final Map totalSchemas, final Map compositedSchemas, final Set fieldObjectArrayList, final CommonSpecFile specFile, - final JsonNode schema, final Set antiLoopList, final Path baseDir) { + private static Consumer> processProperties( + final String buildingSchema, + final Map totalSchemas, final Map compositedSchemas, final Set fieldObjectArrayList, final CommonSpecFile specFile, + final JsonNode schema, final Set antiLoopList, final Path baseDir) { return field -> { final var nodeName = field.getKey(); final var nodeValue = field.getValue(); @@ -248,9 +263,10 @@ private static Consumer> processProperties(final Str } @SuppressWarnings({"checkstyle:CyclomaticComplexity", "checkstyle:ParameterNumber"}) - private static List processObjectProperty(final String buildingSchema, - final Map totalSchemas, final String fieldName, final JsonNode fieldBody, final Map compositedSchemas, final CommonSpecFile specFile, - final JsonNode schema, final Set antiLoopList, final Path baseDir) { + private static List processObjectProperty( + final String buildingSchema, + final Map totalSchemas, final String fieldName, final JsonNode fieldBody, final Map compositedSchemas, final CommonSpecFile specFile, + final JsonNode schema, final Set antiLoopList, final Path baseDir) { final List fieldObjectArrayList = new LinkedList<>(); final var isRequired = ApiTool.checkIfRequired(fieldBody, fieldName); final SchemaFieldObject field; @@ -258,48 +274,48 @@ private static List processObjectProperty(final String buildi final var typeName = MapperUtil.getRefSchemaName(fieldBody, fieldName); final var refSchema = totalSchemas.get(MapperUtil.getRefSchemaKey(fieldBody)); if (!antiLoopList.contains(typeName) && Objects.nonNull(refSchema) && ApiTool.hasType(refSchema) - && ApiTool.hasItems(refSchema) || ApiTool.getRefValue(fieldBody).contains(fieldName)) { + && ApiTool.hasItems(refSchema) || ApiTool.getRefValue(fieldBody).contains(fieldName)) { if (antiLoopList.contains(typeName) && ApiTool.getRefValue(fieldBody).contains(fieldName)) { fieldObjectArrayList.add(SchemaFieldObject - .builder() - .baseName(fieldName) - .required(ApiTool.checkIfRequired(schema, fieldName)) - .dataType(SchemaFieldObjectType.fromTypeList(MapperUtil.getSimpleType(refSchema, specFile), - MapperUtil.getPojoName(typeName, specFile))) - .build()); + .builder() + .baseName(fieldName) + .required(ApiTool.checkIfRequired(schema, fieldName)) + .dataType(SchemaFieldObjectType.fromTypeList(MapperUtil.getSimpleType(refSchema, specFile), + MapperUtil.getPojoName(typeName, specFile))) + .build()); } else { - antiLoopList.add(typeName); - fieldObjectArrayList.addAll(processFieldObjectList(buildingSchema, fieldName, typeName, refSchema, specFile, totalSchemas, compositedSchemas, - antiLoopList, baseDir)); + antiLoopList.add(typeName); + fieldObjectArrayList.addAll(processFieldObjectList(buildingSchema, fieldName, typeName, refSchema, specFile, totalSchemas, compositedSchemas, + antiLoopList, baseDir)); } } else if (ApiTool.isEnum(refSchema)) { fieldObjectArrayList.add(processEnumField(fieldName, refSchema, specFile, ApiTool.getEnumValues(refSchema), schema)); } else if (ApiTool.isObject(refSchema) || ApiTool.isComposed(refSchema)) { - compositedSchemas.put(typeName, buildSchemaObject(totalSchemas, typeName, refSchema, antiLoopList, compositedSchemas, "", specFile, baseDir )); - fieldObjectArrayList.add(SchemaFieldObject - .builder() - .baseName(fieldName) - .required(ApiTool.checkIfRequired(schema, fieldName)) - .dataType(SchemaFieldObjectType.fromTypeList(MapperUtil.getSimpleType(refSchema, specFile), - MapperUtil.getPojoName(typeName, specFile))) - .build()); + compositedSchemas.put(typeName, buildSchemaObject(totalSchemas, typeName, refSchema, antiLoopList, compositedSchemas, "", specFile, baseDir)); + fieldObjectArrayList.add(SchemaFieldObject + .builder() + .baseName(fieldName) + .required(ApiTool.checkIfRequired(schema, fieldName)) + .dataType(SchemaFieldObjectType.fromTypeList(MapperUtil.getSimpleType(refSchema, specFile), + MapperUtil.getPojoName(typeName, specFile))) + .build()); } else if (ApiTool.isBoolean(refSchema) || ApiTool.isString(refSchema) || ApiTool.isNumber(refSchema) || ApiTool.isDateTime(refSchema)) { fieldObjectArrayList.add(SchemaFieldObject - .builder() - .baseName(fieldName) - .required(ApiTool.checkIfRequired(schema, fieldName)) - .dataType(new SchemaFieldObjectType(MapperUtil.getSimpleType(refSchema, specFile))) - .constValue(ApiTool.getConst(refSchema)) - .build()); + .builder() + .baseName(fieldName) + .required(ApiTool.checkIfRequired(schema, fieldName)) + .dataType(new SchemaFieldObjectType(MapperUtil.getSimpleType(refSchema, specFile))) + .constValue(ApiTool.getConst(refSchema)) + .build()); } else if (antiLoopList.contains(typeName) && - cachedSchemas.containsKey(typeName)) { - fieldObjectArrayList.add(SchemaFieldObject - .builder() - .baseName(fieldName) - .required(ApiTool.checkIfRequired(schema, fieldName)) - .dataType(SchemaFieldObjectType.fromTypeList(MapperUtil.getSimpleType(refSchema, specFile), - MapperUtil.getPojoName(typeName, specFile))) - .build()); + cachedSchemas.containsKey(typeName)) { + fieldObjectArrayList.add(SchemaFieldObject + .builder() + .baseName(fieldName) + .required(ApiTool.checkIfRequired(schema, fieldName)) + .dataType(SchemaFieldObjectType.fromTypeList(MapperUtil.getSimpleType(refSchema, specFile), + MapperUtil.getPojoName(typeName, specFile))) + .build()); } } else if (ApiTool.isEnum(fieldBody)) { fieldObjectArrayList.add(processEnumField(fieldName, fieldBody, specFile, ApiTool.getEnumValues(fieldBody), fieldBody)); @@ -309,12 +325,12 @@ private static List processObjectProperty(final String buildi fieldObjectArrayList.add(field); } else if (isBasicType(fieldBody)) { field = SchemaFieldObject - .builder() - .baseName(fieldName) - .required(isRequired || ApiTool.hasConst(fieldBody)) - .dataType(new SchemaFieldObjectType(MapperUtil.getSimpleType(fieldBody, specFile))) - .constValue(ApiTool.getConst(fieldBody)) - .build(); + .builder() + .baseName(fieldName) + .required(isRequired || ApiTool.hasConst(fieldBody)) + .dataType(new SchemaFieldObjectType(MapperUtil.getSimpleType(fieldBody, specFile))) + .constValue(ApiTool.getConst(fieldBody)) + .build(); addPropertiesToFieldObject(field, fieldBody); setFieldType(field, fieldBody, schema, specFile, fieldName); fieldObjectArrayList.add(field); @@ -332,21 +348,19 @@ private static SchemaFieldObject processStringProperty(final String propertyName String resultingType; if (ApiTool.isDateTime(schema)) { resultingType = MapperUtil.getDateType(schema, specFile); - } - else if (ApiTool.isBinary(schema)) { + } else if (ApiTool.isBinary(schema)) { resultingType = TypeConstants.MULTIPART_FILE; - } - else { + } else { resultingType = TypeConstants.STRING; } final SchemaFieldObject field = SchemaFieldObject - .builder() - .baseName(propertyName) - .required(ApiTool.checkIfRequired(schema, propertyName) || ApiTool.hasConst(schema)) - .dataType(new SchemaFieldObjectType(resultingType)) - .constValue(ApiTool.getConst(schema)) - .build(); + .builder() + .baseName(propertyName) + .required(ApiTool.checkIfRequired(schema, propertyName) || ApiTool.hasConst(schema)) + .dataType(new SchemaFieldObjectType(resultingType)) + .constValue(ApiTool.getConst(schema)) + .build(); addPropertiesToFieldObject(field, schema); return field; } @@ -408,51 +422,51 @@ private static void addPropertiesToFieldObject(final SchemaFieldObject fieldObje @SuppressWarnings("checkstyle:ParameterNumber") private static List processArray( - final String fieldName, final String className, final JsonNode schema, final CommonSpecFile specFile, final Map totalSchemas, - final Map compositedSchemas, final Set antiLoopList, final Path baseDir) { + final String fieldName, final String className, final JsonNode schema, final CommonSpecFile specFile, final Map totalSchemas, + final Map compositedSchemas, final Set antiLoopList, final Path baseDir) { final List fieldObjectArrayList = new LinkedList<>(); if (!ApiTool.hasItems(schema)) { fieldObjectArrayList.add(SchemaFieldObject - .builder() - .baseName(fieldName) - .dataType(new SchemaFieldObjectType(TypeConstants.OBJECT)) - .build()); + .builder() + .baseName(fieldName) + .dataType(new SchemaFieldObjectType(TypeConstants.OBJECT)) + .build()); } else { final var items = ApiTool.getItems(schema); if (ApiTool.hasRef(items)) { fieldObjectArrayList.add( - processRef(fieldName, items, SchemaFieldObjectType.fromTypeList(TypeConstants.ARRAY, MapperUtil.getSimpleType(items, specFile)), totalSchemas, compositedSchemas, - antiLoopList, specFile, baseDir)); + processRef(fieldName, items, SchemaFieldObjectType.fromTypeList(TypeConstants.ARRAY, MapperUtil.getSimpleType(items, specFile)), totalSchemas, compositedSchemas, + antiLoopList, specFile, baseDir)); } else if (ApiTool.isComposed(items)) { final String composedSchemaName = StringUtils.defaultIfBlank(className, fieldName); SchemaObject schemaObjectComposed = compositedSchemas.get(composedSchemaName); if (Objects.isNull(schemaObjectComposed)) { schemaObjectComposed = createComposedSchema("", StringUtils.defaultIfBlank(className, fieldName), items, specFile, - totalSchemas, compositedSchemas, antiLoopList, baseDir); + totalSchemas, compositedSchemas, antiLoopList, baseDir); compositedSchemas.put(composedSchemaName, schemaObjectComposed); } fieldObjectArrayList.add(SchemaFieldObject - .builder() - .baseName(fieldName) - .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.ARRAY, schemaObjectComposed.getClassName())) - .importClass(schemaObjectComposed.getClassName()) - .build()); + .builder() + .baseName(fieldName) + .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.ARRAY, schemaObjectComposed.getClassName())) + .importClass(schemaObjectComposed.getClassName()) + .build()); } else if (ApiTool.hasProperties(items)) { final var itemsObject = buildSchemaObject(totalSchemas, className, items, antiLoopList, compositedSchemas, "", specFile, baseDir); compositedSchemas.put(className, itemsObject); fieldObjectArrayList.add(SchemaFieldObject - .builder() - .baseName(fieldName) - .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.ARRAY, MapperUtil.getPojoName(fieldName, specFile))) - .build()); + .builder() + .baseName(fieldName) + .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.ARRAY, MapperUtil.getPojoName(fieldName, specFile))) + .build()); } else { final SchemaFieldObject field = SchemaFieldObject - .builder() - .baseName(fieldName) - .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.ARRAY, MapperUtil.getSimpleType(items, specFile))) - .build(); + .builder() + .baseName(fieldName) + .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.ARRAY, MapperUtil.getSimpleType(items, specFile))) + .build(); fieldObjectArrayList.add(field); addPropertiesToFieldObject(field, schema); } @@ -463,109 +477,109 @@ private static List processArray( @SuppressWarnings("checkstyle:ParameterNumber") private static Set processObject( - final String fieldName, final String className, final JsonNode schema, final CommonSpecFile specFile, - final Map totalSchemas, final Map compositedSchemas, - final Set antiLoopList, final Path baseDir) { + final String fieldName, final String className, final JsonNode schema, final CommonSpecFile specFile, + final Map totalSchemas, final Map compositedSchemas, + final Set antiLoopList, final Path baseDir) { final Set fieldObjectArrayList = new HashSet<>(); if (ObjectUtils.allNull(className, fieldName)) { ApiTool.getProperties(schema).forEachRemaining( - processProperties("", totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, schema, antiLoopList, baseDir)); + processProperties("", totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, schema, antiLoopList, baseDir)); } else if (antiLoopList.contains(className) && compositedSchemas.containsKey(className)) { fieldObjectArrayList - .add(SchemaFieldObject - .builder() - .baseName(className) - .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.OBJECT, MapperUtil.getPojoName(className, specFile))) - .build()); + .add(SchemaFieldObject + .builder() + .baseName(className) + .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.OBJECT, MapperUtil.getPojoName(className, specFile))) + .build()); } else if (antiLoopList.contains(fieldName) && compositedSchemas.containsKey(className)) { fieldObjectArrayList - .add(SchemaFieldObject - .builder() - .baseName(fieldName) - .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.OBJECT, MapperUtil.getPojoName(fieldName, specFile))) - .build()); + .add(SchemaFieldObject + .builder() + .baseName(fieldName) + .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.OBJECT, MapperUtil.getPojoName(fieldName, specFile))) + .build()); } else { final String name = StringUtils.defaultIfBlank(className, fieldName); final var itemsObject = buildSchemaObject(totalSchemas, className, schema, antiLoopList, compositedSchemas, "", specFile, baseDir); compositedSchemas.put(className, itemsObject); fieldObjectArrayList - .add(SchemaFieldObject - .builder() - .baseName(name) - .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.OBJECT, MapperUtil.getPojoName(name, specFile))) - .build()); + .add(SchemaFieldObject + .builder() + .baseName(name) + .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.OBJECT, MapperUtil.getPojoName(name, specFile))) + .build()); } return fieldObjectArrayList; } private static Set processMap( - final String fieldName, final JsonNode schema, final CommonSpecFile specFile, final Map totalSchemas, - final Map compositedSchemas, final Set antiLoopList, final Path baseDir) { + final String fieldName, final JsonNode schema, final CommonSpecFile specFile, final Map totalSchemas, + final Map compositedSchemas, final Set antiLoopList, final Path baseDir) { final Set fieldObjectArrayList = new HashSet<>(); if (TypeConstants.OBJECT.equalsIgnoreCase(ApiTool.getType(schema)) && ApiTool.hasProperties(schema)) { ApiTool.getProperties(schema).forEachRemaining( - processProperties("", totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, schema, antiLoopList, baseDir)); + processProperties("", totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, schema, antiLoopList, baseDir)); } if (ApiTool.hasAdditionalProperties(schema)) { fieldObjectArrayList.addAll(processAdditionalProperties(fieldName, schema, specFile, totalSchemas, compositedSchemas, - antiLoopList, ADDITIONAL_PROPERTIES, baseDir)); + antiLoopList, ADDITIONAL_PROPERTIES, baseDir)); } return fieldObjectArrayList; } private static List processAdditionalProperties( - final String fieldName, final JsonNode schema, final CommonSpecFile specFile, final Map totalSchemas, - final Map compositedSchemas, final Set antiLoopList, final String nameSchema, - final Path baseDir) { + final String fieldName, final JsonNode schema, final CommonSpecFile specFile, final Map totalSchemas, + final Map compositedSchemas, final Set antiLoopList, final String nameSchema, + final Path baseDir) { final var fieldObjectArrayList = new ArrayList(); final var addPropObj = ApiTool.getAdditionalProperties(schema); if (TypeConstants.isBoolean(addPropObj.asText())) { fieldObjectArrayList - .add(SchemaFieldObject - .builder() - .baseName(fieldName) - .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.MAP, TypeConstants.OBJECT)) - .build()); + .add(SchemaFieldObject + .builder() + .baseName(fieldName) + .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.MAP, TypeConstants.OBJECT)) + .build()); } else if (ApiTool.hasRef(addPropObj)) { final String refSchemaName = MapperUtil.getPojoNameFromRef(addPropObj, specFile, null); fieldObjectArrayList.add(processRef(fieldName, addPropObj, - SchemaFieldObjectType.fromTypeList(TypeConstants.MAP, refSchemaName), totalSchemas, compositedSchemas, - antiLoopList, specFile, baseDir)); + SchemaFieldObjectType.fromTypeList(TypeConstants.MAP, refSchemaName), totalSchemas, compositedSchemas, + antiLoopList, specFile, baseDir)); } else if (ApiTool.hasItems(addPropObj)) { fieldObjectArrayList - .add(SchemaFieldObject - .builder() - .baseName(fieldName) - .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.MAP, TypeConstants.ARRAY, - MapperUtil.getSimpleType(ApiTool.getItems(addPropObj), specFile))) - .build()); + .add(SchemaFieldObject + .builder() + .baseName(fieldName) + .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.MAP, TypeConstants.ARRAY, + MapperUtil.getSimpleType(ApiTool.getItems(addPropObj), specFile))) + .build()); } else if (ApiTool.isObject(addPropObj)) { final String className = nameSchema + "Value"; final var itemsObject = buildSchemaObject(totalSchemas, className, addPropObj, antiLoopList, compositedSchemas, "", specFile, baseDir); compositedSchemas.put(className, itemsObject); fieldObjectArrayList - .add(SchemaFieldObject - .builder() - .baseName(ADDITIONAL_PROPERTIES) - .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.MAP, MapperUtil.getPojoName(className, specFile))) - .build()); + .add(SchemaFieldObject + .builder() + .baseName(ADDITIONAL_PROPERTIES) + .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.MAP, MapperUtil.getPojoName(className, specFile))) + .build()); } else { final String type = isBasicType(addPropObj) ? MapperUtil.getSimpleType(addPropObj, specFile) - : MapperUtil.getPojoName(ApiTool.getName(schema) + ADDITIONAL_PROPERTY_NAME, specFile); + : MapperUtil.getPojoName(ApiTool.getName(schema) + ADDITIONAL_PROPERTY_NAME, specFile); fieldObjectArrayList - .add(SchemaFieldObject - .builder() - .baseName(fieldName) - .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.MAP, type)) - .constValue(getConst(addPropObj)) - .required(ApiTool.checkIfRequired(schema, fieldName) ||ApiTool.hasConst(addPropObj)) - .build()); + .add(SchemaFieldObject + .builder() + .baseName(fieldName) + .dataType(SchemaFieldObjectType.fromTypeList(TypeConstants.MAP, type)) + .constValue(getConst(addPropObj)) + .required(ApiTool.checkIfRequired(schema, fieldName) || ApiTool.hasConst(addPropObj)) + .build()); } return fieldObjectArrayList; @@ -573,40 +587,41 @@ private static List processAdditionalProperties( private static boolean isBasicType(final JsonNode value) { return !(ApiTool.isObject(value) || ApiTool.isArray(value) || ApiTool.isComposed(value) - || ApiTool.hasAdditionalProperties(value)); + || ApiTool.hasAdditionalProperties(value)); } - private static SchemaObject createComposedSchema(final String buildingSchema, - final String fieldName, final JsonNode schema, final CommonSpecFile specFile, final Map totalSchemas, - final Map compositedSchemas, final Set antiLoopList, final Path baseDir) { + private static SchemaObject createComposedSchema( + final String buildingSchema, + final String fieldName, final JsonNode schema, final CommonSpecFile specFile, final Map totalSchemas, + final Map compositedSchemas, final Set antiLoopList, final Path baseDir) { final Set fieldObjectArrayList = new HashSet<>(); String schemaCombinatorType = ""; if (ApiTool.isAllOf(schema)) { fieldObjectArrayList.addAll( - processAllOf(totalSchemas, ApiTool.getAllOf(schema), specFile, compositedSchemas, antiLoopList, baseDir)); + processAllOf(totalSchemas, ApiTool.getAllOf(schema), specFile, compositedSchemas, antiLoopList, baseDir)); schemaCombinatorType = ALL_OF_COMBINATOR; } else if (ApiTool.isAnyOf(schema)) { fieldObjectArrayList.addAll( - processAnyOfOneOf(fieldName, totalSchemas, ApiTool.getAnyOf(schema), specFile, compositedSchemas, antiLoopList, baseDir)); + processAnyOfOneOf(fieldName, totalSchemas, ApiTool.getAnyOf(schema), specFile, compositedSchemas, antiLoopList, baseDir)); schemaCombinatorType = ANY_OF_COMBINATOR; } else if (ApiTool.isOneOf(schema)) { fieldObjectArrayList.addAll( - processAnyOfOneOf(buildingSchema, totalSchemas, ApiTool.getOneOf(schema), specFile, compositedSchemas, antiLoopList, baseDir)); + processAnyOfOneOf(buildingSchema, totalSchemas, ApiTool.getOneOf(schema), specFile, compositedSchemas, antiLoopList, baseDir)); schemaCombinatorType = ONE_OF_COMBINATOR; } return SchemaObject.builder() - .schemaName(fieldName) - .className(MapperUtil.getPojoName(fieldName, specFile)) - .importList(getImportList(fieldObjectArrayList, specFile.getModelPackage())) - .schemaCombinator(schemaCombinatorType) - .fieldObjectList(fieldObjectArrayList) - .build(); + .schemaName(fieldName) + .className(MapperUtil.getPojoName(fieldName, specFile)) + .importList(getImportList(fieldObjectArrayList, specFile.getModelPackage())) + .schemaCombinator(schemaCombinatorType) + .fieldObjectList(fieldObjectArrayList) + .build(); } private static void setFieldType( - final SchemaFieldObject field, final JsonNode schemaProperty, final JsonNode schema, - final CommonSpecFile specFile, final String key) { + final SchemaFieldObject field, final JsonNode schemaProperty, final JsonNode schema, + final CommonSpecFile specFile, final String key) { field.setRequired(ApiTool.hasRequired(schema) && ApiTool.checkIfRequired(schema, key)); if (ApiTool.isArray(schemaProperty)) { final String typeArray; @@ -642,10 +657,10 @@ private static String getMapTypeObject(final JsonNode schema, final CommonSpecFi type = MapperUtil.getPojoNameFromRef(additionalProperties, specFile, null); } else if (ApiTool.isObject(schema)) { final var additionalPropertiesField = SchemaFieldObject - .builder() - .baseName(ApiTool.getName(additionalProperties)) - .dataType(new SchemaFieldObjectType(MapperUtil.getSimpleType(additionalProperties, specFile))) - .build(); + .builder() + .baseName(ApiTool.getName(additionalProperties)) + .dataType(new SchemaFieldObjectType(MapperUtil.getSimpleType(additionalProperties, specFile))) + .build(); setFieldType(additionalPropertiesField, additionalProperties, additionalProperties, specFile, ""); type = getMapFieldType(additionalPropertiesField); } else { @@ -667,8 +682,8 @@ private static String getMapFieldType(final SchemaFieldObject schemaFieldObject) } private static Set processAllOf( - final Map totalSchemas, final JsonNode schemaList, final CommonSpecFile specFile, - final Map compositedSchemas, final Set antiLoopList, final Path baseDir) { + final Map totalSchemas, final JsonNode schemaList, final CommonSpecFile specFile, + final Map compositedSchemas, final Set antiLoopList, final Path baseDir) { final Set fieldObjectArrayList = new HashSet<>(); for (JsonNode ref : schemaList) { @@ -683,9 +698,10 @@ private static Set processAllOf( return fieldObjectArrayList; } - private static Set processAnyOfOneOf(final String buildingSchema, - final Map totalSchemas, final JsonNode schemaList, final CommonSpecFile specFile, - final Map compositedSchemas, final Set antiLoopList, final Path baseDir) { + private static Set processAnyOfOneOf( + final String buildingSchema, + final Map totalSchemas, final JsonNode schemaList, final CommonSpecFile specFile, + final Map compositedSchemas, final Set antiLoopList, final Path baseDir) { final Set fieldObjectArrayList = new HashSet<>(); for (JsonNode internalSchema : schemaList) { @@ -704,9 +720,9 @@ private static Set processAnyOfOneOf(final String buildingSch fieldObjectArrayList.addAll(compositedSchemas.get(schemaName).getFieldObjectList()); } else if (!schemaName.equalsIgnoreCase(buildingSchema)) { fieldObjectArrayList.add(SchemaFieldObject.builder() - .baseName(schemaName) - .dataType(new SchemaFieldObjectType(MapperUtil.getSimpleType(internalSchema, specFile))) - .build()); + .baseName(schemaName) + .dataType(new SchemaFieldObjectType(MapperUtil.getSimpleType(internalSchema, specFile))) + .build()); } } else { fieldObjectArrayList.addAll(getFields(buildingSchema, totalSchemas, internalSchema, specFile, compositedSchemas, antiLoopList, ApiTool.getName(internalSchema), baseDir)); @@ -721,13 +737,13 @@ private static Set processAnyOfOneOf(final String buildingSch } private static SchemaFieldObject processRef( - final String fieldName, final JsonNode schema, final SchemaFieldObjectType dataType, - final Map totalSchemas, final Map compositedSchemas, - final Set antiLoopList, final CommonSpecFile specFile, final Path baseDir) { + final String fieldName, final JsonNode schema, final SchemaFieldObjectType dataType, + final Map totalSchemas, final Map compositedSchemas, + final Set antiLoopList, final CommonSpecFile specFile, final Path baseDir) { final var field = SchemaFieldObject.builder() - .baseName(fieldName) - .dataType(dataType) - .build(); + .baseName(fieldName) + .dataType(dataType) + .build(); if (!antiLoopList.contains(MapperUtil.getRefSchemaName(schema, fieldName))) { antiLoopList.add(MapperUtil.getRefSchemaName(schema, fieldName)); final String refSchemaName = MapperUtil.getPojoNameFromRef(schema, specFile, fieldName); @@ -739,14 +755,14 @@ private static SchemaFieldObject processRef( } private static SchemaObject solveRef( - final JsonNode schema, final Map totalSchemas, - final Map compositedSchemas, final Set antiLoopList, final CommonSpecFile specFile, - final Path baseDir) { + final JsonNode schema, final Map totalSchemas, + final Map compositedSchemas, final Set antiLoopList, final CommonSpecFile specFile, + final Path baseDir) { final var referredSchema = SchemaUtil.solveRef(ApiTool.getRefValue(schema), totalSchemas, baseDir.resolve(specFile.getFilePath()).getParent().toUri()); final var schemaObject = buildSchemaObject(totalSchemas, MapperUtil.getRefSchemaName(schema, null), referredSchema, - antiLoopList, compositedSchemas, MapperUtil.getRefSchemaName(schema, null), specFile, baseDir); + antiLoopList, compositedSchemas, MapperUtil.getRefSchemaName(schema, null), specFile, baseDir); schemaObject.setEnum(ApiTool.isEnum(referredSchema)); compositedSchemas.put(MapperUtil.getRefSchemaName(schema, null), schemaObject); @@ -754,13 +770,13 @@ private static SchemaObject solveRef( } private static SchemaFieldObject processEnumField( - final String name, final JsonNode value, - final CommonSpecFile specFile, final List enumValues, final JsonNode schema) { + final String name, final JsonNode value, + final CommonSpecFile specFile, final List enumValues, final JsonNode schema) { final var field = SchemaFieldObject - .builder() - .baseName(name) - .dataType(new SchemaFieldObjectType(TypeConstants.ENUM)) - .build(); + .builder() + .baseName(name) + .dataType(new SchemaFieldObjectType(TypeConstants.ENUM)) + .build(); field.setRequired(ApiTool.checkIfRequired(schema, name)); final var dataType = MapperUtil.getSimpleType(value, specFile); field.getDataType().setDeepType(dataType); @@ -790,7 +806,7 @@ private static SchemaFieldObject processEnumField( case TypeConstants.STRING: default: enumValuesMap.put(StringUtils.replace(StringUtils.upperCase(valueName), " ", "_"), - '"' + enumValue + '"'); + '"' + enumValue + '"'); break; } } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/PathUtil.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/PathUtil.java new file mode 100644 index 00000000..18d36b7c --- /dev/null +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/PathUtil.java @@ -0,0 +1,40 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * * License, v. 2.0. If a copy of the MPL was not distributed with this + * * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +package com.sngular.api.generator.plugin.common.tools; + +import java.nio.file.InvalidPathException; +import java.nio.file.Paths; + +import org.apache.commons.lang3.StringUtils; + +/** + * Utility class for path operations. + */ +public final class PathUtil { + + private PathUtil() { + // Utility class + } + + /** + * Checks if a file path is absolute. An absolute path is platform-dependent: - On Windows: C:\path, D:\path, \\server\share (UNC) - On Unix/Linux: /path + * + * @param filePath the file path to check + * @return true if the path is absolute, false if relative or invalid + */ + public static boolean isAbsolutePath(final String filePath) { + if (StringUtils.isEmpty(filePath)) { + return false; + } + try { + return Paths.get(filePath).isAbsolute(); + } catch (final InvalidPathException e) { + // If the path is invalid, treat it as not absolute + return false; + } + } +} diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/SchemaUtil.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/SchemaUtil.java index d685e99f..4bc7d6c5 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/SchemaUtil.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/SchemaUtil.java @@ -1,20 +1,21 @@ package com.sngular.api.generator.plugin.common.tools; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; -import com.sngular.api.generator.plugin.openapi.exception.FileParseException; -import org.apache.commons.lang3.StringUtils; - import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; +import java.nio.file.Paths; import java.util.Map; import java.util.Objects; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.sngular.api.generator.plugin.openapi.exception.FileParseException; +import org.apache.commons.lang3.StringUtils; + public class SchemaUtil { static final ObjectMapper PARSER = new ObjectMapper(new YAMLFactory()); @@ -50,23 +51,28 @@ public static JsonNode getPojoFromRef(final URI rootFilePath, final String refPa } catch (final IOException e) { throw new FileParseException(refPath, e); } - if (Objects.isNull(schemaFile)) { throw new FileParseException("empty .yml"); } - return schemaFile; } - private static String readFile(final URI rootFilePath, final String filePath) throws MalformedURLException { if (Objects.isNull(filePath)) { throw new IllegalArgumentException("File Path cannot be empty"); } + // First, try to find the file in the classpath URL fileURL = SchemaUtil.class.getClassLoader().getResource(filePath); if (Objects.isNull(fileURL)) { - final var parentFolder = rootFilePath.resolve(cleanUpPath(filePath)); - fileURL = parentFolder.toURL(); + // Check if the path is absolute + if (PathUtil.isAbsolutePath(filePath)) { + // For absolute paths, convert directly to URL without resolving against rootFilePath + fileURL = Paths.get(filePath).toUri().toURL(); + } else { + // For relative paths, resolve against the root file path + final var parentFolder = rootFilePath.resolve(cleanUpPath(filePath)); + fileURL = parentFolder.toURL(); + } } final var sb = new StringBuilder(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(fileURL.openStream()))) { @@ -83,5 +89,4 @@ private static String readFile(final URI rootFilePath, final String filePath) th private static String cleanUpPath(final String filePath) { return StringUtils.startsWith(filePath, "./") ? filePath.substring(2) : filePath; } - } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/StringCaseUtils.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/StringCaseUtils.java index 8107da85..b6d10e14 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/StringCaseUtils.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/StringCaseUtils.java @@ -4,26 +4,26 @@ public class StringCaseUtils { - public static String titleToSnakeCase(String titleCase) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < titleCase.length(); i++) { - char c = titleCase.charAt(i); - if (Character.isUpperCase(c)) { - if (i > 0) { - sb.append("_"); - } - sb.append(c); - } else { - sb.append(Character.toUpperCase(c)); - } - } - return sb.toString(); - } + private StringCaseUtils() { + } - public static String toCamelCase(final String toCamelCase) { - return CaseUtils.toCamelCase(toCamelCase, true, '_'); + public static String titleToSnakeCase(String titleCase) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < titleCase.length(); i++) { + char c = titleCase.charAt(i); + if (Character.isUpperCase(c)) { + if (i > 0) { + sb.append("_"); + } + sb.append(c); + } else { + sb.append(Character.toUpperCase(c)); + } } + return sb.toString(); + } - private StringCaseUtils() { - } + public static String toCamelCase(final String toCamelCase) { + return CaseUtils.toCamelCase(toCamelCase, true, '_'); + } } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/OpenApiGenerator.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/OpenApiGenerator.java index 8f6831a5..9177c273 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/OpenApiGenerator.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/OpenApiGenerator.java @@ -6,6 +6,16 @@ package com.sngular.api.generator.plugin.openapi; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + import com.fasterxml.jackson.databind.JsonNode; import com.sngular.api.generator.plugin.PluginConstants; import com.sngular.api.generator.plugin.common.model.SchemaObject; @@ -26,11 +36,6 @@ import org.apache.commons.collections4.MultiValuedMap; import org.apache.commons.lang3.StringUtils; -import java.io.File; -import java.io.IOException; -import java.nio.file.Path; -import java.util.*; - public class OpenApiGenerator { private static final String SLASH = "/"; @@ -51,14 +56,14 @@ public class OpenApiGenerator { private final Path baseDir; - private Boolean isWebClient = false; - - private Boolean isRestClient = false; - private final List authentications = new ArrayList<>(); private final Integer springBootVersion; + private Boolean isWebClient = false; + + private Boolean isRestClient = false; + public OpenApiGenerator( final Integer springBootVersion, final Boolean overwriteModel, @@ -75,10 +80,18 @@ public OpenApiGenerator( public final void processFileSpec(final List specsListFile) { for (SpecFile specFile : specsListFile) { - processPackage(specFile.getApiPackage()); - processFile(specFile); - createClients(specFile); - templateFactory.clearData(); + processPackage(specFile.getApiPackage()); + processFile(specFile); + createClients(specFile); + templateFactory.clearData(); + } + } + + private void processPackage(final String apiPackage) { + if (StringUtils.isNotBlank(apiPackage)) { + templateFactory.setPackageName(apiPackage.trim()); + } else { + templateFactory.setPackageName(Objects.requireNonNullElse(groupId, DEFAULT_OPENAPI_API_PACKAGE)); } } @@ -120,20 +133,6 @@ private void createClients(final SpecFile specFile) { } } - private void createAuthTemplates(final SpecFile specFile) throws IOException { - final String clientPackage = specFile.getClientPackage(); - final var authFileRoot = (StringUtils.isNotBlank(clientPackage) ? clientPackage : DEFAULT_OPENAPI_CLIENT_PACKAGE) + ".auth"; - - templateFactory.setAuthPackageName(authFileRoot); - templateFactory.fillTemplateAuth(authFileRoot, "Authentication"); - - if (!authentications.isEmpty()) { - for (String authentication : authentications) { - templateFactory.fillTemplateAuth(authFileRoot, authentication); - } - } - } - private GlobalObject createApiTemplate(final SpecFile specFile, final JsonNode openAPI) { final MultiValuedMap> apis = OpenApiUtil.mapApiGroups(openAPI, specFile.isUseTagsGroup()); final var authSchemaList = MapperAuthUtil.createAuthSchemaList(openAPI); @@ -150,7 +149,7 @@ private GlobalObject createApiTemplate(final SpecFile specFile, final JsonNode o throw new GeneratorTemplateException("Error filling the template", specFile.getFilePath(), e); } - if (Boolean.TRUE.equals(specFile.isCallMode())) { + if (specFile.isCallMode()) { addAuthentications(authObject); } } @@ -158,17 +157,6 @@ private GlobalObject createApiTemplate(final SpecFile specFile, final JsonNode o return globalObject; } - private void addAuthentications(final AuthObject authObject) { - - if (null != authObject.getSecurityRequirements() && !authObject.getSecurityRequirements().isEmpty()) { - authObject.getSecurityRequirements().forEach(authType -> { - if (!authentications.contains(authType)) { - authentications.add(authType); - } - }); - } - } - private void createModelTemplate(final SpecFile specFile, final JsonNode openAPI, final GlobalObject globalObject) { final var modelPackage = processModelPackage(specFile.getModelPackage()); @@ -177,11 +165,28 @@ private void createModelTemplate(final SpecFile specFile, final JsonNode openAPI processModels(specFile, modelPackage, totalSchemas, overwriteModel); } - private void processPackage(final String apiPackage) { - if (StringUtils.isNotBlank(apiPackage)) { - templateFactory.setPackageName(apiPackage.trim()); - } else { - templateFactory.setPackageName(Objects.requireNonNullElse(groupId, DEFAULT_OPENAPI_API_PACKAGE)); + private void createAuthTemplates(final SpecFile specFile) throws IOException { + final String clientPackage = specFile.getClientPackage(); + final var authFileRoot = (StringUtils.isNotBlank(clientPackage) ? clientPackage : DEFAULT_OPENAPI_CLIENT_PACKAGE) + ".auth"; + + templateFactory.setAuthPackageName(authFileRoot); + templateFactory.fillTemplateAuth(authFileRoot, "Authentication"); + + if (!authentications.isEmpty()) { + for (String authentication : authentications) { + templateFactory.fillTemplateAuth(authFileRoot, authentication); + } + } + } + + private void addAuthentications(final AuthObject authObject) { + + if (null != authObject.getSecurityRequirements() && !authObject.getSecurityRequirements().isEmpty()) { + authObject.getSecurityRequirements().forEach(authType -> { + if (!authentications.contains(authType)) { + authentications.add(authType); + } + }); } } @@ -211,14 +216,6 @@ private void processModels( }); } - private String chooseRightName(final String schemaName) { - String rightName = schemaName; - if (!StringUtils.startsWith(schemaName, "Inline")) { - rightName = MapperUtil.getKeySchemaName(schemaName); - } - return rightName; - } - private boolean validType(final String type) { return !TypeConstants.NO_PROCESS_TYPE.contains(type); } @@ -238,12 +235,20 @@ private void processModel( } } + private String chooseRightName(final String schemaName) { + String rightName = schemaName; + if (!StringUtils.startsWith(schemaName, "Inline")) { + rightName = MapperUtil.getKeySchemaName(schemaName); + } + return rightName; + } + private void writeSchemaObject( final SpecFile specFile, final String schemaName, final JsonNode model, final Map basicSchemaMap, final String modelPackage) { final String parentPackage = modelPackage.substring(modelPackage.lastIndexOf(".") + 1); final var schemaObjectIt = MapperContentUtil - .mapComponentToSchemaObject(basicSchemaMap, schemaName, model, parentPackage, specFile, this.baseDir).iterator(); + .mapComponentToSchemaObject(basicSchemaMap, schemaName, model, parentPackage, specFile, this.baseDir).iterator(); if (schemaObjectIt.hasNext()) { writeSchemaObject(specFile.isUseLombokModelAnnotation(), specFile.getModelPackage(), schemaName, schemaObjectIt.next()); } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/AuthObject.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/AuthObject.java index c479c801..a63b14b2 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/AuthObject.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/AuthObject.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.List; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/GlobalObject.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/GlobalObject.java index 8d12752a..a5109e00 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/GlobalObject.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/GlobalObject.java @@ -11,6 +11,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; + import com.fasterxml.jackson.databind.JsonNode; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/OperationObject.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/OperationObject.java index 61158a40..9f20fb70 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/OperationObject.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/OperationObject.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.List; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/PathObject.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/PathObject.java index 6240c11e..a1921fc1 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/PathObject.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/PathObject.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.List; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/RequestObject.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/RequestObject.java index f635a035..98e8a6d3 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/RequestObject.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/RequestObject.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.List; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/ResponseObject.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/ResponseObject.java index 92b75b5d..156f8277 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/ResponseObject.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/ResponseObject.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.List; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/template/ClasspathTemplateLoader.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/template/ClasspathTemplateLoader.java index ab977b65..4a03255a 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/template/ClasspathTemplateLoader.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/template/ClasspathTemplateLoader.java @@ -6,9 +6,6 @@ package com.sngular.api.generator.plugin.openapi.template; -import com.sngular.api.generator.plugin.common.template.CommonTemplateLoader; -import com.sngular.api.generator.plugin.exception.GeneratorTemplateException; - import java.io.IOException; import java.io.InputStream; import java.util.HashMap; @@ -16,6 +13,9 @@ import java.util.Map; import java.util.Objects; +import com.sngular.api.generator.plugin.common.template.CommonTemplateLoader; +import com.sngular.api.generator.plugin.exception.GeneratorTemplateException; + public class ClasspathTemplateLoader extends CommonTemplateLoader { private static final List TEMPLATE_FILES = List.of(TemplateIndexConstants.TEMPLATE_INTERFACE_API, TemplateIndexConstants.TEMPLATE_CALL_WEB_API, @@ -25,6 +25,7 @@ public class ClasspathTemplateLoader extends CommonTemplateLoader { private static final List TEMPLATE_AUTH_FILES = List.of(TemplateIndexConstants.TEMPLATE_API_KEY, TemplateIndexConstants.TEMPLATE_AUTHENTICATION, TemplateIndexConstants.TEMPLATE_HTTP_BASIC, TemplateIndexConstants.TEMPLATE_HTTP_BEARER, TemplateIndexConstants.TEMPLATE_OAUTH, TemplateIndexConstants.TEMPLATE_OAUTH_FLOW); + public ClasspathTemplateLoader() { super(); init(getResourceFolderFiles()); diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/template/TemplateFactory.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/template/TemplateFactory.java index 255ea19d..47905c32 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/template/TemplateFactory.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/template/TemplateFactory.java @@ -10,6 +10,7 @@ import java.io.IOException; import java.util.List; import java.util.Objects; + import com.sngular.api.generator.plugin.common.template.CommonTemplateFactory; import com.sngular.api.generator.plugin.openapi.model.AuthObject; import com.sngular.api.generator.plugin.openapi.model.PathObject; @@ -20,10 +21,11 @@ public class TemplateFactory extends CommonTemplateFactory { private static final String DEFAULT_API_PACKAGE = "com.sngular.api"; - public TemplateFactory(boolean enableOverwrite, - final File targetFolder, - final String processedGeneratedSourcesFolder, - final File baseDir) { + public TemplateFactory( + boolean enableOverwrite, + final File targetFolder, + final String processedGeneratedSourcesFolder, + final File baseDir) { super(enableOverwrite, targetFolder, processedGeneratedSourcesFolder, baseDir, new ClasspathTemplateLoader()); } @@ -59,7 +61,12 @@ public final void fillTemplateAuth(final String apiPackage, final String authNam writeTemplateToFile(createNameTemplate(authName), apiPackage, authName); } - public final void fillTemplate(final SpecFile specFile, final String className, + private String createNameTemplate(final String classNameAuth) { + return "template" + classNameAuth + ".ftlh"; + } + + public final void fillTemplate( + final SpecFile specFile, final String className, final List pathObjects, final AuthObject authObject) throws IOException { addToRoot("className", className); @@ -79,7 +86,15 @@ public final void fillTemplate(final SpecFile specFile, final String className, } writeTemplateToFile(specFile.isCallMode() ? getTemplateClientApi(specFile) : getTemplateApi(specFile), - StringUtils.defaultIfEmpty(specFile.getApiPackage(), DEFAULT_API_PACKAGE), className + "Api"); + StringUtils.defaultIfEmpty(specFile.getApiPackage(), DEFAULT_API_PACKAGE), className + "Api"); + } + + private String getTemplateClientApi(final SpecFile specFile) { + return specFile.isReactive() ? TemplateIndexConstants.TEMPLATE_CALL_WEB_API : TemplateIndexConstants.TEMPLATE_CALL_REST_API; + } + + private String getTemplateApi(final SpecFile specFile) { + return specFile.isReactive() ? TemplateIndexConstants.TEMPLATE_REACTIVE_API : TemplateIndexConstants.TEMPLATE_INTERFACE_API; } public final void calculateJavaEEPackage(final Integer springBootVersion) { @@ -106,16 +121,4 @@ public final void setAuthPackageName(final String packageName) { addToRoot("packageAuth", packageName); } - private String createNameTemplate(final String classNameAuth) { - return "template" + classNameAuth + ".ftlh"; - } - - private String getTemplateClientApi(final SpecFile specFile) { - return specFile.isReactive() ? TemplateIndexConstants.TEMPLATE_CALL_WEB_API : TemplateIndexConstants.TEMPLATE_CALL_REST_API; - } - - private String getTemplateApi(final SpecFile specFile) { - return specFile.isReactive() ? TemplateIndexConstants.TEMPLATE_REACTIVE_API : TemplateIndexConstants.TEMPLATE_INTERFACE_API; - } - } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/MapperAuthUtil.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/MapperAuthUtil.java index cefde8e2..3241f308 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/MapperAuthUtil.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/MapperAuthUtil.java @@ -10,6 +10,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map.Entry; + import com.fasterxml.jackson.databind.JsonNode; import com.sngular.api.generator.plugin.common.tools.ApiTool; import com.sngular.api.generator.plugin.common.tools.MapperUtil; @@ -24,7 +25,8 @@ public class MapperAuthUtil { private static final String API_KEY = "apiKey"; - private MapperAuthUtil() {} + private MapperAuthUtil() { + } public static List createAuthSchemaList(final JsonNode openAPI) { final ArrayList authList = new ArrayList<>(); @@ -34,13 +36,13 @@ public static List createAuthSchemaList(final JsonNode openAPI final var typeStr = ApiTool.getType(value); final var isHttpBearer = "http".equalsIgnoreCase(typeStr) && "bearer".equalsIgnoreCase(ApiTool.getNodeAsString(value, "scheme")); final var authSchema = AuthSchemaObject - .builder() - .name(StringCaseUtils.toCamelCase(MapperUtil.getKey(key))) - .type(isHttpBearer ? "HttpBearerAuth" : getModelTypeAuth(value)) - .apiKeyParam(API_KEY.equalsIgnoreCase(typeStr) ? ApiTool.getName(value) : "") - .apiKeyPlace(API_KEY.equalsIgnoreCase(typeStr) ? ApiTool.getNodeAsString(value, "in") : "") - .bearerSchema(isHttpBearer ? ApiTool.getNodeAsString(value, "scheme") : "") - .build(); + .builder() + .name(StringCaseUtils.toCamelCase(MapperUtil.getKey(key))) + .type(isHttpBearer ? "HttpBearerAuth" : getModelTypeAuth(value)) + .apiKeyParam(API_KEY.equalsIgnoreCase(typeStr) ? ApiTool.getName(value) : "") + .apiKeyPlace(API_KEY.equalsIgnoreCase(typeStr) ? ApiTool.getNodeAsString(value, "in") : "") + .bearerSchema(isHttpBearer ? ApiTool.getNodeAsString(value, "scheme") : "") + .build(); authList.add(authSchema); } return authList; diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/MapperPathUtil.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/MapperPathUtil.java index fefa109f..d1fa7daa 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/MapperPathUtil.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/MapperPathUtil.java @@ -6,24 +6,41 @@ package com.sngular.api.generator.plugin.openapi.utils; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.function.BiConsumer; + import com.fasterxml.jackson.databind.JsonNode; import com.sngular.api.generator.plugin.common.model.SchemaFieldObjectType; import com.sngular.api.generator.plugin.common.model.SchemaObject; import com.sngular.api.generator.plugin.common.model.TypeConstants; -import com.sngular.api.generator.plugin.common.tools.*; +import com.sngular.api.generator.plugin.common.tools.ApiTool; +import com.sngular.api.generator.plugin.common.tools.MapperContentUtil; +import com.sngular.api.generator.plugin.common.tools.MapperUtil; +import com.sngular.api.generator.plugin.common.tools.SchemaUtil; +import com.sngular.api.generator.plugin.common.tools.StringCaseUtils; import com.sngular.api.generator.plugin.openapi.exception.DuplicatedOperationException; import com.sngular.api.generator.plugin.openapi.exception.InvalidOpenAPIException; -import com.sngular.api.generator.plugin.openapi.model.*; +import com.sngular.api.generator.plugin.openapi.model.AuthSchemaObject; +import com.sngular.api.generator.plugin.openapi.model.ContentObject; +import com.sngular.api.generator.plugin.openapi.model.GlobalObject; import com.sngular.api.generator.plugin.openapi.model.GlobalObject.GlobalObjectBuilder; +import com.sngular.api.generator.plugin.openapi.model.OperationObject; +import com.sngular.api.generator.plugin.openapi.model.ParameterObject; +import com.sngular.api.generator.plugin.openapi.model.PathObject; +import com.sngular.api.generator.plugin.openapi.model.RequestObject; +import com.sngular.api.generator.plugin.openapi.model.ResponseObject; import com.sngular.api.generator.plugin.openapi.parameter.SpecFile; import org.apache.commons.collections4.IteratorUtils; import org.apache.commons.lang3.StringUtils; -import java.nio.file.Path; -import java.util.*; -import java.util.Map.Entry; -import java.util.function.BiConsumer; - public class MapperPathUtil { public static final String INLINE_PARAMETER = "InlineParameter"; @@ -38,7 +55,8 @@ public class MapperPathUtil { public static final String SCHEMA = "schema"; - private MapperPathUtil() {} + private MapperPathUtil() { + } public static GlobalObject mapOpenApiObjectToOurModels(final JsonNode openAPI, final List authSchemaList) { final var authList = getSecurityRequirementList(ApiTool.getNode(openAPI, "security"), new ArrayList<>()); @@ -87,7 +105,7 @@ private static List mapOperationObject(final SpecFile specFile, final List operationIdList = new ArrayList<>(); final var pathNode = path.getValue(); final var pathParameters = new ArrayList(); - for (final Iterator> it = pathNode.fields(); it.hasNext();) { + for (final Iterator> it = pathNode.fields(); it.hasNext(); ) { final var field = it.next(); switch (field.getKey()) { case "get": @@ -176,10 +194,10 @@ private static List getResponseList(final JsonNode responses) { if (Objects.nonNull(response.findValue(CONTENT))) { response.get(CONTENT).fieldNames().forEachRemaining( mediaType -> { - if (!mediaType.equalsIgnoreCase("*/*") && !producesList.contains(mediaType)) { - producesList.add(mediaType.replace("\"", "\\\"")); - } - }); + if (!mediaType.equalsIgnoreCase("*/*") && !producesList.contains(mediaType)) { + producesList.add(mediaType.replace("\"", "\\\"")); + } + }); } }); } @@ -237,7 +255,7 @@ private static List mapParameterObjects( } private static ParameterObject buildParameterObject( - final SpecFile specFile, final GlobalObject globalObject, final JsonNode refParameter, final Path baseDir) { + final SpecFile specFile, final GlobalObject globalObject, final JsonNode refParameter, final Path baseDir) { final var dateType = getSchemaType(getContentOrSchema(refParameter), TypeConstants.OBJECT, specFile, globalObject, baseDir); return ParameterObject.builder() .name(ApiTool.getName(refParameter)) @@ -266,7 +284,7 @@ private static List buildParameterContent( final var content = ApiTool.getNode(parameter, CONTENT); final var parameterName = ApiTool.getName(parameter); final var parameterObjects = new ArrayList(); - for (final Iterator it = content.elements(); it.hasNext();) { + for (final Iterator it = content.elements(); it.hasNext(); ) { final var contentType = it.next(); final String inlineParameter = INLINE_PARAMETER + safeCapitalize(contentClassName) + StringUtils.capitalize(parameterName); @@ -280,16 +298,16 @@ private static List buildParameterContent( final var parameterSchema = ApiTool.getNode(contentType, SCHEMA); if (TypeConstants.OBJECT.equalsIgnoreCase(ApiTool.getType(parameterSchema))) { parameterObjects.add(builder - .name(parameterName) - .dataType(SchemaFieldObjectType.fromTypeList(inlineParameterPojo)) - .importName(inlineParameterPojo) - .build()); + .name(parameterName) + .dataType(SchemaFieldObjectType.fromTypeList(inlineParameterPojo)) + .importName(inlineParameterPojo) + .build()); globalObject.getSchemaMap().put(StringCaseUtils.titleToSnakeCase(inlineParameterPojo), parameterSchema); } else { parameterObjects.add(builder - .name(parameterName) - .dataType(getSchemaType(parameterSchema, inlineParameterPojo, specFile, globalObject, baseDir)) - .build()); + .name(parameterName) + .dataType(getSchemaType(parameterSchema, inlineParameterPojo, specFile, globalObject, baseDir)) + .build()); } } return parameterObjects; @@ -307,8 +325,8 @@ private static List mapResponseObject(final SpecFile specFile, f responses .fieldNames() .forEachRemaining(responseCode -> - createResponseObject(specFile, globalObject, responseObjects, operationId, baseDir) - .accept(responseCode, ApiTool.getNode(responses, responseCode))); + createResponseObject(specFile, globalObject, responseObjects, operationId, baseDir) + .accept(responseCode, ApiTool.getNode(responses, responseCode))); } return responseObjects; } @@ -318,7 +336,7 @@ private static BiConsumer createResponseObject( final SpecFile specFile, final GlobalObject globalObject, final List responseObjects, final String operationId, final Path baseDir) { return (responseCode, response) -> - buildResponse(specFile, globalObject, responseObjects, operationId, baseDir, responseCode, response); + buildResponse(specFile, globalObject, responseObjects, operationId, baseDir, responseCode, response); } private static void buildResponse( @@ -331,11 +349,11 @@ private static void buildResponse( final String operationIdWithCap = operationId.substring(0, 1).toUpperCase() + operationId.substring(1); final var content = ApiTool.getNode(realResponse, CONTENT); responseObjects.add(ResponseObject - .builder() - .responseName(responseCode) - .description(StringUtils.defaultIfEmpty(ApiTool.getNodeAsString(realResponse, DESCRIPTION), "")) - .contentObjects(mapContentObject(specFile, content, "InlineResponse" + responseCode + operationIdWithCap, globalObject, baseDir)) - .build()); + .builder() + .responseName(responseCode) + .description(StringUtils.defaultIfEmpty(ApiTool.getNodeAsString(realResponse, DESCRIPTION), "")) + .contentObjects(mapContentObject(specFile, content, "InlineResponse" + responseCode + operationIdWithCap, globalObject, baseDir)) + .build()); } private static List mapContentObject( @@ -343,7 +361,7 @@ private static List mapContentObject( final Path baseDir) { final List contentObjects = new ArrayList<>(); if (Objects.nonNull(content)) { - for (final Iterator it = content.fieldNames(); it.hasNext();) { + for (final Iterator it = content.fieldNames(); it.hasNext(); ) { final String mediaType = it.next(); final var schema = ApiTool.getNode(ApiTool.getNode(content, mediaType), SCHEMA); final String pojoName = preparePojoName(inlineObject, schema, specFile); @@ -354,11 +372,11 @@ private static List mapContentObject( schemaObject = MapperContentUtil.mapComponentToSchemaObject(globalObject.getSchemaMap(), pojoName, schema, dataType.getBaseType(), specFile, baseDir).get(0); } contentObjects.add(ContentObject.builder() - .dataType(dataType) - .name(mediaType) - .importName(importName) - .schemaObject(schemaObject) - .build()); + .dataType(dataType) + .name(mediaType) + .importName(importName) + .schemaObject(schemaObject) + .build()); } } return contentObjects; @@ -408,19 +426,19 @@ private static JsonNode getRefSchema(JsonNode schema, SpecFile specFile, GlobalO final String refValue = ApiTool.getRefValue(schema); if (refValue.contains("schemas")) { refSchema = SchemaUtil.solveRef(refValue, globalObject.getSchemaMap(), - baseDir.resolve(specFile.getFilePath()).getParent().toUri()); + baseDir.resolve(specFile.getFilePath()).getParent().toUri()); } else if (refValue.contains("requestBodies")) { refSchema = SchemaUtil.solveRef(refValue, globalObject.getRequestBodyMap(), - baseDir.resolve(specFile.getFilePath()).getParent().toUri()); + baseDir.resolve(specFile.getFilePath()).getParent().toUri()); } else if (refValue.contains("parameters")) { refSchema = SchemaUtil.solveRef(refValue, globalObject.getParameterMap(), - baseDir.resolve(specFile.getFilePath()).getParent().toUri()); + baseDir.resolve(specFile.getFilePath()).getParent().toUri()); } else if (refValue.contains("responseBodies")) { refSchema = SchemaUtil.solveRef(refValue, globalObject.getResponseMap(), - baseDir.resolve(specFile.getFilePath()).getParent().toUri()); + baseDir.resolve(specFile.getFilePath()).getParent().toUri()); } else { refSchema = SchemaUtil.solveRef(refValue, globalObject.getSchemaMap(), - baseDir.resolve(specFile.getFilePath()).getParent().toUri()); + baseDir.resolve(specFile.getFilePath()).getParent().toUri()); globalObject.getSchemaMap().put(inlinePojoName, refSchema); } return refSchema; @@ -434,8 +452,7 @@ private static SchemaFieldObjectType getObjectOrType( case TypeConstants.INTEGER -> new SchemaFieldObjectType(getIntegerFormat(schema)); case TypeConstants.NUMBER -> new SchemaFieldObjectType(getNumberFormat(schema)); case TypeConstants.BOOLEAN -> new SchemaFieldObjectType(TypeConstants.BOOLEAN); - case TypeConstants.ARRAY -> - new SchemaFieldObjectType(TypeConstants.ARRAY, getSchemaType(ApiTool.getItems(schema), pojoName, specFile, globalObject, baseDir)); + case TypeConstants.ARRAY -> new SchemaFieldObjectType(TypeConstants.ARRAY, getSchemaType(ApiTool.getItems(schema), pojoName, specFile, globalObject, baseDir)); default -> new SchemaFieldObjectType(TypeConstants.STRING); }; } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/OpenApiUtil.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/OpenApiUtil.java index fc4f2c1f..c5690e71 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/OpenApiUtil.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/OpenApiUtil.java @@ -6,6 +6,17 @@ package com.sngular.api.generator.plugin.openapi.utils; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Set; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -19,17 +30,14 @@ import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.apache.commons.lang3.StringUtils; -import java.nio.file.Path; -import java.util.*; -import java.util.Map.Entry; - public class OpenApiUtil { public static final String PATHS = "paths"; static final Set REST_VERB_SET = Set.of("get", "post", "delete", "patch", "put"); - private OpenApiUtil() {} + private OpenApiUtil() { + } public static MultiValuedMap> mapApiGroups(final JsonNode openAPI, final boolean groupByTags) { final MultiValuedMap> mapApis = new ArrayListValuedHashMap<>(); @@ -41,11 +49,6 @@ public static MultiValuedMap> mapApiGroups(final J return mapApis; } - public static JsonNode getPojoFromSpecFile(final Path baseDir, final SpecFile specFile) { - - return SchemaUtil.getPojoFromRef(baseDir.toUri(), specFile.getFilePath()); - } - private static MultiValuedMap> mapApiGroupsByTags(final Iterator> pathList) { final MultiValuedMap> mapApis = new ArrayListValuedHashMap<>(); @@ -58,6 +61,18 @@ private static MultiValuedMap> mapApiGroupsByTags( } + private static MultiValuedMap> mapApiGroupsByUrl(final JsonNode openAPI) { + final var mapByUrl = new ArrayListValuedHashMap>(); + + for (Iterator it = openAPI.get(PATHS).fieldNames(); it.hasNext(); ) { + final var pathUrl = it.next(); + final String[] pathName = pathUrl.split("/"); + mapByUrl.put(pathName[1], Map.of(pathUrl, openAPI.get(PATHS).get(pathUrl))); + } + + return mapByUrl; + } + private static MultiValuedMap> getMapMethodsByTag(final Entry pathItem) { final MultiValuedMap> mapByTag = new ArrayListValuedHashMap<>(); final var operations = IteratorUtils.filteredIterator(pathItem.getValue().fields(), opProperty -> REST_VERB_SET.contains(opProperty.getKey())); @@ -71,24 +86,17 @@ private static MultiValuedMap> getMapMethodsByTag( return mapByTag; } - private static MultiValuedMap> mapApiGroupsByUrl(final JsonNode openAPI) { - final var mapByUrl = new ArrayListValuedHashMap>(); - - for (Iterator it = openAPI.get(PATHS).fieldNames(); it.hasNext();) { - final var pathUrl = it.next(); - final String[] pathName = pathUrl.split("/"); - mapByUrl.put(pathName[1], Map.of(pathUrl, openAPI.get(PATHS).get(pathUrl))); - } + public static JsonNode getPojoFromSpecFile(final Path baseDir, final SpecFile specFile) { - return mapByUrl; + return SchemaUtil.getPojoFromRef(baseDir.toUri(), specFile.getFilePath()); } public static Map processPaths(final JsonNode openApi, final Map schemaMap, SpecFile specFile) { final var basicJsonNodeMap = new HashMap<>(schemaMap); - for (final var pathElement = openApi.findValue(PATHS).elements(); pathElement.hasNext();) { + for (final var pathElement = openApi.findValue(PATHS).elements(); pathElement.hasNext(); ) { final var pathDefinition = pathElement.next(); - for (Iterator it = pathDefinition.fieldNames(); it.hasNext();) { + for (Iterator it = pathDefinition.fieldNames(); it.hasNext(); ) { final var pathDefElement = it.next(); if (REST_VERB_SET.contains(pathDefElement)) { processPathContent(basicJsonNodeMap, ApiTool.getNode(pathDefinition, pathDefElement), specFile); @@ -106,6 +114,20 @@ private static void processPathContent(final HashMap basicJson processResponses(basicJsonNodeMap, operation, specFile); } + private static void processParameters(final HashMap basicJsonNodeMap, final JsonNode operation, SpecFile specFile) { + if (ApiTool.hasNode(operation, "parameters")) { + for (Iterator it = operation.findValue("parameters").elements(); it.hasNext(); ) { + final var parameter = it.next(); + if (ApiTool.hasNode(parameter, "content")) { + basicJsonNodeMap.putIfAbsent( + StringCaseUtils.titleToSnakeCase( + MapperUtil.getPojoName("InlineParameter" + StringUtils.capitalize(getOperationId(operation)) + StringUtils.capitalize(ApiTool.getName(parameter)), specFile)), + ApiTool.getNode(parameter, "schema")); + } + } + } + } + private static void processRequestBody(final HashMap basicJsonNodeMap, final JsonNode operation, SpecFile specFile) { if (ApiTool.hasNode(operation, "requestBody") && !operation.at("/requestBody/content").isMissingNode()) { final var content = operation.at("/requestBody/content"); @@ -113,7 +135,9 @@ private static void processRequestBody(final HashMap basicJson if (!ApiTool.hasRef(schema)) { basicJsonNodeMap.put(StringCaseUtils.titleToSnakeCase(MapperUtil.getPojoName("InlineObject" + StringUtils.capitalize(getOperationId(operation)), specFile)), schema); } else if (ApiTool.hasItems(schema)) { - basicJsonNodeMap.put(StringCaseUtils.titleToSnakeCase(MapperUtil.getPojoName("InlineObject" + StringUtils.capitalize(ApiTool.getNodeAsString(operation, "operationId")), specFile)), ApiTool.getItems(schema)); + basicJsonNodeMap.put( + StringCaseUtils.titleToSnakeCase(MapperUtil.getPojoName("InlineObject" + StringUtils.capitalize(ApiTool.getNodeAsString(operation, "operationId")), specFile)), + ApiTool.getItems(schema)); } } } @@ -121,15 +145,19 @@ private static void processRequestBody(final HashMap basicJson private static void processResponses(final HashMap basicJsonNodeMap, final JsonNode operation, SpecFile specFile) { if (ApiTool.hasNode(operation, "responses")) { final var responses = ApiTool.getNode(operation, "responses"); - for (Iterator> it = responses.fields(); it.hasNext();) { + for (Iterator> it = responses.fields(); it.hasNext(); ) { final var response = it.next(); if (ApiTool.hasContent(response.getValue())) { final var schemaList = ApiTool.findContentSchemas(response.getValue()); for (var schema : schemaList) { if (!ApiTool.hasRef(schema) && ApiTool.isObject(schema)) { - basicJsonNodeMap.put(StringCaseUtils.titleToSnakeCase(MapperUtil.getPojoName("InlineResponse" + response.getKey() + StringUtils.capitalize(getOperationId(operation)), specFile)), schema); + basicJsonNodeMap.put( + StringCaseUtils.titleToSnakeCase(MapperUtil.getPojoName("InlineResponse" + response.getKey() + StringUtils.capitalize(getOperationId(operation)), specFile)), + schema); } else if (ApiTool.isComposed(schema)) { - basicJsonNodeMap.put(StringCaseUtils.titleToSnakeCase(MapperUtil.getPojoName("InlineResponse" + response.getKey() + StringUtils.capitalize(getOperationId(operation)) + getComposedJsonNodeName(schema), specFile)), schema); + basicJsonNodeMap.put(StringCaseUtils.titleToSnakeCase( + MapperUtil.getPojoName("InlineResponse" + response.getKey() + StringUtils.capitalize(getOperationId(operation)) + getComposedJsonNodeName(schema), specFile)), + schema); } } } @@ -137,19 +165,6 @@ private static void processResponses(final HashMap basicJsonNo } } - private static void processParameters(final HashMap basicJsonNodeMap, final JsonNode operation, SpecFile specFile) { - if (ApiTool.hasNode(operation, "parameters")) { - for (Iterator it = operation.findValue("parameters").elements(); it.hasNext();) { - final var parameter = it.next(); - if (ApiTool.hasNode(parameter, "content")) { - basicJsonNodeMap.putIfAbsent( - StringCaseUtils.titleToSnakeCase(MapperUtil.getPojoName("InlineParameter" + StringUtils.capitalize(getOperationId(operation)) + StringUtils.capitalize(ApiTool.getName(parameter)), specFile)), - ApiTool.getNode(parameter, "schema")); - } - } - } - } - private static String getOperationId(final JsonNode operation) { return ApiTool.getNodeAsString(operation, "operationId"); } diff --git a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v2/AsyncApiGeneratorFixtures.java b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v2/AsyncApiGeneratorFixtures.java index d3531e93..ecc9a218 100644 --- a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v2/AsyncApiGeneratorFixtures.java +++ b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v2/AsyncApiGeneratorFixtures.java @@ -6,11 +6,7 @@ package com.sngular.api.generator.plugin.asyncapi.v2; -import com.sngular.api.generator.plugin.asyncapi.parameter.OperationParameterObject; -import com.sngular.api.generator.plugin.asyncapi.parameter.SpecFile; -import com.sngular.api.generator.test.utils.TestUtils; -import org.apache.commons.collections4.CollectionUtils; -import org.assertj.core.api.Assertions; +import static java.util.Collections.singletonList; import java.io.File; import java.net.URISyntaxException; @@ -19,412 +15,416 @@ import java.util.List; import java.util.function.Function; -import static java.util.Collections.singletonList; +import com.sngular.api.generator.plugin.asyncapi.parameter.OperationParameterObject; +import com.sngular.api.generator.plugin.asyncapi.parameter.SpecFile; +import com.sngular.api.generator.test.utils.TestUtils; +import org.apache.commons.collections4.CollectionUtils; +import org.assertj.core.api.Assertions; public class AsyncApiGeneratorFixtures { static final List TEST_FILE_GENERATION = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testFileGeneration/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("publishOperationFileGeneration") - .classNamePostfix("TestClassName") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.filegeneration.model.event.consumer") - .modelPackage("com.sngular.scsplugin.filegeneration.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("subscribeOperationFileGeneration") - .modelNameSuffix("Mapper") - .apiPackage("com.sngular.scsplugin.filegeneration.model.event.producer") - .modelPackage("com.sngular.scsplugin.filegeneration.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testFileGeneration/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("publishOperationFileGeneration") + .classNamePostfix("TestClassName") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.filegeneration.model.event.consumer") + .modelPackage("com.sngular.scsplugin.filegeneration.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("subscribeOperationFileGeneration") + .modelNameSuffix("Mapper") + .apiPackage("com.sngular.scsplugin.filegeneration.model.event.producer") + .modelPackage("com.sngular.scsplugin.filegeneration.model.event") + .build()) + .build() ); static final List TEST_FILE_GENERATION_NO_CONFIG = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testFileGenerationNoConfiguration/event-api.yml") - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testFileGenerationNoConfiguration/event-api.yml") + .build() ); static final List TEST_ISSUE_GENERATION = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testIssueGeneration/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("response") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.issuegeneration.model.event.consumer") - .modelPackage("com.sngular.scsplugin.issuegeneration.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("clients") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.issuegeneration.model.event.producer") - .modelPackage("com.sngular.scsplugin.issuegeneration.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testIssueGeneration/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("response") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.issuegeneration.model.event.consumer") + .modelPackage("com.sngular.scsplugin.issuegeneration.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("clients") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.issuegeneration.model.event.producer") + .modelPackage("com.sngular.scsplugin.issuegeneration.model.event") + .build()) + .build() ); static final List TEST_ISSUE_SIMPLE_TYPE_GENERATION = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testIssueSimpleTypeGeneration/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("response") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.issuesimpletypegeneration.model.event.consumer") - .modelPackage("com.sngular.scsplugin.issuesimpletypegeneration.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("clients") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.issuesimpletypegeneration.model.event.producer") - .modelPackage("com.sngular.scsplugin.issuesimpletypegeneration.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testIssueSimpleTypeGeneration/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("response") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.issuesimpletypegeneration.model.event.consumer") + .modelPackage("com.sngular.scsplugin.issuesimpletypegeneration.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("clients") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.issuesimpletypegeneration.model.event.producer") + .modelPackage("com.sngular.scsplugin.issuesimpletypegeneration.model.event") + .build()) + .build() ); static final List TEST_RESERVED_WORDS_GENERATION = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testReservedWordsGeneration/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("subscribeOperationFileGeneration") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.reservedwordsgeneration.model.event.consumer") - .modelPackage("com.sngular.scsplugin.reservedwordsgeneration.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("publishOperationFileGeneration") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.reservedwordsgeneration.model.event.producer") - .modelPackage("com.sngular.scsplugin.reservedwordsgeneration.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testReservedWordsGeneration/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("subscribeOperationFileGeneration") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.reservedwordsgeneration.model.event.consumer") + .modelPackage("com.sngular.scsplugin.reservedwordsgeneration.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("publishOperationFileGeneration") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.reservedwordsgeneration.model.event.producer") + .modelPackage("com.sngular.scsplugin.reservedwordsgeneration.model.event") + .build()) + .build() ); static final List TEST_RARE_CHARS_GENERATION = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testRareCharsGeneration/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("subscribeOperationFileGeneration") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.rarecharsgeneration.model.event.consumer") - .modelPackage("com.sngular.scsplugin.rarecharsgeneration.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("publishOperationFileGeneration") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.rarecharsgeneration.model.event.producer") - .modelPackage("com.sngular.scsplugin.rarecharsgeneration.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testRareCharsGeneration/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("subscribeOperationFileGeneration") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.rarecharsgeneration.model.event.consumer") + .modelPackage("com.sngular.scsplugin.rarecharsgeneration.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("publishOperationFileGeneration") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.rarecharsgeneration.model.event.producer") + .modelPackage("com.sngular.scsplugin.rarecharsgeneration.model.event") + .build()) + .build() ); static final List TEST_CUSTOM_VALIDATORS = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testCustomValidators/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("customValidatorResponse") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.customvalidator.model.event.consumer") - .modelPackage("com.sngular.scsplugin.customvalidator.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("customValidatorClients") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.customvalidator.model.event.producer") - .modelPackage("com.sngular.scsplugin.customvalidator.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testCustomValidators/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("customValidatorResponse") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.customvalidator.model.event.consumer") + .modelPackage("com.sngular.scsplugin.customvalidator.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("customValidatorClients") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.customvalidator.model.event.producer") + .modelPackage("com.sngular.scsplugin.customvalidator.model.event") + .build()) + .build() ); static final List TEST_FILE_GENERATION_ISSUE = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testFileGenerationIssue/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("onCustomerEvent") - .classNamePostfix("TestClassName") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.filegenerationissue.model.event.consumer") - .modelPackage("com.sngular.scsplugin.filegenerationissue.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("onCustomerOrderEvent") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.filegenerationissue.model.event.producer") - .modelPackage("com.sngular.scsplugin.filegenerationissue.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testFileGenerationIssue/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("onCustomerEvent") + .classNamePostfix("TestClassName") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.filegenerationissue.model.event.consumer") + .modelPackage("com.sngular.scsplugin.filegenerationissue.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("onCustomerOrderEvent") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.filegenerationissue.model.event.producer") + .modelPackage("com.sngular.scsplugin.filegenerationissue.model.event") + .build()) + .build() ); static final List TEST_FILE_GENERATION_EXTERNAL_AVRO = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testFileGenerationExternalAvro/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("subscribeOperationExternalAvro,subscribeReceiptExternalAvro") - .apiPackage("com.sngular.scsplugin.externalavro.model.event.consumer") - .modelPackage("com.sngular.scsplugin.externalavro.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("publishOperationExternalAvro") - .apiPackage("com.sngular.scsplugin.externalavro.model.event.producer") - .modelPackage("com.sngular.scsplugin.externalavro.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testFileGenerationExternalAvro/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("subscribeOperationExternalAvro,subscribeReceiptExternalAvro") + .apiPackage("com.sngular.scsplugin.externalavro.model.event.consumer") + .modelPackage("com.sngular.scsplugin.externalavro.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("publishOperationExternalAvro") + .apiPackage("com.sngular.scsplugin.externalavro.model.event.producer") + .modelPackage("com.sngular.scsplugin.externalavro.model.event") + .build()) + .build() ); static final List TEST_ISSUE_INVALID_AVRO = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testIssueInvalidAvro/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("subscribeOperationExternalAvro") - .apiPackage("com.sngular.scsplugin.issueAvro.model.event.consumer") - .modelPackage("com.sngular.scsplugin.issueAvro.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("publishOperationExternalAvro") - .apiPackage("com.sngular.scsplugin.issueAvro.model.event.producer") - .modelPackage("com.sngular.scsplugin.issueAvro.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testIssueInvalidAvro/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("subscribeOperationExternalAvro") + .apiPackage("com.sngular.scsplugin.issueAvro.model.event.consumer") + .modelPackage("com.sngular.scsplugin.issueAvro.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("publishOperationExternalAvro") + .apiPackage("com.sngular.scsplugin.issueAvro.model.event.producer") + .modelPackage("com.sngular.scsplugin.issueAvro.model.event") + .build()) + .build() ); static final List TEST_FILE_GENERATION_STREAM_BRIDGE = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testFileGenerationStreamBridge/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("subscribeOperationStreamBridge") - .classNamePostfix("TestClassName") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.streambridge.model.event.consumer") - .modelPackage("com.sngular.scsplugin.streambridge.model.event") - .build()) - .streamBridge(OperationParameterObject.builder() - .ids("publishOperationStreamBridge") - .apiPackage("com.sngular.scsplugin.streambridge.model.event.producer") - .modelPackage("com.sngular.scsplugin.streambridge.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testFileGenerationStreamBridge/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("subscribeOperationStreamBridge") + .classNamePostfix("TestClassName") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.streambridge.model.event.consumer") + .modelPackage("com.sngular.scsplugin.streambridge.model.event") + .build()) + .streamBridge(OperationParameterObject.builder() + .ids("publishOperationStreamBridge") + .apiPackage("com.sngular.scsplugin.streambridge.model.event.producer") + .modelPackage("com.sngular.scsplugin.streambridge.model.event") + .build()) + .build() ); static final List TEST_FILE_GENERATION_WITHOUT_OPERATION_IDS = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testFileGenerationWithoutOperationIds/event-api.yml") - .consumer(OperationParameterObject.builder() - .classNamePostfix("TestClassName") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.withoutoperationids.model.event.consumer") - .modelPackage("com.sngular.scsplugin.withoutoperationids.model.event") - .build()) - .streamBridge(OperationParameterObject.builder() - .apiPackage("com.sngular.scsplugin.withoutoperationids.model.event.producer") - .modelPackage("com.sngular.scsplugin.withoutoperationids.model.event") - .modelNameSuffix("DTO") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testFileGenerationWithoutOperationIds/event-api.yml") + .consumer(OperationParameterObject.builder() + .classNamePostfix("TestClassName") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.withoutoperationids.model.event.consumer") + .modelPackage("com.sngular.scsplugin.withoutoperationids.model.event") + .build()) + .streamBridge(OperationParameterObject.builder() + .apiPackage("com.sngular.scsplugin.withoutoperationids.model.event.producer") + .modelPackage("com.sngular.scsplugin.withoutoperationids.model.event") + .modelNameSuffix("DTO") + .build()) + .build() ); static final List TEST_FILE_GENERATION_WITH_ARRAY_STRING = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testFileGenerationArrayString/event-api.yml") - .supplier(OperationParameterObject.builder() - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.arraywithstring.model.event.producer") - .modelPackage("com.sngular.scsplugin.arraywithstring.model.event") - .useLombokModelAnnotation(true) - .build()) - .build()); + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testFileGenerationArrayString/event-api.yml") + .supplier(OperationParameterObject.builder() + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.arraywithstring.model.event.producer") + .modelPackage("com.sngular.scsplugin.arraywithstring.model.event") + .useLombokModelAnnotation(true) + .build()) + .build()); static final List TEST_ISSUE_GENERATE_SUPPLIER = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testIssueGenerateSupplier/event-api.yml") - .supplier(OperationParameterObject.builder() - .modelNameSuffix("DTO") - .apiPackage("company.mail.messaging") - .modelPackage("company.mail.model") - .useLombokModelAnnotation(true) - .build()) - .build()); + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testIssueGenerateSupplier/event-api.yml") + .supplier(OperationParameterObject.builder() + .modelNameSuffix("DTO") + .apiPackage("company.mail.messaging") + .modelPackage("company.mail.model") + .useLombokModelAnnotation(true) + .build()) + .build()); static final List TEST_ISSUE_INFINITE_LOOP = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testIssueInfiniteLoop/event-api.yml") - .supplier(OperationParameterObject.builder() - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.infiniteLoop.messaging") - .modelPackage("com.sngular.scsplugin.infiniteLoop.model") - .useLombokModelAnnotation(true) - .build()) - .build()); + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testIssueInfiniteLoop/event-api.yml") + .supplier(OperationParameterObject.builder() + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.infiniteLoop.messaging") + .modelPackage("com.sngular.scsplugin.infiniteLoop.model") + .useLombokModelAnnotation(true) + .build()) + .build()); static final List TEST_MODEL_CLASS_EXCEPTION_GENERATION = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testModelClassExceptionGeneration/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("subscribeOrder") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.modelclass.model.event.consumer") - .modelPackage("com.sngular.scsplugin.modelclass.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("publishOrder") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.modelclass.model.event.producer") - .modelPackage("com.sngular.scsplugin.modelclass.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testModelClassExceptionGeneration/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("subscribeOrder") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.modelclass.model.event.consumer") + .modelPackage("com.sngular.scsplugin.modelclass.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("publishOrder") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.modelclass.model.event.producer") + .modelPackage("com.sngular.scsplugin.modelclass.model.event") + .build()) + .build() ); static final List TEST_GENERATION_WITH_NO_OPERATION_ID = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testGenerationWithNoOperationId/event-api.yml") - .consumer(OperationParameterObject.builder() - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.withoutoperationid.model.event.consumer") - .modelPackage("com.sngular.scsplugin.withoutoperationid.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testGenerationWithNoOperationId/event-api.yml") + .consumer(OperationParameterObject.builder() + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.withoutoperationid.model.event.consumer") + .modelPackage("com.sngular.scsplugin.withoutoperationid.model.event") + .build()) + .build() ); static final List TEST_NO_SCHEMAS = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testNoSchemas/event-api.yml") - .supplier(OperationParameterObject.builder() - .modelNameSuffix("") - .apiPackage("com.sngular.scsplugin.noschemas") - .modelPackage("com.sngular.scsplugin.noschemas.model") - .useLombokModelAnnotation(true) - .build()) - .build()); + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testNoSchemas/event-api.yml") + .supplier(OperationParameterObject.builder() + .modelNameSuffix("") + .apiPackage("com.sngular.scsplugin.noschemas") + .modelPackage("com.sngular.scsplugin.noschemas.model") + .useLombokModelAnnotation(true) + .build()) + .build()); static final List TEST_MESSAGE_NAMING = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testMessageNaming/event-api.yml") - .supplier(OperationParameterObject.builder() - .modelNameSuffix("") - .apiPackage("com.sngular.scsplugin.messagenaming") - .modelPackage("com.sngular.scsplugin.messagenaming.model") - .useLombokModelAnnotation(true) - .build()) - .build()); + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testMessageNaming/event-api.yml") + .supplier(OperationParameterObject.builder() + .modelNameSuffix("") + .apiPackage("com.sngular.scsplugin.messagenaming") + .modelPackage("com.sngular.scsplugin.messagenaming.model") + .useLombokModelAnnotation(true) + .build()) + .build()); static final List TEST_NESTED_OBJECT_ISSUE = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testNestedObjectIssue/event-api.yml") - .consumer(OperationParameterObject.builder() - .modelNameSuffix("") - .apiPackage("com.sngular.scsplugin.nestedobject.consumer") - .modelPackage("com.sngular.scsplugin.nestedobject.model") - .useLombokModelAnnotation(true) - .build()) - .supplier(OperationParameterObject.builder() - .modelNameSuffix("") - .apiPackage("com.sngular.scsplugin.nestedobject.producer") - .modelPackage("com.sngular.scsplugin.nestedobject.model") - .useLombokModelAnnotation(true) - .build()) - .build()); + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testNestedObjectIssue/event-api.yml") + .consumer(OperationParameterObject.builder() + .modelNameSuffix("") + .apiPackage("com.sngular.scsplugin.nestedobject.consumer") + .modelPackage("com.sngular.scsplugin.nestedobject.model") + .useLombokModelAnnotation(true) + .build()) + .supplier(OperationParameterObject.builder() + .modelNameSuffix("") + .apiPackage("com.sngular.scsplugin.nestedobject.producer") + .modelPackage("com.sngular.scsplugin.nestedobject.model") + .useLombokModelAnnotation(true) + .build()) + .build()); static final List TEST_CONSTANT_GENERATION = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testConstantGeneration/event-api.yml") - .consumer(OperationParameterObject.builder() - .modelNameSuffix("") - .apiPackage("com.sngular.scsplugin.constantgeneration.consumer") - .modelPackage("com.sngular.scsplugin.constantgeneration.model") - .useLombokModelAnnotation(true) - .build()) - .supplier(OperationParameterObject.builder() - .modelNameSuffix("") - .apiPackage("com.sngular.scsplugin.constantgeneration.producer") - .modelPackage("com.sngular.scsplugin.constantgeneration.model") - .useLombokModelAnnotation(true) - .build()) - .build()); + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testConstantGeneration/event-api.yml") + .consumer(OperationParameterObject.builder() + .modelNameSuffix("") + .apiPackage("com.sngular.scsplugin.constantgeneration.consumer") + .modelPackage("com.sngular.scsplugin.constantgeneration.model") + .useLombokModelAnnotation(true) + .build()) + .supplier(OperationParameterObject.builder() + .modelNameSuffix("") + .apiPackage("com.sngular.scsplugin.constantgeneration.producer") + .modelPackage("com.sngular.scsplugin.constantgeneration.model") + .useLombokModelAnnotation(true) + .build()) + .build()); static final List PROPERTIES_NOT_GENERATED_ISSUE = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testPropertiesNotGeneratedIssue/event-api.yml") - .consumer(OperationParameterObject.builder() - .modelNameSuffix("") - .operationIds(List.of("emitUserSignUpEvent")) - .apiPackage("com.sngular.scsplugin.notgeneratedproperties.consumer") - .modelPackage("com.sngular.scsplugin.notgeneratedproperties.model") - .useLombokModelAnnotation(true) - .build()) - .build()); + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testPropertiesNotGeneratedIssue/event-api.yml") + .consumer(OperationParameterObject.builder() + .modelNameSuffix("") + .operationIds(List.of("emitUserSignUpEvent")) + .apiPackage("com.sngular.scsplugin.notgeneratedproperties.consumer") + .modelPackage("com.sngular.scsplugin.notgeneratedproperties.model") + .useLombokModelAnnotation(true) + .build()) + .build()); static final List TEST_FILE_GENERATION_WITH_KAFKA_BINDINGS = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v2/testFileGenerationWithKafkaBindings/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("publishOperationFileGenerationWithKafkaBindings") - .classNamePostfix("TestClassName") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.filegenerationwithkafkabindings.model.event.consumer") - .modelPackage("com.sngular.scsplugin.filegenerationwithkafkabindings.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("subscribeOperationFileGenerationWithKafkaBindings") - .modelNameSuffix("Mapper") - .apiPackage("com.sngular.scsplugin.filegenerationwithkafkabindings.model.event.producer") - .modelPackage("com.sngular.scsplugin.filegenerationwithkafkabindings.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v2/testFileGenerationWithKafkaBindings/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("publishOperationFileGenerationWithKafkaBindings") + .classNamePostfix("TestClassName") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.filegenerationwithkafkabindings.model.event.consumer") + .modelPackage("com.sngular.scsplugin.filegenerationwithkafkabindings.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("subscribeOperationFileGenerationWithKafkaBindings") + .modelNameSuffix("Mapper") + .apiPackage("com.sngular.scsplugin.filegenerationwithkafkabindings.model.event.producer") + .modelPackage("com.sngular.scsplugin.filegenerationwithkafkabindings.model.event") + .build()) + .build() ); static final List TEST_SUB_OBJECT_SAME_NAME = - List.of( - SpecFile.builder() - .filePath("asyncapigenerator/v2/testSubObjectSameName/event-api.yml") - .consumer( - OperationParameterObject.builder() - .ids("input") - .apiPackage("input.controller") - .modelPackage("input.model") - .build()) - .supplier( - OperationParameterObject.builder() - .ids("output") - .apiPackage("output.provider") - .modelPackage("output.model") - .build()) - .build()); + List.of( + SpecFile.builder() + .filePath("asyncapigenerator/v2/testSubObjectSameName/event-api.yml") + .consumer( + OperationParameterObject.builder() + .ids("input") + .apiPackage("input.controller") + .modelPackage("input.model") + .build()) + .supplier( + OperationParameterObject.builder() + .ids("output") + .apiPackage("output.provider") + .modelPackage("output.model") + .build()) + .build()); static final List TEST_REFERENCE_FROM_LOCAL_ISSUE = - List.of( - SpecFile.builder() - .filePath("asyncapigenerator/v2/testReferenceFromLocalIssue/event-api.yml") - .consumer( - OperationParameterObject.builder() - .ids("userSignedUp") - .apiPackage("com.github.issue.listener") - .modelPackage("com.github.issue.model") - .build()) - .build()); + List.of( + SpecFile.builder() + .filePath("asyncapigenerator/v2/testReferenceFromLocalIssue/event-api.yml") + .consumer( + OperationParameterObject.builder() + .ids("userSignedUp") + .apiPackage("com.github.issue.listener") + .modelPackage("com.github.issue.model") + .build()) + .build()); static final String TARGET = "target"; @@ -449,41 +449,41 @@ static Function validateTestFileGeneration() { final String DEFAULT_EXCEPTION_API = DEFAULT_COMMON_FOLDER + "/exception"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "IPublishOperationFileGeneration.java", - ASSETS_PATH + "TestClassName.java"); + ASSETS_PATH + "IPublishOperationFileGeneration.java", + ASSETS_PATH + "TestClassName.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "ISubscribeOperationFileGeneration.java", - ASSETS_PATH + "Producer.java"); + ASSETS_PATH + "ISubscribeOperationFileGeneration.java", + ASSETS_PATH + "Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "CreateOrderMapper.java", - ASSETS_PATH + "OrderDTO.java", - ASSETS_PATH + "OrderLineDTO.java", - ASSETS_PATH + "OrderLineMapper.java", - ASSETS_PATH + "OrderMapper.java", - ASSETS_PATH + "OrderProductDTO.java", - ASSETS_PATH + "OrderProductMapper.java", - ASSETS_PATH + "WaiterMapper.java" + ASSETS_PATH + "CreateOrderMapper.java", + ASSETS_PATH + "OrderDTO.java", + ASSETS_PATH + "OrderLineDTO.java", + ASSETS_PATH + "OrderLineMapper.java", + ASSETS_PATH + "OrderMapper.java", + ASSETS_PATH + "OrderProductDTO.java", + ASSETS_PATH + "OrderProductMapper.java", + ASSETS_PATH + "WaiterMapper.java" ); final List expectedValidatorFiles = List.of( - CUSTOM_VALIDATOR_PATH + "NotNull.java", - CUSTOM_VALIDATOR_PATH + "NotNullValidator.java" + CUSTOM_VALIDATOR_PATH + "NotNull.java", + CUSTOM_VALIDATOR_PATH + "NotNullValidator.java" ); final List expectedExceptionFiles = List.of( - ASSETS_PATH + "ModelClassException.java"); + ASSETS_PATH + "ModelClassException.java"); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - expectedExceptionFiles, DEFAULT_EXCEPTION_API) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_COMMON_FOLDER) && - customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); + expectedExceptionFiles, DEFAULT_EXCEPTION_API) && + modelTest(path, expectedModelSchemaFiles, DEFAULT_COMMON_FOLDER) && + customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); } private static Boolean commonTest( - final Path resultPath, final List expectedFile, final List expectedModelFiles, final String targetConsumer, - final String targetProducer, final List expectedExceptionFiles, final String targetException) { + final Path resultPath, final List expectedFile, final List expectedModelFiles, final String targetConsumer, + final String targetProducer, final List expectedExceptionFiles, final String targetException) { Boolean result = Boolean.TRUE; try { final Path pathToTarget = Path.of(resultPath.toString(), "target"); @@ -558,21 +558,21 @@ static Function validateTestIssueGeneration() { final String ASSETS_PATH = COMMON_PATH + "assets/"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "IResponse.java", - ASSETS_PATH + "Subscriber.java"); + ASSETS_PATH + "IResponse.java", + ASSETS_PATH + "Subscriber.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "IClients.java", - ASSETS_PATH + "Producer.java"); + ASSETS_PATH + "IClients.java", + ASSETS_PATH + "Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "DataDTO.java", - ASSETS_PATH + "StatusMsgDTO.java" + ASSETS_PATH + "DataDTO.java", + ASSETS_PATH + "StatusMsgDTO.java" ); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - Collections.emptyList(), null) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); + Collections.emptyList(), null) && + modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); } static Function validateTestIssueSimpleTypeGeneration() { @@ -587,21 +587,21 @@ static Function validateTestIssueSimpleTypeGeneration() { final String ASSETS_PATH = COMMON_PATH + "assets/"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "IResponse.java", - ASSETS_PATH + "Subscriber.java"); + ASSETS_PATH + "IResponse.java", + ASSETS_PATH + "Subscriber.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "IClients.java", - ASSETS_PATH + "Producer.java"); + ASSETS_PATH + "IClients.java", + ASSETS_PATH + "Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "DataDTO.java", - ASSETS_PATH + "StatusMsgDTO.java" + ASSETS_PATH + "DataDTO.java", + ASSETS_PATH + "StatusMsgDTO.java" ); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - Collections.emptyList(), null) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); + Collections.emptyList(), null) && + modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); } static Function validateTestReservedWordsGeneration() { @@ -616,22 +616,22 @@ static Function validateTestReservedWordsGeneration() { final String ASSETS_PATH = COMMON_PATH + "assets/"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "ISubscribeOperationFileGeneration.java", - ASSETS_PATH + "Subscriber.java"); + ASSETS_PATH + "ISubscribeOperationFileGeneration.java", + ASSETS_PATH + "Subscriber.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "IPublishOperationFileGeneration.java", - ASSETS_PATH + "Producer.java"); + ASSETS_PATH + "IPublishOperationFileGeneration.java", + ASSETS_PATH + "Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "CreateOrderDTO.java", - ASSETS_PATH + "OrderDTO.java", - ASSETS_PATH + "OrderLineDTO.java", - ASSETS_PATH + "WaiterDTO.java" + ASSETS_PATH + "CreateOrderDTO.java", + ASSETS_PATH + "OrderDTO.java", + ASSETS_PATH + "OrderLineDTO.java", + ASSETS_PATH + "WaiterDTO.java" ); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, Collections.emptyList(), null) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); + modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); } static Function validateTestRareCharsGeneration() { @@ -646,21 +646,21 @@ static Function validateTestRareCharsGeneration() { final String ASSETS_PATH = COMMON_PATH + "assets/"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "ISubscribeOperationFileGeneration.java", - ASSETS_PATH + "Subscriber.java"); + ASSETS_PATH + "ISubscribeOperationFileGeneration.java", + ASSETS_PATH + "Subscriber.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "IPublishOperationFileGeneration.java", - ASSETS_PATH + "Producer.java"); + ASSETS_PATH + "IPublishOperationFileGeneration.java", + ASSETS_PATH + "Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "CreateOrderDTO.java", - ASSETS_PATH + "OrderDTO.java", - ASSETS_PATH + "WaiterDTO.java" + ASSETS_PATH + "CreateOrderDTO.java", + ASSETS_PATH + "OrderDTO.java", + ASSETS_PATH + "WaiterDTO.java" ); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, Collections.emptyList(), null) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); + modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); } static Function validateCustomValidators(final int springBootVersion) { @@ -681,58 +681,58 @@ static Function validateCustomValidators(final int springBootVers final String DEFAULT_EXCEPTION_API = DEFAULT_MODEL_SCHEMA_FOLDER + "/exception"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "ICustomValidatorResponse.java", - ASSETS_PATH + "Subscriber.java"); + ASSETS_PATH + "ICustomValidatorResponse.java", + ASSETS_PATH + "Subscriber.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "ICustomValidatorClients.java", - ASSETS_PATH + "Producer.java"); + ASSETS_PATH + "ICustomValidatorClients.java", + ASSETS_PATH + "Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "DataDTO.java", - ASSETS_PATH + "StatusMsgDTO.java" + ASSETS_PATH + "DataDTO.java", + ASSETS_PATH + "StatusMsgDTO.java" ); final List expectedValidatorFiles = List.of( - CUSTOM_VALIDATOR_PATH + "MaxBigDecimal.java", - CUSTOM_VALIDATOR_PATH + "MaxBigDecimalValidator.java", - CUSTOM_VALIDATOR_PATH + "MaxDouble.java", - CUSTOM_VALIDATOR_PATH + "MaxDoubleValidator.java", - CUSTOM_VALIDATOR_PATH + "MaxFloat.java", - CUSTOM_VALIDATOR_PATH + "MaxFloatValidator.java", - CUSTOM_VALIDATOR_PATH + "MaxInteger.java", - CUSTOM_VALIDATOR_PATH + "MaxIntegerValidator.java", - CUSTOM_VALIDATOR_PATH + "MaxItems.java", - CUSTOM_VALIDATOR_PATH + "MaxItemsValidator.java", - CUSTOM_VALIDATOR_PATH + "MinBigDecimal.java", - CUSTOM_VALIDATOR_PATH + "MinBigDecimalValidator.java", - CUSTOM_VALIDATOR_PATH + "MinDouble.java", - CUSTOM_VALIDATOR_PATH + "MinDoubleValidator.java", - CUSTOM_VALIDATOR_PATH + "MinFloat.java", - CUSTOM_VALIDATOR_PATH + "MinFloatValidator.java", - CUSTOM_VALIDATOR_PATH + "MinInteger.java", - CUSTOM_VALIDATOR_PATH + "MinIntegerValidator.java", - CUSTOM_VALIDATOR_PATH + "MinItems.java", - CUSTOM_VALIDATOR_PATH + "MinItemsValidator.java", - CUSTOM_VALIDATOR_PATH + "MultipleOf.java", - CUSTOM_VALIDATOR_PATH + "MultipleOfValidator.java", - CUSTOM_VALIDATOR_PATH + "NotNull.java", - CUSTOM_VALIDATOR_PATH + "NotNullValidator.java", - CUSTOM_VALIDATOR_PATH + "Pattern.java", - CUSTOM_VALIDATOR_PATH + "PatternValidator.java", - CUSTOM_VALIDATOR_PATH + "Size.java", - CUSTOM_VALIDATOR_PATH + "SizeValidator.java", - CUSTOM_VALIDATOR_PATH + "UniqueItems.java", - CUSTOM_VALIDATOR_PATH + "UniqueItemsValidator.java" + CUSTOM_VALIDATOR_PATH + "MaxBigDecimal.java", + CUSTOM_VALIDATOR_PATH + "MaxBigDecimalValidator.java", + CUSTOM_VALIDATOR_PATH + "MaxDouble.java", + CUSTOM_VALIDATOR_PATH + "MaxDoubleValidator.java", + CUSTOM_VALIDATOR_PATH + "MaxFloat.java", + CUSTOM_VALIDATOR_PATH + "MaxFloatValidator.java", + CUSTOM_VALIDATOR_PATH + "MaxInteger.java", + CUSTOM_VALIDATOR_PATH + "MaxIntegerValidator.java", + CUSTOM_VALIDATOR_PATH + "MaxItems.java", + CUSTOM_VALIDATOR_PATH + "MaxItemsValidator.java", + CUSTOM_VALIDATOR_PATH + "MinBigDecimal.java", + CUSTOM_VALIDATOR_PATH + "MinBigDecimalValidator.java", + CUSTOM_VALIDATOR_PATH + "MinDouble.java", + CUSTOM_VALIDATOR_PATH + "MinDoubleValidator.java", + CUSTOM_VALIDATOR_PATH + "MinFloat.java", + CUSTOM_VALIDATOR_PATH + "MinFloatValidator.java", + CUSTOM_VALIDATOR_PATH + "MinInteger.java", + CUSTOM_VALIDATOR_PATH + "MinIntegerValidator.java", + CUSTOM_VALIDATOR_PATH + "MinItems.java", + CUSTOM_VALIDATOR_PATH + "MinItemsValidator.java", + CUSTOM_VALIDATOR_PATH + "MultipleOf.java", + CUSTOM_VALIDATOR_PATH + "MultipleOfValidator.java", + CUSTOM_VALIDATOR_PATH + "NotNull.java", + CUSTOM_VALIDATOR_PATH + "NotNullValidator.java", + CUSTOM_VALIDATOR_PATH + "Pattern.java", + CUSTOM_VALIDATOR_PATH + "PatternValidator.java", + CUSTOM_VALIDATOR_PATH + "Size.java", + CUSTOM_VALIDATOR_PATH + "SizeValidator.java", + CUSTOM_VALIDATOR_PATH + "UniqueItems.java", + CUSTOM_VALIDATOR_PATH + "UniqueItemsValidator.java" ); final List expectedExceptionFiles = List.of( - ASSETS_PATH + "ModelClassException.java"); + ASSETS_PATH + "ModelClassException.java"); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - expectedExceptionFiles, DEFAULT_EXCEPTION_API) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER) && - customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); + expectedExceptionFiles, DEFAULT_EXCEPTION_API) && + modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER) && + customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); } private static String calculateJavaEEPackage(final int springBootVersion) { @@ -762,37 +762,37 @@ static Function validateTestFileGenerationIssue() { final String DEFAULT_EXCEPTION_API = DEFAULT_COMMON_FOLDER + "/exception"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "IOnCustomerEvent.java", - ASSETS_PATH + "TestClassName.java"); + ASSETS_PATH + "IOnCustomerEvent.java", + ASSETS_PATH + "TestClassName.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "IOnCustomerOrderEvent.java", - ASSETS_PATH + "Producer.java"); + ASSETS_PATH + "IOnCustomerOrderEvent.java", + ASSETS_PATH + "Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "CustomerDTO.java", - ASSETS_PATH + "CustomerEventPayloadDTO.java", - ASSETS_PATH + "CustomerOrderDTO.java", - ASSETS_PATH + "CustomerOrderEventPayloadDTO.java", - ASSETS_PATH + "OrderedItemDTO.java", - ASSETS_PATH + "PaymentDetailsDTO.java", - ASSETS_PATH + "ShippingDetailsDTO.java" + ASSETS_PATH + "CustomerDTO.java", + ASSETS_PATH + "CustomerEventPayloadDTO.java", + ASSETS_PATH + "CustomerOrderDTO.java", + ASSETS_PATH + "CustomerOrderEventPayloadDTO.java", + ASSETS_PATH + "OrderedItemDTO.java", + ASSETS_PATH + "PaymentDetailsDTO.java", + ASSETS_PATH + "ShippingDetailsDTO.java" ); final List expectedValidatorFiles = List.of( - CUSTOM_VALIDATOR_PATH + "NotNull.java", - CUSTOM_VALIDATOR_PATH + "NotNullValidator.java", - CUSTOM_VALIDATOR_PATH + "Size.java", - CUSTOM_VALIDATOR_PATH + "SizeValidator.java" + CUSTOM_VALIDATOR_PATH + "NotNull.java", + CUSTOM_VALIDATOR_PATH + "NotNullValidator.java", + CUSTOM_VALIDATOR_PATH + "Size.java", + CUSTOM_VALIDATOR_PATH + "SizeValidator.java" ); final List expectedExceptionFiles = List.of( - ASSETS_PATH + "ModelClassException.java"); + ASSETS_PATH + "ModelClassException.java"); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - expectedExceptionFiles, DEFAULT_EXCEPTION_API) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_COMMON_FOLDER) && - customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); + expectedExceptionFiles, DEFAULT_EXCEPTION_API) && + modelTest(path, expectedModelSchemaFiles, DEFAULT_COMMON_FOLDER) && + customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); } static Function validateTestFileGenerationExternalAvro() { @@ -805,18 +805,18 @@ static Function validateTestFileGenerationExternalAvro() { final String ASSETS_PATH = COMMON_PATH + "assets/"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "ISubscribeOperationExternalAvro.java", - ASSETS_PATH + "ISubscribeReceiptExternalAvro.java", - ASSETS_PATH + "Subscriber.java" + ASSETS_PATH + "ISubscribeOperationExternalAvro.java", + ASSETS_PATH + "ISubscribeReceiptExternalAvro.java", + ASSETS_PATH + "Subscriber.java" ); final List expectedProducerFiles = List.of( - ASSETS_PATH + "IPublishOperation.java", - ASSETS_PATH + "Producer.java" + ASSETS_PATH + "IPublishOperation.java", + ASSETS_PATH + "Producer.java" ); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - Collections.emptyList(), null); + Collections.emptyList(), null); } static Function validateTestFileGenerationStreamBridge() { @@ -834,19 +834,19 @@ static Function validateTestFileGenerationStreamBridge() { final String DEFAULT_EXCEPTION_API = DEFAULT_COMMON_FOLDER + "/exception"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "ISubscribeOperationStreamBridge.java", - ASSETS_PATH + "TestClassName.java" + ASSETS_PATH + "ISubscribeOperationStreamBridge.java", + ASSETS_PATH + "TestClassName.java" ); final List expectedProducerFiles = List.of( - ASSETS_PATH + "StreamBridgeProducer.java" + ASSETS_PATH + "StreamBridgeProducer.java" ); final List expectedExceptionFiles = List.of( - ASSETS_PATH + "ModelClassException.java"); + ASSETS_PATH + "ModelClassException.java"); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - expectedExceptionFiles, DEFAULT_EXCEPTION_API); + expectedExceptionFiles, DEFAULT_EXCEPTION_API); } static Function validateTestFileGenerationWithoutOperationIds() { @@ -864,19 +864,19 @@ static Function validateTestFileGenerationWithoutOperationIds() { final String DEFAULT_EXCEPTION_API = DEFAULT_COMMON_FOLDER + "/exception"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "ISubscribeOperation.java", - ASSETS_PATH + "TestClassName.java" + ASSETS_PATH + "ISubscribeOperation.java", + ASSETS_PATH + "TestClassName.java" ); final List expectedProducerFiles = List.of( - ASSETS_PATH + "StreamBridgeProducer.java" + ASSETS_PATH + "StreamBridgeProducer.java" ); final List expectedExceptionFiles = List.of( - ASSETS_PATH + "ModelClassException.java"); + ASSETS_PATH + "ModelClassException.java"); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - expectedExceptionFiles, DEFAULT_EXCEPTION_API); + expectedExceptionFiles, DEFAULT_EXCEPTION_API); } static Function validateTestFileGenerationArrayString() { @@ -887,7 +887,7 @@ static Function validateTestFileGenerationArrayString() { final String ASSETS_PATH = COMMON_PATH + "assets/"; final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "ObjectArrayDTO.java" + ASSETS_PATH + "ObjectArrayDTO.java" ); return path -> modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); @@ -897,8 +897,8 @@ static Function validateTestIssueGenerateSupplier() { final String DEFAULT_MODEL_SCHEMA_FOLDER = "generated/company/mail/model"; final List expectedModelSchemaFiles = List.of( - "asyncapigenerator/v2/testIssueGenerateSupplier/assets/ConfigurationDTO.java", - "asyncapigenerator/v2/testIssueGenerateSupplier/assets/MailRequestDTO.java" + "asyncapigenerator/v2/testIssueGenerateSupplier/assets/ConfigurationDTO.java", + "asyncapigenerator/v2/testIssueGenerateSupplier/assets/MailRequestDTO.java" ); return path -> modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); @@ -908,8 +908,8 @@ static Function validateTestIssueInfiniteLoop() { final String DEFAULT_MODEL_SCHEMA_FOLDER = "generated/com/sngular/scsplugin/infiniteLoop/model"; final List expectedModelSchemaFiles = List.of( - "asyncapigenerator/v2/testIssueInfiniteLoop/assets/ConfigDTO.java", - "asyncapigenerator/v2/testIssueInfiniteLoop/assets/MailRequestInfiniteDTO.java" + "asyncapigenerator/v2/testIssueInfiniteLoop/assets/ConfigDTO.java", + "asyncapigenerator/v2/testIssueInfiniteLoop/assets/MailRequestInfiniteDTO.java" ); return path -> modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); @@ -934,33 +934,33 @@ static Function validateTestModelClassExceptionGeneration() { final String DEFAULT_EXCEPTION_API = DEFAULT_COMMON_FOLDER + "/exception"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "ISubscribeOrder.java", - ASSETS_PATH + "Subscriber.java"); + ASSETS_PATH + "ISubscribeOrder.java", + ASSETS_PATH + "Subscriber.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "IPublishOrder.java", - ASSETS_PATH + "Producer.java"); + ASSETS_PATH + "IPublishOrder.java", + ASSETS_PATH + "Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "CreateOrderEventDTO.java", - ASSETS_PATH + "OrderDTO.java", - ASSETS_PATH + "OrderLineDTO.java", - ASSETS_PATH + "OrderProductDTO.java", - ASSETS_PATH + "WaiterDTO.java" + ASSETS_PATH + "CreateOrderEventDTO.java", + ASSETS_PATH + "OrderDTO.java", + ASSETS_PATH + "OrderLineDTO.java", + ASSETS_PATH + "OrderProductDTO.java", + ASSETS_PATH + "WaiterDTO.java" ); final List expectedValidatorFiles = List.of( - CUSTOM_VALIDATOR_PATH + "NotNull.java", - CUSTOM_VALIDATOR_PATH + "NotNullValidator.java" + CUSTOM_VALIDATOR_PATH + "NotNull.java", + CUSTOM_VALIDATOR_PATH + "NotNullValidator.java" ); final List expectedExceptionFiles = List.of( - ASSETS_PATH + "ModelClassException.java"); + ASSETS_PATH + "ModelClassException.java"); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - expectedExceptionFiles, DEFAULT_EXCEPTION_API) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_COMMON_FOLDER) && - customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); + expectedExceptionFiles, DEFAULT_EXCEPTION_API) && + modelTest(path, expectedModelSchemaFiles, DEFAULT_COMMON_FOLDER) && + customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); } static Function validateNoSchemas() { @@ -969,18 +969,18 @@ static Function validateNoSchemas() { final String MODEL_SCHEMA_FOLDER = "generated/com/sngular/scsplugin/noschemas/model"; final List expectedModelSchemaFiles = List.of( - "asyncapigenerator/v2/testNoSchemas/assets/TestMsg.java", - "asyncapigenerator/v2/testNoSchemas/assets/Thing.java" + "asyncapigenerator/v2/testNoSchemas/assets/TestMsg.java", + "asyncapigenerator/v2/testNoSchemas/assets/Thing.java" ); final List expectedProducerFiles = List.of( - "asyncapigenerator/v2/testNoSchemas/assets/IOnTest.java", - "asyncapigenerator/v2/testNoSchemas/assets/IOnTest2.java", - "asyncapigenerator/v2/testNoSchemas/assets/Producer.java" + "asyncapigenerator/v2/testNoSchemas/assets/IOnTest.java", + "asyncapigenerator/v2/testNoSchemas/assets/IOnTest2.java", + "asyncapigenerator/v2/testNoSchemas/assets/Producer.java" ); return path -> modelTest(path, expectedModelSchemaFiles, MODEL_SCHEMA_FOLDER) && - modelTest(path, expectedProducerFiles, API_FOLDER); + modelTest(path, expectedProducerFiles, API_FOLDER); } static Function validateMessageNaming() { @@ -989,20 +989,20 @@ static Function validateMessageNaming() { final String MODEL_SCHEMA_FOLDER = "generated/com/sngular/scsplugin/messagenaming/model"; final List expectedModelSchemaFiles = List.of( - "asyncapigenerator/v2/testMessageNaming/assets/OnTest3.java", - "asyncapigenerator/v2/testMessageNaming/assets/TestMsg.java", - "asyncapigenerator/v2/testMessageNaming/assets/TestMsg2.java" + "asyncapigenerator/v2/testMessageNaming/assets/OnTest3.java", + "asyncapigenerator/v2/testMessageNaming/assets/TestMsg.java", + "asyncapigenerator/v2/testMessageNaming/assets/TestMsg2.java" ); final List expectedProducerFiles = List.of( - "asyncapigenerator/v2/testMessageNaming/assets/IOnTest.java", - "asyncapigenerator/v2/testMessageNaming/assets/IOnTest2.java", - "asyncapigenerator/v2/testMessageNaming/assets/IOnTest3.java", - "asyncapigenerator/v2/testMessageNaming/assets/Producer.java" + "asyncapigenerator/v2/testMessageNaming/assets/IOnTest.java", + "asyncapigenerator/v2/testMessageNaming/assets/IOnTest2.java", + "asyncapigenerator/v2/testMessageNaming/assets/IOnTest3.java", + "asyncapigenerator/v2/testMessageNaming/assets/Producer.java" ); return path -> modelTest(path, expectedModelSchemaFiles, MODEL_SCHEMA_FOLDER) && - modelTest(path, expectedProducerFiles, API_FOLDER); + modelTest(path, expectedProducerFiles, API_FOLDER); } static Function validateNestedObject() { @@ -1011,14 +1011,14 @@ static Function validateNestedObject() { final String MODEL_SCHEMA_FOLDER = "generated/com/sngular/scsplugin/nestedobject/model"; final List expectedModelSchemaFiles = List.of( - "asyncapigenerator/v2/testNestedObjectIssue/assets/payload/SomeOtherObject.java", - "asyncapigenerator/v2/testNestedObjectIssue/assets/payload/UserSignedUpPayload.java" + "asyncapigenerator/v2/testNestedObjectIssue/assets/payload/SomeOtherObject.java", + "asyncapigenerator/v2/testNestedObjectIssue/assets/payload/UserSignedUpPayload.java" ); final List expectedProducerFiles = List.of(); return path -> modelTest(path, expectedModelSchemaFiles, MODEL_SCHEMA_FOLDER) && - modelTest(path, expectedProducerFiles, API_FOLDER); + modelTest(path, expectedProducerFiles, API_FOLDER); } static Function validateConstantGeneration() { @@ -1027,14 +1027,14 @@ static Function validateConstantGeneration() { final String MODEL_SCHEMA_FOLDER = "generated/com/sngular/scsplugin/constantgeneration/model"; final List expectedModelSchemaFiles = List.of( - "asyncapigenerator/v2/testConstantGeneration/assets/payload/SomeOtherObject.java", - "asyncapigenerator/v2/testConstantGeneration/assets/payload/UserSignedUpPayload.java" + "asyncapigenerator/v2/testConstantGeneration/assets/payload/SomeOtherObject.java", + "asyncapigenerator/v2/testConstantGeneration/assets/payload/UserSignedUpPayload.java" ); final List expectedProducerFiles = List.of(); return path -> modelTest(path, expectedModelSchemaFiles, MODEL_SCHEMA_FOLDER) && - modelTest(path, expectedProducerFiles, API_FOLDER); + modelTest(path, expectedProducerFiles, API_FOLDER); } static Function validateNotGeneratedPropertiesIssue() { @@ -1043,14 +1043,14 @@ static Function validateNotGeneratedPropertiesIssue() { final String MODEL_SCHEMA_FOLDER = "generated/com/sngular/scsplugin/notgeneratedproperties/model"; final List expectedModelSchemaFiles = List.of( - "asyncapigenerator/v2/testPropertiesNotGeneratedIssue/assets/payload/UserDetails.java", - "asyncapigenerator/v2/testPropertiesNotGeneratedIssue/assets/payload/UserSignedUp.java" + "asyncapigenerator/v2/testPropertiesNotGeneratedIssue/assets/payload/UserDetails.java", + "asyncapigenerator/v2/testPropertiesNotGeneratedIssue/assets/payload/UserSignedUp.java" ); final List expectedProducerFiles = List.of(); return path -> modelTest(path, expectedModelSchemaFiles, MODEL_SCHEMA_FOLDER) && - modelTest(path, expectedProducerFiles, API_FOLDER); + modelTest(path, expectedProducerFiles, API_FOLDER); } static Function validateTestFileGenerationWithKafkaBindings() { @@ -1070,34 +1070,34 @@ static Function validateTestFileGenerationWithKafkaBindings() { final String CUSTOM_VALIDATOR_PATH = COMMON_PATH + "customvalidator/"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "consumer/IPublishOperationFileGenerationWithKafkaBindings.java", - ASSETS_PATH + "consumer/MessageWrapper.java", - ASSETS_PATH + "consumer/TestClassName.java"); + ASSETS_PATH + "consumer/IPublishOperationFileGenerationWithKafkaBindings.java", + ASSETS_PATH + "consumer/MessageWrapper.java", + ASSETS_PATH + "consumer/TestClassName.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "producer/ISubscribeOperationFileGenerationWithKafkaBindings.java", - ASSETS_PATH + "producer/MessageWrapper.java", - ASSETS_PATH + "producer/Producer.java"); + ASSETS_PATH + "producer/ISubscribeOperationFileGenerationWithKafkaBindings.java", + ASSETS_PATH + "producer/MessageWrapper.java", + ASSETS_PATH + "producer/Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "CreateOrderMapper.java", - ASSETS_PATH + "OrderDTO.java", - ASSETS_PATH + "OrderLineDTO.java", - ASSETS_PATH + "OrderLineMapper.java", - ASSETS_PATH + "OrderMapper.java", - ASSETS_PATH + "OrderProductDTO.java", - ASSETS_PATH + "OrderProductMapper.java", - ASSETS_PATH + "WaiterMapper.java" + ASSETS_PATH + "CreateOrderMapper.java", + ASSETS_PATH + "OrderDTO.java", + ASSETS_PATH + "OrderLineDTO.java", + ASSETS_PATH + "OrderLineMapper.java", + ASSETS_PATH + "OrderMapper.java", + ASSETS_PATH + "OrderProductDTO.java", + ASSETS_PATH + "OrderProductMapper.java", + ASSETS_PATH + "WaiterMapper.java" ); final List expectedValidatorFiles = List.of( - CUSTOM_VALIDATOR_PATH + "NotNull.java", - CUSTOM_VALIDATOR_PATH + "NotNullValidator.java" + CUSTOM_VALIDATOR_PATH + "NotNull.java", + CUSTOM_VALIDATOR_PATH + "NotNullValidator.java" ); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, Collections.emptyList(), null) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_COMMON_FOLDER) && - customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); + modelTest(path, expectedModelSchemaFiles, DEFAULT_COMMON_FOLDER) && + customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); } static Function validateTestSubObjectSameName() { @@ -1117,31 +1117,31 @@ static Function validateTestSubObjectSameName() { final String ASSETS_PATH = COMMON_PATH + "assets/"; final List expectedConsumerFiles = - List.of( - ASSETS_PATH + "input/controller/IInput.java", - ASSETS_PATH + "input/controller/Subscriber.java"); + List.of( + ASSETS_PATH + "input/controller/IInput.java", + ASSETS_PATH + "input/controller/Subscriber.java"); final List expectedProducerFiles = - List.of( - ASSETS_PATH + "output/provider/IOutput.java", - ASSETS_PATH + "output/provider/Producer.java"); + List.of( + ASSETS_PATH + "output/provider/IOutput.java", + ASSETS_PATH + "output/provider/Producer.java"); final List expectedConsumerModelSchemaFiles = - List.of(ASSETS_PATH + "input/model/Data.java", ASSETS_PATH + "input/model/Input.java"); + List.of(ASSETS_PATH + "input/model/Data.java", ASSETS_PATH + "input/model/Input.java"); final List expectedProducerModelSchemaFiles = - List.of(ASSETS_PATH + "output/model/Data.java", ASSETS_PATH + "output/model/Output.java"); + List.of(ASSETS_PATH + "output/model/Data.java", ASSETS_PATH + "output/model/Output.java"); return path -> - commonTest( - path, - expectedConsumerFiles, - expectedProducerFiles, - DEFAULT_CONSUMER_FOLDER, - DEFAULT_PRODUCER_FOLDER, - Collections.emptyList(), - null) - && modelTest(path, expectedConsumerModelSchemaFiles, DEFAULT_CONSUMER_MODEL_FOLDER) - && modelTest(path, expectedProducerModelSchemaFiles, DEFAULT_PRODUCER_MODEL_FOLDER); + commonTest( + path, + expectedConsumerFiles, + expectedProducerFiles, + DEFAULT_CONSUMER_FOLDER, + DEFAULT_PRODUCER_FOLDER, + Collections.emptyList(), + null) + && modelTest(path, expectedConsumerModelSchemaFiles, DEFAULT_CONSUMER_MODEL_FOLDER) + && modelTest(path, expectedProducerModelSchemaFiles, DEFAULT_PRODUCER_MODEL_FOLDER); } static Function validateTestReferenceFromLocalIssue() { diff --git a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v2/AsyncApiGeneratorJakartaTest.java b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v2/AsyncApiGeneratorJakartaTest.java index deddbc5f..7bb0f9e8 100644 --- a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v2/AsyncApiGeneratorJakartaTest.java +++ b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v2/AsyncApiGeneratorJakartaTest.java @@ -6,6 +6,12 @@ package com.sngular.api.generator.plugin.asyncapi.v2; +import java.io.File; +import java.nio.file.Path; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Stream; + import com.sngular.api.generator.plugin.asyncapi.AsyncApiGenerator; import com.sngular.api.generator.plugin.asyncapi.parameter.SpecFile; import org.assertj.core.api.Assertions; @@ -16,12 +22,6 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.io.File; -import java.nio.file.Path; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Stream; - class AsyncApiGeneratorJakartaTest { @TempDir(cleanup = CleanupMode.ON_SUCCESS) @@ -29,14 +29,14 @@ class AsyncApiGeneratorJakartaTest { private static AsyncApiGenerator asyncApiGenerator; - private static int SPRING_BOOT_VERSION = 3; + private static final int SPRING_BOOT_VERSION = 3; @BeforeAll static void setup() { asyncApiGenerator = new AsyncApiGenerator(SPRING_BOOT_VERSION, true, new File(baseDir.toAbsolutePath() + File.separator + AsyncApiGeneratorFixtures.TARGET), AsyncApiGeneratorFixtures.GENERATED, - "groupId", - baseDir.toFile()); + "groupId", + baseDir.toFile()); } static Stream fileSpecToProcess() { diff --git a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v2/AsyncApiGeneratorTest.java b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v2/AsyncApiGeneratorTest.java index b30971e4..de4affb4 100644 --- a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v2/AsyncApiGeneratorTest.java +++ b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v2/AsyncApiGeneratorTest.java @@ -6,6 +6,12 @@ package com.sngular.api.generator.plugin.asyncapi.v2; +import java.io.File; +import java.nio.file.Path; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Stream; + import com.sngular.api.generator.plugin.asyncapi.AsyncApiGenerator; import com.sngular.api.generator.plugin.asyncapi.exception.InvalidAvroException; import com.sngular.api.generator.plugin.asyncapi.parameter.SpecFile; @@ -20,22 +26,14 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.io.File; -import java.nio.file.Path; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Stream; - @Slf4j class AsyncApiGeneratorTest { + private static final int SPRING_BOOT_VERSION = 2; @TempDir(cleanup = CleanupMode.NEVER) static Path baseDir; - private static AsyncApiGenerator asyncApiGenerator; - private static final int SPRING_BOOT_VERSION = 2; - @BeforeAll static void setup() { asyncApiGenerator = @@ -44,7 +42,7 @@ static void setup() { new File(baseDir.toAbsolutePath() + File.separator + AsyncApiGeneratorFixtures.TARGET), AsyncApiGeneratorFixtures.GENERATED, "groupId", - Path.of("src","test","resources").toFile() + Path.of("src", "test", "resources").toFile() ); } @@ -56,33 +54,33 @@ static Stream fileSpecToProcess() { Arguments.of("TestRareCharsGeneration", AsyncApiGeneratorFixtures.TEST_RARE_CHARS_GENERATION, AsyncApiGeneratorFixtures.validateTestRareCharsGeneration()), Arguments.of("TestFileGenerationIssue", AsyncApiGeneratorFixtures.TEST_FILE_GENERATION_ISSUE, AsyncApiGeneratorFixtures.validateTestFileGenerationIssue()), Arguments.of("TestFileGenerationExternalAvro", AsyncApiGeneratorFixtures.TEST_FILE_GENERATION_EXTERNAL_AVRO, - AsyncApiGeneratorFixtures.validateTestFileGenerationExternalAvro()), + AsyncApiGeneratorFixtures.validateTestFileGenerationExternalAvro()), Arguments.of("TestFileGenerationStreamBridge", AsyncApiGeneratorFixtures.TEST_FILE_GENERATION_STREAM_BRIDGE, - AsyncApiGeneratorFixtures.validateTestFileGenerationStreamBridge()), + AsyncApiGeneratorFixtures.validateTestFileGenerationStreamBridge()), Arguments.of("TestFileGenerationWithoutIds", AsyncApiGeneratorFixtures.TEST_FILE_GENERATION_WITHOUT_OPERATION_IDS, - AsyncApiGeneratorFixtures.validateTestFileGenerationWithoutOperationIds()), + AsyncApiGeneratorFixtures.validateTestFileGenerationWithoutOperationIds()), Arguments.of("TestFileGenerationArrayString", AsyncApiGeneratorFixtures.TEST_FILE_GENERATION_WITH_ARRAY_STRING, - AsyncApiGeneratorFixtures.validateTestFileGenerationArrayString()), + AsyncApiGeneratorFixtures.validateTestFileGenerationArrayString()), Arguments.of("TestIssueGenerateSupplier", AsyncApiGeneratorFixtures.TEST_ISSUE_GENERATE_SUPPLIER, - AsyncApiGeneratorFixtures.validateTestIssueGenerateSupplier()), + AsyncApiGeneratorFixtures.validateTestIssueGenerateSupplier()), Arguments.of("TestIssueSimpleTypeGenerate", AsyncApiGeneratorFixtures.TEST_ISSUE_SIMPLE_TYPE_GENERATION, - AsyncApiGeneratorFixtures.validateTestIssueSimpleTypeGeneration()), + AsyncApiGeneratorFixtures.validateTestIssueSimpleTypeGeneration()), Arguments.of("TestIssueInfiniteLoop", AsyncApiGeneratorFixtures.TEST_ISSUE_INFINITE_LOOP, - AsyncApiGeneratorFixtures.validateTestIssueInfiniteLoop()), + AsyncApiGeneratorFixtures.validateTestIssueInfiniteLoop()), Arguments.of("TestCustomValidators", AsyncApiGeneratorFixtures.TEST_CUSTOM_VALIDATORS, AsyncApiGeneratorFixtures.validateCustomValidators(SPRING_BOOT_VERSION)), Arguments.of("TestModelClassExceptionGeneration", AsyncApiGeneratorFixtures.TEST_MODEL_CLASS_EXCEPTION_GENERATION, - AsyncApiGeneratorFixtures.validateTestModelClassExceptionGeneration()), + AsyncApiGeneratorFixtures.validateTestModelClassExceptionGeneration()), Arguments.of("TestNoSchemas", AsyncApiGeneratorFixtures.TEST_NO_SCHEMAS, AsyncApiGeneratorFixtures.validateNoSchemas()), Arguments.of("TestMessageNaming", AsyncApiGeneratorFixtures.TEST_MESSAGE_NAMING, AsyncApiGeneratorFixtures.validateMessageNaming()), Arguments.of("TestNestedObjectIssue", AsyncApiGeneratorFixtures.TEST_NESTED_OBJECT_ISSUE, AsyncApiGeneratorFixtures.validateNestedObject()), Arguments.of("TestConstantGeneration", AsyncApiGeneratorFixtures.TEST_CONSTANT_GENERATION, AsyncApiGeneratorFixtures.validateConstantGeneration()), Arguments.of("testPropertiesNotGeneratedIssue", AsyncApiGeneratorFixtures.PROPERTIES_NOT_GENERATED_ISSUE, AsyncApiGeneratorFixtures.validateNotGeneratedPropertiesIssue()), Arguments.of("TestFileGenerationWithKafkaBindings", AsyncApiGeneratorFixtures.TEST_FILE_GENERATION_WITH_KAFKA_BINDINGS, - AsyncApiGeneratorFixtures.validateTestFileGenerationWithKafkaBindings()), + AsyncApiGeneratorFixtures.validateTestFileGenerationWithKafkaBindings()), Arguments.of("TestSubObjectSameName", AsyncApiGeneratorFixtures.TEST_SUB_OBJECT_SAME_NAME, - AsyncApiGeneratorFixtures.validateTestSubObjectSameName()), + AsyncApiGeneratorFixtures.validateTestSubObjectSameName()), Arguments.of("TestReferenceFromLocalIssue", AsyncApiGeneratorFixtures.TEST_REFERENCE_FROM_LOCAL_ISSUE, - AsyncApiGeneratorFixtures.validateTestReferenceFromLocalIssue())); + AsyncApiGeneratorFixtures.validateTestReferenceFromLocalIssue())); } @ParameterizedTest(name = "Test {index} - Process File Spec for case {0}") diff --git a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v3/AsyncApiGeneratorFixtures.java b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v3/AsyncApiGeneratorFixtures.java index ca65b5cf..dbdbfb34 100644 --- a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v3/AsyncApiGeneratorFixtures.java +++ b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v3/AsyncApiGeneratorFixtures.java @@ -6,11 +6,7 @@ package com.sngular.api.generator.plugin.asyncapi.v3; -import com.sngular.api.generator.plugin.asyncapi.parameter.OperationParameterObject; -import com.sngular.api.generator.plugin.asyncapi.parameter.SpecFile; -import com.sngular.api.generator.test.utils.TestUtils; -import org.apache.commons.collections4.CollectionUtils; -import org.assertj.core.api.Assertions; +import static java.util.Collections.singletonList; import java.io.File; import java.net.URISyntaxException; @@ -19,412 +15,416 @@ import java.util.List; import java.util.function.Function; -import static java.util.Collections.singletonList; +import com.sngular.api.generator.plugin.asyncapi.parameter.OperationParameterObject; +import com.sngular.api.generator.plugin.asyncapi.parameter.SpecFile; +import com.sngular.api.generator.test.utils.TestUtils; +import org.apache.commons.collections4.CollectionUtils; +import org.assertj.core.api.Assertions; public class AsyncApiGeneratorFixtures { static final List TEST_FILE_GENERATION = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testFileGeneration/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("publishOperationFileGeneration") - .classNamePostfix("TestClassName") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.filegeneration.model.event.consumer") - .modelPackage("com.sngular.scsplugin.filegeneration.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("subscribeOperationFileGeneration") - .modelNameSuffix("Mapper") - .apiPackage("com.sngular.scsplugin.filegeneration.model.event.producer") - .modelPackage("com.sngular.scsplugin.filegeneration.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testFileGeneration/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("publishOperationFileGeneration") + .classNamePostfix("TestClassName") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.filegeneration.model.event.consumer") + .modelPackage("com.sngular.scsplugin.filegeneration.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("subscribeOperationFileGeneration") + .modelNameSuffix("Mapper") + .apiPackage("com.sngular.scsplugin.filegeneration.model.event.producer") + .modelPackage("com.sngular.scsplugin.filegeneration.model.event") + .build()) + .build() ); static final List TEST_FILE_GENERATION_NO_CONFIG = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testFileGenerationNoConfiguration/event-api.yml") - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testFileGenerationNoConfiguration/event-api.yml") + .build() ); static final List TEST_ISSUE_GENERATION = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testIssueGeneration/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("response") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.issuegeneration.model.event.consumer") - .modelPackage("com.sngular.scsplugin.issuegeneration.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("clients") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.issuegeneration.model.event.producer") - .modelPackage("com.sngular.scsplugin.issuegeneration.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testIssueGeneration/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("response") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.issuegeneration.model.event.consumer") + .modelPackage("com.sngular.scsplugin.issuegeneration.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("clients") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.issuegeneration.model.event.producer") + .modelPackage("com.sngular.scsplugin.issuegeneration.model.event") + .build()) + .build() ); static final List TEST_ISSUE_SIMPLE_TYPE_GENERATION = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testIssueSimpleTypeGeneration/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("response") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.issuesimpletypegeneration.model.event.consumer") - .modelPackage("com.sngular.scsplugin.issuesimpletypegeneration.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("clients") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.issuesimpletypegeneration.model.event.producer") - .modelPackage("com.sngular.scsplugin.issuesimpletypegeneration.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testIssueSimpleTypeGeneration/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("response") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.issuesimpletypegeneration.model.event.consumer") + .modelPackage("com.sngular.scsplugin.issuesimpletypegeneration.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("clients") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.issuesimpletypegeneration.model.event.producer") + .modelPackage("com.sngular.scsplugin.issuesimpletypegeneration.model.event") + .build()) + .build() ); static final List TEST_RESERVED_WORDS_GENERATION = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testReservedWordsGeneration/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("subscribeOperationFileGeneration") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.reservedwordsgeneration.model.event.consumer") - .modelPackage("com.sngular.scsplugin.reservedwordsgeneration.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("publishOperationFileGeneration") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.reservedwordsgeneration.model.event.producer") - .modelPackage("com.sngular.scsplugin.reservedwordsgeneration.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testReservedWordsGeneration/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("subscribeOperationFileGeneration") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.reservedwordsgeneration.model.event.consumer") + .modelPackage("com.sngular.scsplugin.reservedwordsgeneration.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("publishOperationFileGeneration") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.reservedwordsgeneration.model.event.producer") + .modelPackage("com.sngular.scsplugin.reservedwordsgeneration.model.event") + .build()) + .build() ); static final List TEST_RARE_CHARS_GENERATION = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testRareCharsGeneration/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("subscribeOperationFileGeneration") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.rarecharsgeneration.model.event.consumer") - .modelPackage("com.sngular.scsplugin.rarecharsgeneration.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("publishOperationFileGeneration") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.rarecharsgeneration.model.event.producer") - .modelPackage("com.sngular.scsplugin.rarecharsgeneration.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testRareCharsGeneration/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("subscribeOperationFileGeneration") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.rarecharsgeneration.model.event.consumer") + .modelPackage("com.sngular.scsplugin.rarecharsgeneration.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("publishOperationFileGeneration") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.rarecharsgeneration.model.event.producer") + .modelPackage("com.sngular.scsplugin.rarecharsgeneration.model.event") + .build()) + .build() ); static final List TEST_CUSTOM_VALIDATORS = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testCustomValidators/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("customValidatorResponse") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.customvalidator.model.event.consumer") - .modelPackage("com.sngular.scsplugin.customvalidator.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("customValidatorClients") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.customvalidator.model.event.producer") - .modelPackage("com.sngular.scsplugin.customvalidator.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testCustomValidators/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("customValidatorResponse") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.customvalidator.model.event.consumer") + .modelPackage("com.sngular.scsplugin.customvalidator.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("customValidatorClients") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.customvalidator.model.event.producer") + .modelPackage("com.sngular.scsplugin.customvalidator.model.event") + .build()) + .build() ); static final List TEST_FILE_GENERATION_ISSUE = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testFileGenerationIssue/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("onCustomerEvent") - .classNamePostfix("TestClassName") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.filegenerationissue.model.event.consumer") - .modelPackage("com.sngular.scsplugin.filegenerationissue.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("onCustomerOrderEvent") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.filegenerationissue.model.event.producer") - .modelPackage("com.sngular.scsplugin.filegenerationissue.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testFileGenerationIssue/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("onCustomerEvent") + .classNamePostfix("TestClassName") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.filegenerationissue.model.event.consumer") + .modelPackage("com.sngular.scsplugin.filegenerationissue.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("onCustomerOrderEvent") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.filegenerationissue.model.event.producer") + .modelPackage("com.sngular.scsplugin.filegenerationissue.model.event") + .build()) + .build() ); static final List TEST_FILE_GENERATION_EXTERNAL_AVRO = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testFileGenerationExternalAvro/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("subscribeOperationExternalAvro,subscribeReceiptExternalAvro") - .apiPackage("com.sngular.scsplugin.externalavro.model.event.consumer") - .modelPackage("com.sngular.scsplugin.externalavro.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("publishOperationExternalAvro") - .apiPackage("com.sngular.scsplugin.externalavro.model.event.producer") - .modelPackage("com.sngular.scsplugin.externalavro.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testFileGenerationExternalAvro/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("subscribeOperationExternalAvro,subscribeReceiptExternalAvro") + .apiPackage("com.sngular.scsplugin.externalavro.model.event.consumer") + .modelPackage("com.sngular.scsplugin.externalavro.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("publishOperationExternalAvro") + .apiPackage("com.sngular.scsplugin.externalavro.model.event.producer") + .modelPackage("com.sngular.scsplugin.externalavro.model.event") + .build()) + .build() ); static final List TEST_ISSUE_INVALID_AVRO = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testIssueInvalidAvro/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("subscribeOperationExternalAvro") - .apiPackage("com.sngular.scsplugin.issueAvro.model.event.consumer") - .modelPackage("com.sngular.scsplugin.issueAvro.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("publishOperationExternalAvro") - .apiPackage("com.sngular.scsplugin.issueAvro.model.event.producer") - .modelPackage("com.sngular.scsplugin.issueAvro.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testIssueInvalidAvro/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("subscribeOperationExternalAvro") + .apiPackage("com.sngular.scsplugin.issueAvro.model.event.consumer") + .modelPackage("com.sngular.scsplugin.issueAvro.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("publishOperationExternalAvro") + .apiPackage("com.sngular.scsplugin.issueAvro.model.event.producer") + .modelPackage("com.sngular.scsplugin.issueAvro.model.event") + .build()) + .build() ); static final List TEST_FILE_GENERATION_STREAM_BRIDGE = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testFileGenerationStreamBridge/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("subscribeOperationStreamBridge") - .classNamePostfix("TestClassName") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.streambridge.model.event.consumer") - .modelPackage("com.sngular.scsplugin.streambridge.model.event") - .build()) - .streamBridge(OperationParameterObject.builder() - .ids("publishOperationStreamBridge") - .apiPackage("com.sngular.scsplugin.streambridge.model.event.producer") - .modelPackage("com.sngular.scsplugin.streambridge.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testFileGenerationStreamBridge/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("subscribeOperationStreamBridge") + .classNamePostfix("TestClassName") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.streambridge.model.event.consumer") + .modelPackage("com.sngular.scsplugin.streambridge.model.event") + .build()) + .streamBridge(OperationParameterObject.builder() + .ids("publishOperationStreamBridge") + .apiPackage("com.sngular.scsplugin.streambridge.model.event.producer") + .modelPackage("com.sngular.scsplugin.streambridge.model.event") + .build()) + .build() ); static final List TEST_FILE_GENERATION_WITHOUT_IDS = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testFileGenerationWithoutOperationIds/event-api.yml") - .consumer(OperationParameterObject.builder() - .classNamePostfix("TestClassName") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.withoutids.model.event.consumer") - .modelPackage("com.sngular.scsplugin.withoutids.model.event") - .build()) - .streamBridge(OperationParameterObject.builder() - .apiPackage("com.sngular.scsplugin.withoutids.model.event.producer") - .modelPackage("com.sngular.scsplugin.withoutids.model.event") - .modelNameSuffix("DTO") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testFileGenerationWithoutOperationIds/event-api.yml") + .consumer(OperationParameterObject.builder() + .classNamePostfix("TestClassName") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.withoutids.model.event.consumer") + .modelPackage("com.sngular.scsplugin.withoutids.model.event") + .build()) + .streamBridge(OperationParameterObject.builder() + .apiPackage("com.sngular.scsplugin.withoutids.model.event.producer") + .modelPackage("com.sngular.scsplugin.withoutids.model.event") + .modelNameSuffix("DTO") + .build()) + .build() ); static final List TEST_FILE_GENERATION_WITH_ARRAY_STRING = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testFileGenerationArrayString/event-api.yml") - .supplier(OperationParameterObject.builder() - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.arraywithstring.model.event.producer") - .modelPackage("com.sngular.scsplugin.arraywithstring.model.event") - .useLombokModelAnnotation(true) - .build()) - .build()); + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testFileGenerationArrayString/event-api.yml") + .supplier(OperationParameterObject.builder() + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.arraywithstring.model.event.producer") + .modelPackage("com.sngular.scsplugin.arraywithstring.model.event") + .useLombokModelAnnotation(true) + .build()) + .build()); static final List TEST_ISSUE_GENERATE_SUPPLIER = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testIssueGenerateSupplier/event-api.yml") - .supplier(OperationParameterObject.builder() - .modelNameSuffix("DTO") - .apiPackage("company.mail.messaging") - .modelPackage("company.mail.model") - .useLombokModelAnnotation(true) - .build()) - .build()); + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testIssueGenerateSupplier/event-api.yml") + .supplier(OperationParameterObject.builder() + .modelNameSuffix("DTO") + .apiPackage("company.mail.messaging") + .modelPackage("company.mail.model") + .useLombokModelAnnotation(true) + .build()) + .build()); static final List TEST_ISSUE_INFINITE_LOOP = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testIssueInfiniteLoop/event-api.yml") - .supplier(OperationParameterObject.builder() - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.infiniteLoop.messaging") - .modelPackage("com.sngular.scsplugin.infiniteLoop.model") - .useLombokModelAnnotation(true) - .build()) - .build()); + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testIssueInfiniteLoop/event-api.yml") + .supplier(OperationParameterObject.builder() + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.infiniteLoop.messaging") + .modelPackage("com.sngular.scsplugin.infiniteLoop.model") + .useLombokModelAnnotation(true) + .build()) + .build()); static final List TEST_MODEL_CLASS_EXCEPTION_GENERATION = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testModelClassExceptionGeneration/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("subscribeOrder") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.modelclass.model.event.consumer") - .modelPackage("com.sngular.scsplugin.modelclass.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("publishOrder") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.modelclass.model.event.producer") - .modelPackage("com.sngular.scsplugin.modelclass.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testModelClassExceptionGeneration/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("subscribeOrder") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.modelclass.model.event.consumer") + .modelPackage("com.sngular.scsplugin.modelclass.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("publishOrder") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.modelclass.model.event.producer") + .modelPackage("com.sngular.scsplugin.modelclass.model.event") + .build()) + .build() ); static final List TEST_GENERATION_WITH_NO_OPERATION_ID = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testGenerationWithNoOperationId/event-api.yml") - .consumer(OperationParameterObject.builder() - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.withoutoperationid.model.event.consumer") - .modelPackage("com.sngular.scsplugin.withoutoperationid.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testGenerationWithNoOperationId/event-api.yml") + .consumer(OperationParameterObject.builder() + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.withoutoperationid.model.event.consumer") + .modelPackage("com.sngular.scsplugin.withoutoperationid.model.event") + .build()) + .build() ); static final List TEST_NO_SCHEMAS = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testNoSchemas/event-api.yml") - .supplier(OperationParameterObject.builder() - .modelNameSuffix("") - .apiPackage("com.sngular.scsplugin.noschemas") - .modelPackage("com.sngular.scsplugin.noschemas.model") - .useLombokModelAnnotation(true) - .build()) - .build()); + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testNoSchemas/event-api.yml") + .supplier(OperationParameterObject.builder() + .modelNameSuffix("") + .apiPackage("com.sngular.scsplugin.noschemas") + .modelPackage("com.sngular.scsplugin.noschemas.model") + .useLombokModelAnnotation(true) + .build()) + .build()); static final List TEST_MESSAGE_NAMING = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testMessageNaming/event-api.yml") - .supplier(OperationParameterObject.builder() - .modelNameSuffix("") - .apiPackage("com.sngular.scsplugin.messagenaming") - .modelPackage("com.sngular.scsplugin.messagenaming.model") - .useLombokModelAnnotation(true) - .build()) - .build()); + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testMessageNaming/event-api.yml") + .supplier(OperationParameterObject.builder() + .modelNameSuffix("") + .apiPackage("com.sngular.scsplugin.messagenaming") + .modelPackage("com.sngular.scsplugin.messagenaming.model") + .useLombokModelAnnotation(true) + .build()) + .build()); static final List TEST_NESTED_OBJECT = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testNestedObjectIssue/event-api.yml") - .consumer(OperationParameterObject.builder() - .modelNameSuffix("") - .apiPackage("com.sngular.scsplugin.nestedobject.consumer") - .modelPackage("com.sngular.scsplugin.nestedobject.model") - .useLombokModelAnnotation(true) - .build()) - .supplier(OperationParameterObject.builder() - .modelNameSuffix("") - .apiPackage("com.sngular.scsplugin.nestedobject.producer") - .modelPackage("com.sngular.scsplugin.nestedobject.model") - .useLombokModelAnnotation(true) - .build()) - .build()); + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testNestedObjectIssue/event-api.yml") + .consumer(OperationParameterObject.builder() + .modelNameSuffix("") + .apiPackage("com.sngular.scsplugin.nestedobject.consumer") + .modelPackage("com.sngular.scsplugin.nestedobject.model") + .useLombokModelAnnotation(true) + .build()) + .supplier(OperationParameterObject.builder() + .modelNameSuffix("") + .apiPackage("com.sngular.scsplugin.nestedobject.producer") + .modelPackage("com.sngular.scsplugin.nestedobject.model") + .useLombokModelAnnotation(true) + .build()) + .build()); static final List TEST_CONSTANT_GENERATION = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testConstantGeneration/event-api.yml") - .consumer(OperationParameterObject.builder() - .modelNameSuffix("") - .apiPackage("com.sngular.scsplugin.constantgeneration.consumer") - .modelPackage("com.sngular.scsplugin.constantgeneration.model") - .useLombokModelAnnotation(true) - .build()) - .supplier(OperationParameterObject.builder() - .modelNameSuffix("") - .apiPackage("com.sngular.scsplugin.constantgeneration.producer") - .modelPackage("com.sngular.scsplugin.constantgeneration.model") - .useLombokModelAnnotation(true) - .build()) - .build()); + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testConstantGeneration/event-api.yml") + .consumer(OperationParameterObject.builder() + .modelNameSuffix("") + .apiPackage("com.sngular.scsplugin.constantgeneration.consumer") + .modelPackage("com.sngular.scsplugin.constantgeneration.model") + .useLombokModelAnnotation(true) + .build()) + .supplier(OperationParameterObject.builder() + .modelNameSuffix("") + .apiPackage("com.sngular.scsplugin.constantgeneration.producer") + .modelPackage("com.sngular.scsplugin.constantgeneration.model") + .useLombokModelAnnotation(true) + .build()) + .build()); static final List PROPERTIES_NOT_GENERATED_ISSUE = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testPropertiesNotGeneratedIssue/event-api.yml") - .consumer(OperationParameterObject.builder() - .modelNameSuffix("") - .operationIds(List.of("emitUserSignUpEvent")) - .apiPackage("com.sngular.scsplugin.notgeneratedproperties.consumer") - .modelPackage("com.sngular.scsplugin.notgeneratedproperties.model") - .useLombokModelAnnotation(true) - .build()) - .build()); + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testPropertiesNotGeneratedIssue/event-api.yml") + .consumer(OperationParameterObject.builder() + .modelNameSuffix("") + .operationIds(List.of("emitUserSignUpEvent")) + .apiPackage("com.sngular.scsplugin.notgeneratedproperties.consumer") + .modelPackage("com.sngular.scsplugin.notgeneratedproperties.model") + .useLombokModelAnnotation(true) + .build()) + .build()); static final List TEST_FILE_GENERATION_WITH_KAFKA_BINDINGS = List.of( - SpecFile - .builder() - .filePath("asyncapigenerator/v3/testFileGenerationWithKafkaBindings/event-api.yml") - .consumer(OperationParameterObject.builder() - .ids("publishOperationFileGenerationWithKafkaBindings") - .classNamePostfix("TestClassName") - .modelNameSuffix("DTO") - .apiPackage("com.sngular.scsplugin.filegenerationwithkafkabindings.model.event.consumer") - .modelPackage("com.sngular.scsplugin.filegenerationwithkafkabindings.model.event") - .build()) - .supplier(OperationParameterObject.builder() - .ids("subscribeOperationFileGenerationWithKafkaBindings") - .modelNameSuffix("Mapper") - .apiPackage("com.sngular.scsplugin.filegenerationwithkafkabindings.model.event.producer") - .modelPackage("com.sngular.scsplugin.filegenerationwithkafkabindings.model.event") - .build()) - .build() + SpecFile + .builder() + .filePath("asyncapigenerator/v3/testFileGenerationWithKafkaBindings/event-api.yml") + .consumer(OperationParameterObject.builder() + .ids("publishOperationFileGenerationWithKafkaBindings") + .classNamePostfix("TestClassName") + .modelNameSuffix("DTO") + .apiPackage("com.sngular.scsplugin.filegenerationwithkafkabindings.model.event.consumer") + .modelPackage("com.sngular.scsplugin.filegenerationwithkafkabindings.model.event") + .build()) + .supplier(OperationParameterObject.builder() + .ids("subscribeOperationFileGenerationWithKafkaBindings") + .modelNameSuffix("Mapper") + .apiPackage("com.sngular.scsplugin.filegenerationwithkafkabindings.model.event.producer") + .modelPackage("com.sngular.scsplugin.filegenerationwithkafkabindings.model.event") + .build()) + .build() ); static final List TEST_SUB_OBJECT_SAME_NAME = - List.of( - SpecFile.builder() - .filePath("asyncapigenerator/v3/testSubObjectSameName/event-api.yml") - .consumer( - OperationParameterObject.builder() - .ids("input") - .apiPackage("input.controller") - .modelPackage("input.model") - .build()) - .supplier( - OperationParameterObject.builder() - .ids("output") - .apiPackage("output.provider") - .modelPackage("output.model") - .build()) - .build()); + List.of( + SpecFile.builder() + .filePath("asyncapigenerator/v3/testSubObjectSameName/event-api.yml") + .consumer( + OperationParameterObject.builder() + .ids("input") + .apiPackage("input.controller") + .modelPackage("input.model") + .build()) + .supplier( + OperationParameterObject.builder() + .ids("output") + .apiPackage("output.provider") + .modelPackage("output.model") + .build()) + .build()); static final List TEST_REFERENCE_FROM_LOCAL_ISSUE = - List.of( - SpecFile.builder() - .filePath("asyncapigenerator/v3/testReferenceFromLocalIssue/event-api.yml") - .consumer( - OperationParameterObject.builder() - .ids("userSignedUp") - .apiPackage("com.github.issue.listener") - .modelPackage("com.github.issue.model") - .build()) - .build()); + List.of( + SpecFile.builder() + .filePath("asyncapigenerator/v3/testReferenceFromLocalIssue/event-api.yml") + .consumer( + OperationParameterObject.builder() + .ids("userSignedUp") + .apiPackage("com.github.issue.listener") + .modelPackage("com.github.issue.model") + .build()) + .build()); static final String TARGET = "target"; @@ -449,41 +449,41 @@ static Function validateTestFileGeneration() { final String DEFAULT_EXCEPTION_API = DEFAULT_COMMON_FOLDER + "/exception"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "IPublishOperationFileGeneration.java", - ASSETS_PATH + "TestClassName.java"); + ASSETS_PATH + "IPublishOperationFileGeneration.java", + ASSETS_PATH + "TestClassName.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "ISubscribeOperationFileGeneration.java", - ASSETS_PATH + "Producer.java"); + ASSETS_PATH + "ISubscribeOperationFileGeneration.java", + ASSETS_PATH + "Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "CreateOrderMapper.java", - ASSETS_PATH + "OrderDTO.java", - ASSETS_PATH + "OrderLineDTO.java", - ASSETS_PATH + "OrderLineMapper.java", - ASSETS_PATH + "OrderMapper.java", - ASSETS_PATH + "OrderProductDTO.java", - ASSETS_PATH + "OrderProductMapper.java", - ASSETS_PATH + "WaiterMapper.java" + ASSETS_PATH + "CreateOrderMapper.java", + ASSETS_PATH + "OrderDTO.java", + ASSETS_PATH + "OrderLineDTO.java", + ASSETS_PATH + "OrderLineMapper.java", + ASSETS_PATH + "OrderMapper.java", + ASSETS_PATH + "OrderProductDTO.java", + ASSETS_PATH + "OrderProductMapper.java", + ASSETS_PATH + "WaiterMapper.java" ); final List expectedValidatorFiles = List.of( - CUSTOM_VALIDATOR_PATH + "NotNull.java", - CUSTOM_VALIDATOR_PATH + "NotNullValidator.java" + CUSTOM_VALIDATOR_PATH + "NotNull.java", + CUSTOM_VALIDATOR_PATH + "NotNullValidator.java" ); final List expectedExceptionFiles = List.of( - ASSETS_PATH + "ModelClassException.java"); + ASSETS_PATH + "ModelClassException.java"); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - expectedExceptionFiles, DEFAULT_EXCEPTION_API) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_COMMON_FOLDER) && - customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); + expectedExceptionFiles, DEFAULT_EXCEPTION_API) && + modelTest(path, expectedModelSchemaFiles, DEFAULT_COMMON_FOLDER) && + customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); } private static Boolean commonTest( - final Path resultPath, final List expectedFile, final List expectedModelFiles, final String targetConsumer, - final String targetProducer, final List expectedExceptionFiles, final String targetException) { + final Path resultPath, final List expectedFile, final List expectedModelFiles, final String targetConsumer, + final String targetProducer, final List expectedExceptionFiles, final String targetException) { Boolean result = Boolean.TRUE; try { final Path pathToTarget = Path.of(resultPath.toString(), "target"); @@ -558,21 +558,21 @@ static Function validateTestIssueGeneration() { final String ASSETS_PATH = COMMON_PATH + "assets/"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "IResponse.java", - ASSETS_PATH + "Subscriber.java"); + ASSETS_PATH + "IResponse.java", + ASSETS_PATH + "Subscriber.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "IClients.java", - ASSETS_PATH + "Producer.java"); + ASSETS_PATH + "IClients.java", + ASSETS_PATH + "Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "DataDTO.java", - ASSETS_PATH + "StatusMsgDTO.java" + ASSETS_PATH + "DataDTO.java", + ASSETS_PATH + "StatusMsgDTO.java" ); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - Collections.emptyList(), null) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); + Collections.emptyList(), null) && + modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); } static Function validateTestIssueSimpleTypeGeneration() { @@ -587,21 +587,21 @@ static Function validateTestIssueSimpleTypeGeneration() { final String ASSETS_PATH = COMMON_PATH + "assets/"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "IResponse.java", - ASSETS_PATH + "Subscriber.java"); + ASSETS_PATH + "IResponse.java", + ASSETS_PATH + "Subscriber.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "IClients.java", - ASSETS_PATH + "Producer.java"); + ASSETS_PATH + "IClients.java", + ASSETS_PATH + "Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "DataDTO.java", - ASSETS_PATH + "StatusMsgDTO.java" + ASSETS_PATH + "DataDTO.java", + ASSETS_PATH + "StatusMsgDTO.java" ); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - Collections.emptyList(), null) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); + Collections.emptyList(), null) && + modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); } static Function validateTestReservedWordsGeneration() { @@ -616,22 +616,22 @@ static Function validateTestReservedWordsGeneration() { final String ASSETS_PATH = COMMON_PATH + "assets/"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "ISubscribeOperationFileGeneration.java", - ASSETS_PATH + "Subscriber.java"); + ASSETS_PATH + "ISubscribeOperationFileGeneration.java", + ASSETS_PATH + "Subscriber.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "IPublishOperationFileGeneration.java", - ASSETS_PATH + "Producer.java"); + ASSETS_PATH + "IPublishOperationFileGeneration.java", + ASSETS_PATH + "Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "CreateOrderDTO.java", - ASSETS_PATH + "OrderDTO.java", - ASSETS_PATH + "OrderLineDTO.java", - ASSETS_PATH + "WaiterDTO.java" + ASSETS_PATH + "CreateOrderDTO.java", + ASSETS_PATH + "OrderDTO.java", + ASSETS_PATH + "OrderLineDTO.java", + ASSETS_PATH + "WaiterDTO.java" ); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, Collections.emptyList(), null) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); + modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); } static Function validateTestRareCharsGeneration() { @@ -646,21 +646,21 @@ static Function validateTestRareCharsGeneration() { final String ASSETS_PATH = COMMON_PATH + "assets/"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "ISubscribeOperationFileGeneration.java", - ASSETS_PATH + "Subscriber.java"); + ASSETS_PATH + "ISubscribeOperationFileGeneration.java", + ASSETS_PATH + "Subscriber.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "IPublishOperationFileGeneration.java", - ASSETS_PATH + "Producer.java"); + ASSETS_PATH + "IPublishOperationFileGeneration.java", + ASSETS_PATH + "Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "CreateOrderDTO.java", - ASSETS_PATH + "OrderDTO.java", - ASSETS_PATH + "WaiterDTO.java" + ASSETS_PATH + "CreateOrderDTO.java", + ASSETS_PATH + "OrderDTO.java", + ASSETS_PATH + "WaiterDTO.java" ); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, Collections.emptyList(), null) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); + modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); } static Function validateCustomValidators(final int springBootVersion) { @@ -681,58 +681,58 @@ static Function validateCustomValidators(final int springBootVers final String DEFAULT_EXCEPTION_API = DEFAULT_MODEL_SCHEMA_FOLDER + "/exception"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "ICustomValidatorResponse.java", - ASSETS_PATH + "Subscriber.java"); + ASSETS_PATH + "ICustomValidatorResponse.java", + ASSETS_PATH + "Subscriber.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "ICustomValidatorClients.java", - ASSETS_PATH + "Producer.java"); + ASSETS_PATH + "ICustomValidatorClients.java", + ASSETS_PATH + "Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "DataDTO.java", - ASSETS_PATH + "StatusMsgDTO.java" + ASSETS_PATH + "DataDTO.java", + ASSETS_PATH + "StatusMsgDTO.java" ); final List expectedValidatorFiles = List.of( - CUSTOM_VALIDATOR_PATH + "MaxBigDecimal.java", - CUSTOM_VALIDATOR_PATH + "MaxBigDecimalValidator.java", - CUSTOM_VALIDATOR_PATH + "MaxDouble.java", - CUSTOM_VALIDATOR_PATH + "MaxDoubleValidator.java", - CUSTOM_VALIDATOR_PATH + "MaxFloat.java", - CUSTOM_VALIDATOR_PATH + "MaxFloatValidator.java", - CUSTOM_VALIDATOR_PATH + "MaxInteger.java", - CUSTOM_VALIDATOR_PATH + "MaxIntegerValidator.java", - CUSTOM_VALIDATOR_PATH + "MaxItems.java", - CUSTOM_VALIDATOR_PATH + "MaxItemsValidator.java", - CUSTOM_VALIDATOR_PATH + "MinBigDecimal.java", - CUSTOM_VALIDATOR_PATH + "MinBigDecimalValidator.java", - CUSTOM_VALIDATOR_PATH + "MinDouble.java", - CUSTOM_VALIDATOR_PATH + "MinDoubleValidator.java", - CUSTOM_VALIDATOR_PATH + "MinFloat.java", - CUSTOM_VALIDATOR_PATH + "MinFloatValidator.java", - CUSTOM_VALIDATOR_PATH + "MinInteger.java", - CUSTOM_VALIDATOR_PATH + "MinIntegerValidator.java", - CUSTOM_VALIDATOR_PATH + "MinItems.java", - CUSTOM_VALIDATOR_PATH + "MinItemsValidator.java", - CUSTOM_VALIDATOR_PATH + "MultipleOf.java", - CUSTOM_VALIDATOR_PATH + "MultipleOfValidator.java", - CUSTOM_VALIDATOR_PATH + "NotNull.java", - CUSTOM_VALIDATOR_PATH + "NotNullValidator.java", - CUSTOM_VALIDATOR_PATH + "Pattern.java", - CUSTOM_VALIDATOR_PATH + "PatternValidator.java", - CUSTOM_VALIDATOR_PATH + "Size.java", - CUSTOM_VALIDATOR_PATH + "SizeValidator.java", - CUSTOM_VALIDATOR_PATH + "UniqueItems.java", - CUSTOM_VALIDATOR_PATH + "UniqueItemsValidator.java" + CUSTOM_VALIDATOR_PATH + "MaxBigDecimal.java", + CUSTOM_VALIDATOR_PATH + "MaxBigDecimalValidator.java", + CUSTOM_VALIDATOR_PATH + "MaxDouble.java", + CUSTOM_VALIDATOR_PATH + "MaxDoubleValidator.java", + CUSTOM_VALIDATOR_PATH + "MaxFloat.java", + CUSTOM_VALIDATOR_PATH + "MaxFloatValidator.java", + CUSTOM_VALIDATOR_PATH + "MaxInteger.java", + CUSTOM_VALIDATOR_PATH + "MaxIntegerValidator.java", + CUSTOM_VALIDATOR_PATH + "MaxItems.java", + CUSTOM_VALIDATOR_PATH + "MaxItemsValidator.java", + CUSTOM_VALIDATOR_PATH + "MinBigDecimal.java", + CUSTOM_VALIDATOR_PATH + "MinBigDecimalValidator.java", + CUSTOM_VALIDATOR_PATH + "MinDouble.java", + CUSTOM_VALIDATOR_PATH + "MinDoubleValidator.java", + CUSTOM_VALIDATOR_PATH + "MinFloat.java", + CUSTOM_VALIDATOR_PATH + "MinFloatValidator.java", + CUSTOM_VALIDATOR_PATH + "MinInteger.java", + CUSTOM_VALIDATOR_PATH + "MinIntegerValidator.java", + CUSTOM_VALIDATOR_PATH + "MinItems.java", + CUSTOM_VALIDATOR_PATH + "MinItemsValidator.java", + CUSTOM_VALIDATOR_PATH + "MultipleOf.java", + CUSTOM_VALIDATOR_PATH + "MultipleOfValidator.java", + CUSTOM_VALIDATOR_PATH + "NotNull.java", + CUSTOM_VALIDATOR_PATH + "NotNullValidator.java", + CUSTOM_VALIDATOR_PATH + "Pattern.java", + CUSTOM_VALIDATOR_PATH + "PatternValidator.java", + CUSTOM_VALIDATOR_PATH + "Size.java", + CUSTOM_VALIDATOR_PATH + "SizeValidator.java", + CUSTOM_VALIDATOR_PATH + "UniqueItems.java", + CUSTOM_VALIDATOR_PATH + "UniqueItemsValidator.java" ); final List expectedExceptionFiles = List.of( - ASSETS_PATH + "ModelClassException.java"); + ASSETS_PATH + "ModelClassException.java"); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - expectedExceptionFiles, DEFAULT_EXCEPTION_API) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER) && - customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); + expectedExceptionFiles, DEFAULT_EXCEPTION_API) && + modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER) && + customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); } private static String calculateJavaEEPackage(final int springBootVersion) { @@ -762,37 +762,37 @@ static Function validateTestFileGenerationIssue() { final String DEFAULT_EXCEPTION_API = DEFAULT_COMMON_FOLDER + "/exception"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "IOnCustomerEvent.java", - ASSETS_PATH + "TestClassName.java"); + ASSETS_PATH + "IOnCustomerEvent.java", + ASSETS_PATH + "TestClassName.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "IOnCustomerOrderEvent.java", - ASSETS_PATH + "Producer.java"); + ASSETS_PATH + "IOnCustomerOrderEvent.java", + ASSETS_PATH + "Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "CustomerDTO.java", - ASSETS_PATH + "CustomerEventPayloadDTO.java", - ASSETS_PATH + "CustomerOrderDTO.java", - ASSETS_PATH + "CustomerOrderEventPayloadDTO.java", - ASSETS_PATH + "OrderedItemDTO.java", - ASSETS_PATH + "PaymentDetailsDTO.java", - ASSETS_PATH + "ShippingDetailsDTO.java" + ASSETS_PATH + "CustomerDTO.java", + ASSETS_PATH + "CustomerEventPayloadDTO.java", + ASSETS_PATH + "CustomerOrderDTO.java", + ASSETS_PATH + "CustomerOrderEventPayloadDTO.java", + ASSETS_PATH + "OrderedItemDTO.java", + ASSETS_PATH + "PaymentDetailsDTO.java", + ASSETS_PATH + "ShippingDetailsDTO.java" ); final List expectedValidatorFiles = List.of( - CUSTOM_VALIDATOR_PATH + "NotNull.java", - CUSTOM_VALIDATOR_PATH + "NotNullValidator.java", - CUSTOM_VALIDATOR_PATH + "Size.java", - CUSTOM_VALIDATOR_PATH + "SizeValidator.java" + CUSTOM_VALIDATOR_PATH + "NotNull.java", + CUSTOM_VALIDATOR_PATH + "NotNullValidator.java", + CUSTOM_VALIDATOR_PATH + "Size.java", + CUSTOM_VALIDATOR_PATH + "SizeValidator.java" ); final List expectedExceptionFiles = List.of( - ASSETS_PATH + "ModelClassException.java"); + ASSETS_PATH + "ModelClassException.java"); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - expectedExceptionFiles, DEFAULT_EXCEPTION_API) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_COMMON_FOLDER) && - customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); + expectedExceptionFiles, DEFAULT_EXCEPTION_API) && + modelTest(path, expectedModelSchemaFiles, DEFAULT_COMMON_FOLDER) && + customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); } static Function validateTestFileGenerationExternalAvro() { @@ -805,18 +805,18 @@ static Function validateTestFileGenerationExternalAvro() { final String ASSETS_PATH = COMMON_PATH + "assets/"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "ISubscribeOperationExternalAvro.java", - ASSETS_PATH + "ISubscribeReceiptExternalAvro.java", - ASSETS_PATH + "Subscriber.java" + ASSETS_PATH + "ISubscribeOperationExternalAvro.java", + ASSETS_PATH + "ISubscribeReceiptExternalAvro.java", + ASSETS_PATH + "Subscriber.java" ); final List expectedProducerFiles = List.of( - ASSETS_PATH + "IPublishOperation.java", - ASSETS_PATH + "Producer.java" + ASSETS_PATH + "IPublishOperation.java", + ASSETS_PATH + "Producer.java" ); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - Collections.emptyList(), null); + Collections.emptyList(), null); } static Function validateTestFileGenerationStreamBridge() { @@ -834,19 +834,19 @@ static Function validateTestFileGenerationStreamBridge() { final String DEFAULT_EXCEPTION_API = DEFAULT_COMMON_FOLDER + "/exception"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "consumer/" + "ISubscribeOperationStreamBridge.java", - ASSETS_PATH + "consumer/" + "TestClassName.java" + ASSETS_PATH + "consumer/" + "ISubscribeOperationStreamBridge.java", + ASSETS_PATH + "consumer/" + "TestClassName.java" ); final List expectedProducerFiles = List.of( - ASSETS_PATH + "producer/" + "StreamBridgeProducer.java" + ASSETS_PATH + "producer/" + "StreamBridgeProducer.java" ); final List expectedExceptionFiles = List.of( - ASSETS_PATH + "exception/" + "ModelClassException.java"); + ASSETS_PATH + "exception/" + "ModelClassException.java"); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - expectedExceptionFiles, DEFAULT_EXCEPTION_API); + expectedExceptionFiles, DEFAULT_EXCEPTION_API); } static Function validateTestFileGenerationWithoutIds() { @@ -864,19 +864,19 @@ static Function validateTestFileGenerationWithoutIds() { final String DEFAULT_EXCEPTION_API = DEFAULT_COMMON_FOLDER + "/exception"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "ISubscribeOperation.java", - ASSETS_PATH + "TestClassName.java" + ASSETS_PATH + "ISubscribeOperation.java", + ASSETS_PATH + "TestClassName.java" ); final List expectedProducerFiles = List.of( - ASSETS_PATH + "StreamBridgeProducer.java" + ASSETS_PATH + "StreamBridgeProducer.java" ); final List expectedExceptionFiles = List.of( - ASSETS_PATH + "ModelClassException.java"); + ASSETS_PATH + "ModelClassException.java"); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - expectedExceptionFiles, DEFAULT_EXCEPTION_API); + expectedExceptionFiles, DEFAULT_EXCEPTION_API); } static Function validateTestFileGenerationArrayString() { @@ -887,7 +887,7 @@ static Function validateTestFileGenerationArrayString() { final String ASSETS_PATH = COMMON_PATH + "assets/"; final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "ObjectArrayDTO.java" + ASSETS_PATH + "ObjectArrayDTO.java" ); return path -> modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); @@ -897,8 +897,8 @@ static Function validateTestIssueGenerateSupplier() { final String DEFAULT_MODEL_SCHEMA_FOLDER = "generated/company/mail/model"; final List expectedModelSchemaFiles = List.of( - "asyncapigenerator/v3/testIssueGenerateSupplier/assets/ConfigurationDTO.java", - "asyncapigenerator/v3/testIssueGenerateSupplier/assets/MailRequestDTO.java" + "asyncapigenerator/v3/testIssueGenerateSupplier/assets/ConfigurationDTO.java", + "asyncapigenerator/v3/testIssueGenerateSupplier/assets/MailRequestDTO.java" ); return path -> modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); @@ -908,8 +908,8 @@ static Function validateTestIssueInfiniteLoop() { final String DEFAULT_MODEL_SCHEMA_FOLDER = "generated/com/sngular/scsplugin/infiniteLoop/model"; final List expectedModelSchemaFiles = List.of( - "asyncapigenerator/v3/testIssueInfiniteLoop/assets/ConfigDTO.java", - "asyncapigenerator/v3/testIssueInfiniteLoop/assets/MailRequestInfiniteDTO.java" + "asyncapigenerator/v3/testIssueInfiniteLoop/assets/ConfigDTO.java", + "asyncapigenerator/v3/testIssueInfiniteLoop/assets/MailRequestInfiniteDTO.java" ); return path -> modelTest(path, expectedModelSchemaFiles, DEFAULT_MODEL_SCHEMA_FOLDER); @@ -934,33 +934,33 @@ static Function validateTestModelClassExceptionGeneration() { final String DEFAULT_EXCEPTION_API = DEFAULT_COMMON_FOLDER + "/exception"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "ISubscribeOrder.java", - ASSETS_PATH + "Subscriber.java"); + ASSETS_PATH + "ISubscribeOrder.java", + ASSETS_PATH + "Subscriber.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "IPublishOrder.java", - ASSETS_PATH + "Producer.java"); + ASSETS_PATH + "IPublishOrder.java", + ASSETS_PATH + "Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "CreateOrderEventDTO.java", - ASSETS_PATH + "OrderDTO.java", - ASSETS_PATH + "OrderLineDTO.java", - ASSETS_PATH + "OrderProductDTO.java", - ASSETS_PATH + "WaiterDTO.java" + ASSETS_PATH + "CreateOrderEventDTO.java", + ASSETS_PATH + "OrderDTO.java", + ASSETS_PATH + "OrderLineDTO.java", + ASSETS_PATH + "OrderProductDTO.java", + ASSETS_PATH + "WaiterDTO.java" ); final List expectedValidatorFiles = List.of( - CUSTOM_VALIDATOR_PATH + "NotNull.java", - CUSTOM_VALIDATOR_PATH + "NotNullValidator.java" + CUSTOM_VALIDATOR_PATH + "NotNull.java", + CUSTOM_VALIDATOR_PATH + "NotNullValidator.java" ); final List expectedExceptionFiles = List.of( - ASSETS_PATH + "ModelClassException.java"); + ASSETS_PATH + "ModelClassException.java"); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, - expectedExceptionFiles, DEFAULT_EXCEPTION_API) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_COMMON_FOLDER) && - customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); + expectedExceptionFiles, DEFAULT_EXCEPTION_API) && + modelTest(path, expectedModelSchemaFiles, DEFAULT_COMMON_FOLDER) && + customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); } static Function validateNoSchemas() { @@ -969,18 +969,18 @@ static Function validateNoSchemas() { final String MODEL_SCHEMA_FOLDER = "generated/com/sngular/scsplugin/noschemas/model"; final List expectedModelSchemaFiles = List.of( - "asyncapigenerator/v3/testNoSchemas/assets/TestMsg.java", - "asyncapigenerator/v3/testNoSchemas/assets/Thing.java" + "asyncapigenerator/v3/testNoSchemas/assets/TestMsg.java", + "asyncapigenerator/v3/testNoSchemas/assets/Thing.java" ); final List expectedProducerFiles = List.of( - "asyncapigenerator/v3/testNoSchemas/assets/IOnTest.java", - "asyncapigenerator/v3/testNoSchemas/assets/IOnTest2.java", - "asyncapigenerator/v3/testNoSchemas/assets/Producer.java" + "asyncapigenerator/v3/testNoSchemas/assets/IOnTest.java", + "asyncapigenerator/v3/testNoSchemas/assets/IOnTest2.java", + "asyncapigenerator/v3/testNoSchemas/assets/Producer.java" ); return path -> modelTest(path, expectedModelSchemaFiles, MODEL_SCHEMA_FOLDER) && - modelTest(path, expectedProducerFiles, API_FOLDER); + modelTest(path, expectedProducerFiles, API_FOLDER); } static Function validateMessageNaming() { @@ -989,20 +989,20 @@ static Function validateMessageNaming() { final String MODEL_SCHEMA_FOLDER = "generated/com/sngular/scsplugin/messagenaming/model"; final List expectedModelSchemaFiles = List.of( - "asyncapigenerator/v3/testMessageNaming/assets/TestMsg.java", - "asyncapigenerator/v3/testMessageNaming/assets/TestMsg2.java", - "asyncapigenerator/v3/testMessageNaming/assets/TestMsg3.java" + "asyncapigenerator/v3/testMessageNaming/assets/TestMsg.java", + "asyncapigenerator/v3/testMessageNaming/assets/TestMsg2.java", + "asyncapigenerator/v3/testMessageNaming/assets/TestMsg3.java" ); final List expectedProducerFiles = List.of( - "asyncapigenerator/v3/testMessageNaming/assets/IOnTest.java", - "asyncapigenerator/v3/testMessageNaming/assets/IOnTest2.java", - "asyncapigenerator/v3/testMessageNaming/assets/IOnTest3.java", - "asyncapigenerator/v3/testMessageNaming/assets/Producer.java" + "asyncapigenerator/v3/testMessageNaming/assets/IOnTest.java", + "asyncapigenerator/v3/testMessageNaming/assets/IOnTest2.java", + "asyncapigenerator/v3/testMessageNaming/assets/IOnTest3.java", + "asyncapigenerator/v3/testMessageNaming/assets/Producer.java" ); return path -> modelTest(path, expectedModelSchemaFiles, MODEL_SCHEMA_FOLDER) && - modelTest(path, expectedProducerFiles, API_FOLDER); + modelTest(path, expectedProducerFiles, API_FOLDER); } static Function validateNestedObject() { @@ -1011,14 +1011,14 @@ static Function validateNestedObject() { final String MODEL_SCHEMA_FOLDER = "generated/com/sngular/scsplugin/nestedobject/model"; final List expectedModelSchemaFiles = List.of( - "asyncapigenerator/v3/testNestedObjectIssue/assets/payload/SomeOtherObject.java", - "asyncapigenerator/v3/testNestedObjectIssue/assets/payload/UserSignedUpPayload.java" + "asyncapigenerator/v3/testNestedObjectIssue/assets/payload/SomeOtherObject.java", + "asyncapigenerator/v3/testNestedObjectIssue/assets/payload/UserSignedUpPayload.java" ); final List expectedProducerFiles = List.of(); return path -> modelTest(path, expectedModelSchemaFiles, MODEL_SCHEMA_FOLDER) && - modelTest(path, expectedProducerFiles, API_FOLDER); + modelTest(path, expectedProducerFiles, API_FOLDER); } static Function validateConstantGeneration() { @@ -1027,14 +1027,14 @@ static Function validateConstantGeneration() { final String MODEL_SCHEMA_FOLDER = "generated/com/sngular/scsplugin/constantgeneration/model"; final List expectedModelSchemaFiles = List.of( - "asyncapigenerator/v3/testConstantGeneration/assets/payload/SomeOtherObject.java", - "asyncapigenerator/v3/testConstantGeneration/assets/payload/UserSignedUpPayload.java" + "asyncapigenerator/v3/testConstantGeneration/assets/payload/SomeOtherObject.java", + "asyncapigenerator/v3/testConstantGeneration/assets/payload/UserSignedUpPayload.java" ); final List expectedProducerFiles = List.of(); return path -> modelTest(path, expectedModelSchemaFiles, MODEL_SCHEMA_FOLDER) && - modelTest(path, expectedProducerFiles, API_FOLDER); + modelTest(path, expectedProducerFiles, API_FOLDER); } static Function validateNotGeneratedPropertiesIssue() { @@ -1043,14 +1043,14 @@ static Function validateNotGeneratedPropertiesIssue() { final String MODEL_SCHEMA_FOLDER = "generated/com/sngular/scsplugin/notgeneratedproperties/model"; final List expectedModelSchemaFiles = List.of( - "asyncapigenerator/v3/testPropertiesNotGeneratedIssue/assets/payload/UserDetails.java", - "asyncapigenerator/v3/testPropertiesNotGeneratedIssue/assets/payload/UserSignedUp.java" + "asyncapigenerator/v3/testPropertiesNotGeneratedIssue/assets/payload/UserDetails.java", + "asyncapigenerator/v3/testPropertiesNotGeneratedIssue/assets/payload/UserSignedUp.java" ); final List expectedProducerFiles = List.of(); return path -> modelTest(path, expectedModelSchemaFiles, MODEL_SCHEMA_FOLDER) && - modelTest(path, expectedProducerFiles, API_FOLDER); + modelTest(path, expectedProducerFiles, API_FOLDER); } static Function validateTestFileGenerationWithKafkaBindings() { @@ -1070,33 +1070,33 @@ static Function validateTestFileGenerationWithKafkaBindings() { final String CUSTOM_VALIDATOR_PATH = COMMON_PATH + "customvalidator/"; final List expectedConsumerFiles = List.of( - ASSETS_PATH + "consumer/IPublishOperationFileGenerationWithKafkaBindings.java", - ASSETS_PATH + "consumer/TestClassName.java"); + ASSETS_PATH + "consumer/IPublishOperationFileGenerationWithKafkaBindings.java", + ASSETS_PATH + "consumer/TestClassName.java"); final List expectedProducerFiles = List.of( - ASSETS_PATH + "producer/ISubscribeOperationFileGenerationWithKafkaBindings.java", - ASSETS_PATH + "producer/MessageWrapper.java", - ASSETS_PATH + "producer/Producer.java"); + ASSETS_PATH + "producer/ISubscribeOperationFileGenerationWithKafkaBindings.java", + ASSETS_PATH + "producer/MessageWrapper.java", + ASSETS_PATH + "producer/Producer.java"); final List expectedModelSchemaFiles = List.of( - ASSETS_PATH + "CreateOrderMapper.java", - ASSETS_PATH + "OrderDTO.java", - ASSETS_PATH + "OrderLineDTO.java", - ASSETS_PATH + "OrderLineMapper.java", - ASSETS_PATH + "OrderMapper.java", - ASSETS_PATH + "OrderProductDTO.java", - ASSETS_PATH + "OrderProductMapper.java", - ASSETS_PATH + "WaiterMapper.java" + ASSETS_PATH + "CreateOrderMapper.java", + ASSETS_PATH + "OrderDTO.java", + ASSETS_PATH + "OrderLineDTO.java", + ASSETS_PATH + "OrderLineMapper.java", + ASSETS_PATH + "OrderMapper.java", + ASSETS_PATH + "OrderProductDTO.java", + ASSETS_PATH + "OrderProductMapper.java", + ASSETS_PATH + "WaiterMapper.java" ); final List expectedValidatorFiles = List.of( - CUSTOM_VALIDATOR_PATH + "NotNull.java", - CUSTOM_VALIDATOR_PATH + "NotNullValidator.java" + CUSTOM_VALIDATOR_PATH + "NotNull.java", + CUSTOM_VALIDATOR_PATH + "NotNullValidator.java" ); return path -> commonTest(path, expectedConsumerFiles, expectedProducerFiles, DEFAULT_CONSUMER_FOLDER, DEFAULT_PRODUCER_FOLDER, Collections.emptyList(), null) && - modelTest(path, expectedModelSchemaFiles, DEFAULT_COMMON_FOLDER) && - customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); + modelTest(path, expectedModelSchemaFiles, DEFAULT_COMMON_FOLDER) && + customValidatorTest(path, expectedValidatorFiles, DEFAULT_CUSTOM_VALIDATOR_FOLDER); } static Function validateTestSubObjectSameName() { @@ -1116,31 +1116,31 @@ static Function validateTestSubObjectSameName() { final String ASSETS_PATH = COMMON_PATH + "assets/"; final List expectedConsumerFiles = - List.of( - ASSETS_PATH + "input/controller/IInput.java", - ASSETS_PATH + "input/controller/Subscriber.java"); + List.of( + ASSETS_PATH + "input/controller/IInput.java", + ASSETS_PATH + "input/controller/Subscriber.java"); final List expectedProducerFiles = - List.of( - ASSETS_PATH + "output/provider/IOutput.java", - ASSETS_PATH + "output/provider/Producer.java"); + List.of( + ASSETS_PATH + "output/provider/IOutput.java", + ASSETS_PATH + "output/provider/Producer.java"); final List expectedConsumerModelSchemaFiles = - List.of(ASSETS_PATH + "input/model/Data.java", ASSETS_PATH + "input/model/Input.java"); + List.of(ASSETS_PATH + "input/model/Data.java", ASSETS_PATH + "input/model/Input.java"); final List expectedProducerModelSchemaFiles = - List.of(ASSETS_PATH + "output/model/Data.java", ASSETS_PATH + "output/model/Output.java"); + List.of(ASSETS_PATH + "output/model/Data.java", ASSETS_PATH + "output/model/Output.java"); return path -> - commonTest( - path, - expectedConsumerFiles, - expectedProducerFiles, - DEFAULT_CONSUMER_FOLDER, - DEFAULT_PRODUCER_FOLDER, - Collections.emptyList(), - null) - && modelTest(path, expectedConsumerModelSchemaFiles, DEFAULT_CONSUMER_MODEL_FOLDER) - && modelTest(path, expectedProducerModelSchemaFiles, DEFAULT_PRODUCER_MODEL_FOLDER); + commonTest( + path, + expectedConsumerFiles, + expectedProducerFiles, + DEFAULT_CONSUMER_FOLDER, + DEFAULT_PRODUCER_FOLDER, + Collections.emptyList(), + null) + && modelTest(path, expectedConsumerModelSchemaFiles, DEFAULT_CONSUMER_MODEL_FOLDER) + && modelTest(path, expectedProducerModelSchemaFiles, DEFAULT_PRODUCER_MODEL_FOLDER); } static Function validateTestReferenceFromLocalIssue() { diff --git a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v3/AsyncApiGeneratorJakartaTest.java b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v3/AsyncApiGeneratorJakartaTest.java index 21402809..ee027a6e 100644 --- a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v3/AsyncApiGeneratorJakartaTest.java +++ b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v3/AsyncApiGeneratorJakartaTest.java @@ -6,6 +6,12 @@ package com.sngular.api.generator.plugin.asyncapi.v3; +import java.io.File; +import java.nio.file.Path; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Stream; + import com.sngular.api.generator.plugin.asyncapi.AsyncApiGenerator; import com.sngular.api.generator.plugin.asyncapi.parameter.SpecFile; import org.assertj.core.api.Assertions; @@ -15,12 +21,6 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.io.File; -import java.nio.file.Path; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Stream; - class AsyncApiGeneratorJakartaTest { @TempDir @@ -28,14 +28,14 @@ class AsyncApiGeneratorJakartaTest { private static AsyncApiGenerator asyncApiGenerator; - private static int SPRING_BOOT_VERSION = 3; + private static final int SPRING_BOOT_VERSION = 3; @BeforeAll static void setup() { asyncApiGenerator = new AsyncApiGenerator(SPRING_BOOT_VERSION, true, new File(baseDir.toAbsolutePath() + File.separator + AsyncApiGeneratorFixtures.TARGET), AsyncApiGeneratorFixtures.GENERATED, - "groupId", - baseDir.toFile()); + "groupId", + baseDir.toFile()); } static Stream fileSpecToProcess() { diff --git a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v3/AsyncApiGeneratorTest.java b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v3/AsyncApiGeneratorTest.java index 98f75ac7..fe07bb7a 100644 --- a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v3/AsyncApiGeneratorTest.java +++ b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/asyncapi/v3/AsyncApiGeneratorTest.java @@ -6,6 +6,12 @@ package com.sngular.api.generator.plugin.asyncapi.v3; +import java.io.File; +import java.nio.file.Path; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Stream; + import com.sngular.api.generator.plugin.asyncapi.AsyncApiGenerator; import com.sngular.api.generator.plugin.asyncapi.exception.InvalidAvroException; import com.sngular.api.generator.plugin.asyncapi.parameter.SpecFile; @@ -20,22 +26,14 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.io.File; -import java.nio.file.Path; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Stream; - @Slf4j class AsyncApiGeneratorTest { + private static final int SPRING_BOOT_VERSION = 2; @TempDir(cleanup = CleanupMode.NEVER) static Path baseDir; - private static AsyncApiGenerator asyncApiGenerator; - private static final int SPRING_BOOT_VERSION = 2; - @BeforeAll static void setup() { asyncApiGenerator = @@ -44,7 +42,7 @@ static void setup() { new File(baseDir.toAbsolutePath() + File.separator + AsyncApiGeneratorFixtures.TARGET), AsyncApiGeneratorFixtures.GENERATED, "groupId", - Path.of("src","test","resources").toFile() + Path.of("src", "test", "resources").toFile() ); } @@ -56,33 +54,33 @@ static Stream fileSpecToProcess() { Arguments.of("TestRareCharsGeneration", AsyncApiGeneratorFixtures.TEST_RARE_CHARS_GENERATION, AsyncApiGeneratorFixtures.validateTestRareCharsGeneration()), Arguments.of("TestFileGenerationIssue", AsyncApiGeneratorFixtures.TEST_FILE_GENERATION_ISSUE, AsyncApiGeneratorFixtures.validateTestFileGenerationIssue()), Arguments.of("TestFileGenerationExternalAvro", AsyncApiGeneratorFixtures.TEST_FILE_GENERATION_EXTERNAL_AVRO, - AsyncApiGeneratorFixtures.validateTestFileGenerationExternalAvro()), + AsyncApiGeneratorFixtures.validateTestFileGenerationExternalAvro()), Arguments.of("TestFileGenerationStreamBridge", AsyncApiGeneratorFixtures.TEST_FILE_GENERATION_STREAM_BRIDGE, - AsyncApiGeneratorFixtures.validateTestFileGenerationStreamBridge()), + AsyncApiGeneratorFixtures.validateTestFileGenerationStreamBridge()), Arguments.of("TestFileGenerationWithoutIds", AsyncApiGeneratorFixtures.TEST_FILE_GENERATION_WITHOUT_IDS, - AsyncApiGeneratorFixtures.validateTestFileGenerationWithoutIds()), + AsyncApiGeneratorFixtures.validateTestFileGenerationWithoutIds()), Arguments.of("TestFileGenerationArrayString", AsyncApiGeneratorFixtures.TEST_FILE_GENERATION_WITH_ARRAY_STRING, - AsyncApiGeneratorFixtures.validateTestFileGenerationArrayString()), + AsyncApiGeneratorFixtures.validateTestFileGenerationArrayString()), Arguments.of("TestIssueGenerateSupplier", AsyncApiGeneratorFixtures.TEST_ISSUE_GENERATE_SUPPLIER, - AsyncApiGeneratorFixtures.validateTestIssueGenerateSupplier()), + AsyncApiGeneratorFixtures.validateTestIssueGenerateSupplier()), Arguments.of("TestIssueSimpleTypeGenerate", AsyncApiGeneratorFixtures.TEST_ISSUE_SIMPLE_TYPE_GENERATION, - AsyncApiGeneratorFixtures.validateTestIssueSimpleTypeGeneration()), + AsyncApiGeneratorFixtures.validateTestIssueSimpleTypeGeneration()), Arguments.of("TestIssueInfiniteLoop", AsyncApiGeneratorFixtures.TEST_ISSUE_INFINITE_LOOP, - AsyncApiGeneratorFixtures.validateTestIssueInfiniteLoop()), + AsyncApiGeneratorFixtures.validateTestIssueInfiniteLoop()), Arguments.of("TestCustomValidators", AsyncApiGeneratorFixtures.TEST_CUSTOM_VALIDATORS, AsyncApiGeneratorFixtures.validateCustomValidators(SPRING_BOOT_VERSION)), Arguments.of("TestModelClassExceptionGeneration", AsyncApiGeneratorFixtures.TEST_MODEL_CLASS_EXCEPTION_GENERATION, - AsyncApiGeneratorFixtures.validateTestModelClassExceptionGeneration()), + AsyncApiGeneratorFixtures.validateTestModelClassExceptionGeneration()), Arguments.of("TestNoSchemas", AsyncApiGeneratorFixtures.TEST_NO_SCHEMAS, AsyncApiGeneratorFixtures.validateNoSchemas()), - Arguments.of("TestMessageNaming", AsyncApiGeneratorFixtures.TEST_MESSAGE_NAMING, AsyncApiGeneratorFixtures.validateMessageNaming()), + Arguments.of("TestMessageNaming", AsyncApiGeneratorFixtures.TEST_MESSAGE_NAMING, AsyncApiGeneratorFixtures.validateMessageNaming()), Arguments.of("TestNestedObjectIssue", AsyncApiGeneratorFixtures.TEST_NESTED_OBJECT, AsyncApiGeneratorFixtures.validateNestedObject()), Arguments.of("TestConstantGeneration", AsyncApiGeneratorFixtures.TEST_CONSTANT_GENERATION, AsyncApiGeneratorFixtures.validateConstantGeneration()), Arguments.of("testPropertiesNotGeneratedIssue", AsyncApiGeneratorFixtures.PROPERTIES_NOT_GENERATED_ISSUE, AsyncApiGeneratorFixtures.validateNotGeneratedPropertiesIssue()), Arguments.of("TestFileGenerationWithKafkaBindings", AsyncApiGeneratorFixtures.TEST_FILE_GENERATION_WITH_KAFKA_BINDINGS, - AsyncApiGeneratorFixtures.validateTestFileGenerationWithKafkaBindings()), + AsyncApiGeneratorFixtures.validateTestFileGenerationWithKafkaBindings()), Arguments.of("TestSubObjectSameName", AsyncApiGeneratorFixtures.TEST_SUB_OBJECT_SAME_NAME, - AsyncApiGeneratorFixtures.validateTestSubObjectSameName()), + AsyncApiGeneratorFixtures.validateTestSubObjectSameName()), Arguments.of("TestReferenceFromLocalIssue", AsyncApiGeneratorFixtures.TEST_REFERENCE_FROM_LOCAL_ISSUE, - AsyncApiGeneratorFixtures.validateTestReferenceFromLocalIssue())); + AsyncApiGeneratorFixtures.validateTestReferenceFromLocalIssue())); } @ParameterizedTest(name = "Test {index} - Process File Spec for case {0}") diff --git a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorFixtures.java b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorFixtures.java index b8dc8f3d..d79beb93 100644 --- a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorFixtures.java +++ b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorFixtures.java @@ -6,11 +6,7 @@ package com.sngular.api.generator.plugin.openapi; -import com.sngular.api.generator.plugin.common.model.TypeConstants.TimeType; -import com.sngular.api.generator.plugin.openapi.parameter.SpecFile; -import com.sngular.api.generator.test.utils.TestUtils; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections4.CollectionUtils; +import static org.assertj.core.api.Assertions.assertThat; import java.io.File; import java.net.URISyntaxException; @@ -19,7 +15,11 @@ import java.util.List; import java.util.function.Function; -import static org.assertj.core.api.Assertions.assertThat; +import com.sngular.api.generator.plugin.common.model.TypeConstants.TimeType; +import com.sngular.api.generator.plugin.openapi.parameter.SpecFile; +import com.sngular.api.generator.test.utils.TestUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; @Slf4j public final class OpenApiGeneratorFixtures { @@ -197,31 +197,31 @@ public final class OpenApiGeneratorFixtures { ); static final List TEST_REST_CLIENT_GENERATION = List.of( - SpecFile - .builder() - .filePath("openapigenerator/testRestClientApiGeneration/api-test.yml") - .apiPackage("com.sngular.multifileplugin.restclient") - .modelPackage("com.sngular.multifileplugin.restclient.model") - .clientPackage("com.sngular.multifileplugin.restclient.client") - .modelNamePrefix("Api") - .modelNameSuffix("DTO") - .useLombokModelAnnotation(false) - .callMode(true) - .build() + SpecFile + .builder() + .filePath("openapigenerator/testRestClientApiGeneration/api-test.yml") + .apiPackage("com.sngular.multifileplugin.restclient") + .modelPackage("com.sngular.multifileplugin.restclient.model") + .clientPackage("com.sngular.multifileplugin.restclient.client") + .modelNamePrefix("Api") + .modelNameSuffix("DTO") + .useLombokModelAnnotation(false) + .callMode(true) + .build() ); static final List TEST_REST_CLIENT_API_WITH_REQUEST_OBJECTS_GENERATION = List.of( - SpecFile - .builder() - .filePath("openapigenerator/testRestClientApiWithRequestObjectGeneration/api-test.yml") - .apiPackage("com.sngular.multifileplugin.restclientWithRequestObjects") - .modelPackage("com.sngular.multifileplugin.restclientWithRequestObjects.model") - .clientPackage("com.sngular.multifileplugin.restclientWithRequestObjects.client") - .modelNamePrefix("Api") - .modelNameSuffix("DTO") - .useLombokModelAnnotation(false) - .callMode(true) - .build() + SpecFile + .builder() + .filePath("openapigenerator/testRestClientApiWithRequestObjectGeneration/api-test.yml") + .apiPackage("com.sngular.multifileplugin.restclientWithRequestObjects") + .modelPackage("com.sngular.multifileplugin.restclientWithRequestObjects.model") + .clientPackage("com.sngular.multifileplugin.restclientWithRequestObjects.client") + .modelNamePrefix("Api") + .modelNameSuffix("DTO") + .useLombokModelAnnotation(false) + .callMode(true) + .build() ); static final List TEST_ENUMS_GENERATION = List.of( @@ -530,14 +530,17 @@ public final class OpenApiGeneratorFixtures { ); static final List TEST_FORM_DATA_MULTIPART_GENERATION = List.of( - SpecFile - .builder() - .filePath("openapigenerator/testFormDataMultipartGeneration/api-test.yml") - .apiPackage("com.sngular.multifileplugin.testformdatamultipartgeneration") - .useLombokModelAnnotation(true) - .build() + SpecFile + .builder() + .filePath("openapigenerator/testFormDataMultipartGeneration/api-test.yml") + .apiPackage("com.sngular.multifileplugin.testformdatamultipartgeneration") + .useLombokModelAnnotation(true) + .build() ); + private OpenApiGeneratorFixtures() { + } + static Function validateOneOfInResponse() { final String DEFAULT_TARGET_API = "generated/com/sngular/multifileplugin/testoneofinresponse"; @@ -954,8 +957,8 @@ static Function validateRestClientGeneration() { ); return path -> - commonTest(path, expectedTestApiFile, Collections.emptyList(), DEFAULT_TARGET_API, null, Collections.emptyList(), null) && - commonTest(path, expectedTestClientApiFile, expectedTestClientAuthModelFiles, CLIENT_TARGET_API, CLIENT_MODEL_API, Collections.emptyList(), null); + commonTest(path, expectedTestApiFile, Collections.emptyList(), DEFAULT_TARGET_API, null, Collections.emptyList(), null) && + commonTest(path, expectedTestClientApiFile, expectedTestClientAuthModelFiles, CLIENT_TARGET_API, CLIENT_MODEL_API, Collections.emptyList(), null); } static Function validateRestClientWithRequestBodyGeneration() { @@ -971,21 +974,21 @@ static Function validateRestClientWithRequestBodyGeneration() { final String ASSETS_PATH = COMMON_PATH + "assets/"; List expectedTestApiFile = List.of( - ASSETS_PATH + "TestApi.java" + ASSETS_PATH + "TestApi.java" ); List expectedTestClientApiFile = List.of( - ASSETS_PATH + "client/ApiRestClient.java" + ASSETS_PATH + "client/ApiRestClient.java" ); List expectedTestClientAuthModelFiles = List.of( - ASSETS_PATH + "client/auth/Authentication.java", - ASSETS_PATH + "client/auth/HttpBasicAuth.java" + ASSETS_PATH + "client/auth/Authentication.java", + ASSETS_PATH + "client/auth/HttpBasicAuth.java" ); return path -> - commonTest(path, expectedTestApiFile, Collections.emptyList(), DEFAULT_TARGET_API, null, Collections.emptyList(), null) && - commonTest(path, expectedTestClientApiFile, expectedTestClientAuthModelFiles, CLIENT_TARGET_API, CLIENT_MODEL_API, Collections.emptyList(), null); + commonTest(path, expectedTestApiFile, Collections.emptyList(), DEFAULT_TARGET_API, null, Collections.emptyList(), null) && + commonTest(path, expectedTestClientApiFile, expectedTestClientAuthModelFiles, CLIENT_TARGET_API, CLIENT_MODEL_API, Collections.emptyList(), null); } static Function validateEnumsGeneration() { @@ -1269,7 +1272,6 @@ static Function validateSimpleBuild() { return path -> commonTest(path, expectedTestApiFile, expectedTestApiModelFiles, DEFAULT_TARGET_API, DEFAULT_MODEL_API, Collections.emptyList(), null); } - static Function validateDataMultipartGeneration() { final String DEFAULT_TARGET_API = "generated/com/sngular/multifileplugin/testformdatamultipartgeneration"; @@ -1284,7 +1286,7 @@ static Function validateDataMultipartGeneration() { ASSETS_PATH + "TestApi.java" ); - final List expectedTestApiModelFiles = Collections.emptyList(); + final List expectedTestApiModelFiles = Collections.emptyList(); return path -> commonTest(path, expectedTestApiFile, expectedTestApiModelFiles, DEFAULT_TARGET_API, DEFAULT_MODEL_API, Collections.emptyList(), null); } @@ -1319,25 +1321,25 @@ static Function validateValidationAnnotations(int springBootVersi final List expectedValidatorFiles = List.of( CUSTOM_VALIDATOR_PATH + "MaxBigDecimal.java", - CUSTOM_VALIDATOR_PATH + "MaxBigDecimalValidator.java", - CUSTOM_VALIDATOR_PATH + "MaxDouble.java", - CUSTOM_VALIDATOR_PATH + "MaxDoubleValidator.java", - CUSTOM_VALIDATOR_PATH + "MaxFloat.java", - CUSTOM_VALIDATOR_PATH + "MaxFloatValidator.java", - CUSTOM_VALIDATOR_PATH + "MaxInteger.java", - CUSTOM_VALIDATOR_PATH + "MaxIntegerValidator.java", - CUSTOM_VALIDATOR_PATH + "MaxItems.java", - CUSTOM_VALIDATOR_PATH + "MaxItemsValidator.java", + CUSTOM_VALIDATOR_PATH + "MaxBigDecimalValidator.java", + CUSTOM_VALIDATOR_PATH + "MaxDouble.java", + CUSTOM_VALIDATOR_PATH + "MaxDoubleValidator.java", + CUSTOM_VALIDATOR_PATH + "MaxFloat.java", + CUSTOM_VALIDATOR_PATH + "MaxFloatValidator.java", + CUSTOM_VALIDATOR_PATH + "MaxInteger.java", + CUSTOM_VALIDATOR_PATH + "MaxIntegerValidator.java", + CUSTOM_VALIDATOR_PATH + "MaxItems.java", + CUSTOM_VALIDATOR_PATH + "MaxItemsValidator.java", CUSTOM_VALIDATOR_PATH + "MinBigDecimal.java", - CUSTOM_VALIDATOR_PATH + "MinBigDecimalValidator.java", - CUSTOM_VALIDATOR_PATH + "MinDouble.java", - CUSTOM_VALIDATOR_PATH + "MinDoubleValidator.java", - CUSTOM_VALIDATOR_PATH + "MinFloat.java", - CUSTOM_VALIDATOR_PATH + "MinFloatValidator.java", - CUSTOM_VALIDATOR_PATH + "MinInteger.java", - CUSTOM_VALIDATOR_PATH + "MinIntegerValidator.java", - CUSTOM_VALIDATOR_PATH + "MinItems.java", - CUSTOM_VALIDATOR_PATH + "MinItemsValidator.java", + CUSTOM_VALIDATOR_PATH + "MinBigDecimalValidator.java", + CUSTOM_VALIDATOR_PATH + "MinDouble.java", + CUSTOM_VALIDATOR_PATH + "MinDoubleValidator.java", + CUSTOM_VALIDATOR_PATH + "MinFloat.java", + CUSTOM_VALIDATOR_PATH + "MinFloatValidator.java", + CUSTOM_VALIDATOR_PATH + "MinInteger.java", + CUSTOM_VALIDATOR_PATH + "MinIntegerValidator.java", + CUSTOM_VALIDATOR_PATH + "MinItems.java", + CUSTOM_VALIDATOR_PATH + "MinItemsValidator.java", CUSTOM_VALIDATOR_PATH + "MultipleOf.java", CUSTOM_VALIDATOR_PATH + "MultipleOfValidator.java", CUSTOM_VALIDATOR_PATH + "NotNull.java", @@ -1351,7 +1353,7 @@ static Function validateValidationAnnotations(int springBootVersi ); return path -> commonTest(path, expectedTestApiFile, expectedTestApiModelFiles, DEFAULT_TARGET_API, DEFAULT_MODEL_API, expectedExceptionFiles, DEFAULT_EXCEPTION_API) - && customValidatorTest(path, expectedValidatorFiles); + && customValidatorTest(path, expectedValidatorFiles); } static Function validateValidationAnnotationsLombok(int springBootTest) { @@ -1566,7 +1568,6 @@ static Function validateReferenceFile() { return path -> commonTest(path, expectedTestApiFiles, expectedTestApiModelFiles, DEFAULT_TARGET_API, DEFAULT_MODEL_API, Collections.emptyList(), DEFAULT_EXCEPTION_API); } - static Function validateReferenceFileNoComponents() { final String DEFAULT_TARGET_API = "generated/com/sngular/multifileplugin/testreferencefilenocomponents"; @@ -1666,9 +1667,6 @@ private static Boolean customValidatorTest(final Path resultPath, final List fileSpecToProcess() { return Stream.of( Arguments.of("testApiReactiveGeneration", OpenApiGeneratorFixtures.TEST_API_REACTIVE_GENERATION, - OpenApiGeneratorFixtures.validateApiReactiveGeneration(SPRING_BOOT_VERSION)), + OpenApiGeneratorFixtures.validateApiReactiveGeneration(SPRING_BOOT_VERSION)), Arguments.of("testValidationAnnotations", OpenApiGeneratorFixtures.TEST_VALIDATION_ANNOTATIONS, - OpenApiGeneratorFixtures.validateValidationAnnotations(SPRING_BOOT_VERSION)), + OpenApiGeneratorFixtures.validateValidationAnnotations(SPRING_BOOT_VERSION)), Arguments.of("testValidationAnnotationsLombok", OpenApiGeneratorFixtures.TEST_VALIDATION_ANNOTATIONS_LOMBOK, - OpenApiGeneratorFixtures.validateValidationAnnotationsLombok(SPRING_BOOT_VERSION)) + OpenApiGeneratorFixtures.validateValidationAnnotationsLombok(SPRING_BOOT_VERSION)) ); } diff --git a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorTest.java b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorTest.java index dfa43aa3..a8db5cf0 100644 --- a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorTest.java +++ b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorTest.java @@ -6,6 +6,12 @@ package com.sngular.api.generator.plugin.openapi; +import java.io.File; +import java.nio.file.Path; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Stream; + import com.sngular.api.generator.plugin.exception.InvalidAPIException; import com.sngular.api.generator.plugin.openapi.parameter.SpecFile; import lombok.extern.slf4j.Slf4j; @@ -18,22 +24,14 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.io.File; -import java.nio.file.Path; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Stream; - @Slf4j class OpenApiGeneratorTest { + private static final int SPRING_BOOT_VERSION = 2; @TempDir(cleanup = CleanupMode.NEVER) static Path baseDir; - private static OpenApiGenerator openApiGenerator; - private static final int SPRING_BOOT_VERSION = 2; - @BeforeAll static void setup() { openApiGenerator = @@ -42,95 +40,95 @@ static void setup() { new File(baseDir.toAbsolutePath() + File.separator + OpenApiGeneratorFixtures.TARGET), OpenApiGeneratorFixtures.GENERATED, "groupId", - Path.of("src","test","resources").toFile()); + Path.of("src", "test", "resources").toFile()); } static Stream fileSpecToProcess() { return Stream.of( Arguments.of("testAllOf", OpenApiGeneratorFixtures.TEST_ALL_OF, - OpenApiGeneratorFixtures.validateAllOf()), + OpenApiGeneratorFixtures.validateAllOf()), Arguments.of("testComplexAnyOf", OpenApiGeneratorFixtures.TEST_COMPLEX_ANY_OF, - OpenApiGeneratorFixtures.validateComplexAnyOf()), + OpenApiGeneratorFixtures.validateComplexAnyOf()), Arguments.of("testAllOfLombok", OpenApiGeneratorFixtures.TEST_ALL_OF_LOMBOK, - OpenApiGeneratorFixtures.validateAllOfLombok()), + OpenApiGeneratorFixtures.validateAllOfLombok()), Arguments.of("testOverWriteModelTrue", OpenApiGeneratorFixtures.TEST_OVER_WRITE_MODEL_TRUE, - OpenApiGeneratorFixtures.validateOverwriteModeTrue()), + OpenApiGeneratorFixtures.validateOverwriteModeTrue()), Arguments.of("testApiClientGeneration", OpenApiGeneratorFixtures.TEST_API_CLIENT_GENERATION, - OpenApiGeneratorFixtures.validateApiClientGeneration()), + OpenApiGeneratorFixtures.validateApiClientGeneration()), Arguments.of("testInlineSchemaCreation", OpenApiGeneratorFixtures.TEST_INLINE_SCHEMA_CREATION, - OpenApiGeneratorFixtures.validateInlineSchemaCreation()), + OpenApiGeneratorFixtures.validateInlineSchemaCreation()), Arguments.of("testApiParametersWithContentGeneration", OpenApiGeneratorFixtures.TEST_PARAMETER_WITH_CONTENT_GENERATION, - OpenApiGeneratorFixtures.validateParametersWithSchemaGeneration()), + OpenApiGeneratorFixtures.validateParametersWithSchemaGeneration()), Arguments.of("testApiPathWithSpecialCharGeneration", OpenApiGeneratorFixtures.TEST_PATH_WITH_SLASH_GENERATION, - OpenApiGeneratorFixtures.validatePathWithSpecialCharGeneration()), + OpenApiGeneratorFixtures.validatePathWithSpecialCharGeneration()), Arguments.of("testApiReactiveGeneration", OpenApiGeneratorFixtures.TEST_API_REACTIVE_GENERATION, - OpenApiGeneratorFixtures.validateApiReactiveGeneration(SPRING_BOOT_VERSION)), + OpenApiGeneratorFixtures.validateApiReactiveGeneration(SPRING_BOOT_VERSION)), Arguments.of("testApiTagsGeneration", OpenApiGeneratorFixtures.TEST_API_TAGS_GENERATION, - OpenApiGeneratorFixtures.validateTagsGeneration()), + OpenApiGeneratorFixtures.validateTagsGeneration()), Arguments.of("testMultipleRefGeneration", OpenApiGeneratorFixtures.TEST_MULTIPLE_REF_GENERATION, - OpenApiGeneratorFixtures.validateMultipleRefGeneration()), + OpenApiGeneratorFixtures.validateMultipleRefGeneration()), Arguments.of("testApiPathParameterGeneration", OpenApiGeneratorFixtures.TEST_PATH_PARAMETER_GENERATION, - OpenApiGeneratorFixtures.validatePathParameterGeneration()), + OpenApiGeneratorFixtures.validatePathParameterGeneration()), Arguments.of("testWebClientApiGeneration", OpenApiGeneratorFixtures.TEST_WEB_CLIENT_GENERATION, - OpenApiGeneratorFixtures.validateWebClientGeneration()), + OpenApiGeneratorFixtures.validateWebClientGeneration()), Arguments.of("testClientPackageWebClientApiGeneration", OpenApiGeneratorFixtures.TEST_CLIENT_PACKAGE_WEB_CLIENT_GENERATION, - OpenApiGeneratorFixtures.validateClientPackageWebClientGeneration()), + OpenApiGeneratorFixtures.validateClientPackageWebClientGeneration()), Arguments.of("testRestClientApiGeneration", OpenApiGeneratorFixtures.TEST_REST_CLIENT_GENERATION, - OpenApiGeneratorFixtures.validateRestClientGeneration()), + OpenApiGeneratorFixtures.validateRestClientGeneration()), Arguments.of("testRestClientApiWithRequestObjectGeneration", OpenApiGeneratorFixtures.TEST_REST_CLIENT_API_WITH_REQUEST_OBJECTS_GENERATION, - OpenApiGeneratorFixtures.validateRestClientWithRequestBodyGeneration()), + OpenApiGeneratorFixtures.validateRestClientWithRequestBodyGeneration()), Arguments.of("testApiEnumsGeneration", OpenApiGeneratorFixtures.TEST_ENUMS_GENERATION, - OpenApiGeneratorFixtures.validateEnumsGeneration()), + OpenApiGeneratorFixtures.validateEnumsGeneration()), Arguments.of("testApiEnumsLombokGeneration", OpenApiGeneratorFixtures.TEST_ENUMS_LOMBOK_GENERATION, - OpenApiGeneratorFixtures.validateEnumsLombokGeneration()), + OpenApiGeneratorFixtures.validateEnumsLombokGeneration()), Arguments.of("testExternalRefsGeneration", OpenApiGeneratorFixtures.TEST_EXTERNAL_REF_GENERATION, - OpenApiGeneratorFixtures.validateExternalRefGeneration()), + OpenApiGeneratorFixtures.validateExternalRefGeneration()), Arguments.of("testAnyOfInResponse", OpenApiGeneratorFixtures.TEST_ANY_OF_IN_RESPONSE, - OpenApiGeneratorFixtures.validateAnyOfInResponse()), + OpenApiGeneratorFixtures.validateAnyOfInResponse()), Arguments.of("testOneOfInResponse", OpenApiGeneratorFixtures.TEST_ONE_OF_IN_RESPONSE, - OpenApiGeneratorFixtures.validateOneOfInResponse()), + OpenApiGeneratorFixtures.validateOneOfInResponse()), Arguments.of("testAdditionalProperties", OpenApiGeneratorFixtures.TEST_ADDITIONAL_PROPERTIES, - OpenApiGeneratorFixtures.validateAdditionalProperties()), + OpenApiGeneratorFixtures.validateAdditionalProperties()), Arguments.of("testAdditionalPropertiesWithSchema", OpenApiGeneratorFixtures.TEST_ADDITIONAL_PROPERTIES_WITH_SCHEMA, - OpenApiGeneratorFixtures.validateAdditionalPropertiesWithSchema()), + OpenApiGeneratorFixtures.validateAdditionalPropertiesWithSchema()), Arguments.of("testAdditionalPropertiesWithUnnamedObject", OpenApiGeneratorFixtures.TEST_ADDITIONAL_PROPERTIES_WITH_UNNAMED_OBJECT, - OpenApiGeneratorFixtures.validateAdditionalPropertiesWithUnnamedObject()), + OpenApiGeneratorFixtures.validateAdditionalPropertiesWithUnnamedObject()), Arguments.of("testCoconutSchema", OpenApiGeneratorFixtures.TEST_COCONUT_SCHEMA, - OpenApiGeneratorFixtures.validateCoconutSchema()), + OpenApiGeneratorFixtures.validateCoconutSchema()), Arguments.of("testValidationAnnotations", OpenApiGeneratorFixtures.TEST_VALIDATION_ANNOTATIONS, - OpenApiGeneratorFixtures.validateValidationAnnotations(SPRING_BOOT_VERSION)), + OpenApiGeneratorFixtures.validateValidationAnnotations(SPRING_BOOT_VERSION)), Arguments.of("testValidationAnnotationsLombok", OpenApiGeneratorFixtures.TEST_VALIDATION_ANNOTATIONS_LOMBOK, - OpenApiGeneratorFixtures.validateValidationAnnotationsLombok(SPRING_BOOT_VERSION)), + OpenApiGeneratorFixtures.validateValidationAnnotationsLombok(SPRING_BOOT_VERSION)), Arguments.of("testCreateDTO", OpenApiGeneratorFixtures.TEST_CREATE_DTO, - OpenApiGeneratorFixtures.validateCreateDTO()), + OpenApiGeneratorFixtures.validateCreateDTO()), Arguments.of("testCreateDTOWithEnum", OpenApiGeneratorFixtures.TEST_CREATE_DTO_WITH_ENUM, - OpenApiGeneratorFixtures.validateCreateDTOWithEnum()), + OpenApiGeneratorFixtures.validateCreateDTOWithEnum()), Arguments.of("testCreateBasicDTO", OpenApiGeneratorFixtures.TEST_CREATE_BASIC_DTO, - OpenApiGeneratorFixtures.validateCreateBasicDTO()), + OpenApiGeneratorFixtures.validateCreateBasicDTO()), Arguments.of("testIssueFaker", OpenApiGeneratorFixtures.TEST_ISSUE_FAKER, - OpenApiGeneratorFixtures.validateIssueFaker()), + OpenApiGeneratorFixtures.validateIssueFaker()), Arguments.of("testDateTime", OpenApiGeneratorFixtures.TEST_DATE_TIME, - OpenApiGeneratorFixtures.validateDateTime()), + OpenApiGeneratorFixtures.validateDateTime()), Arguments.of("testDateTimeZoned", OpenApiGeneratorFixtures.TEST_DATE_TIME_ZONED, - OpenApiGeneratorFixtures.validateDateTimeZoned()), + OpenApiGeneratorFixtures.validateDateTimeZoned()), Arguments.of("testDateTimeOffset", OpenApiGeneratorFixtures.TEST_DATE_TIME_OFFSET, - OpenApiGeneratorFixtures.validateDateTimeOffset()), + OpenApiGeneratorFixtures.validateDateTimeOffset()), Arguments.of("testListString", OpenApiGeneratorFixtures.TEST_LIST_STRING, - OpenApiGeneratorFixtures.validateListString()), + OpenApiGeneratorFixtures.validateListString()), Arguments.of("testReferenceFile", OpenApiGeneratorFixtures.TEST_REFERENCE_FILE, - OpenApiGeneratorFixtures.validateReferenceFile()), + OpenApiGeneratorFixtures.validateReferenceFile()), Arguments.of("testReferenceFileNoComponents", OpenApiGeneratorFixtures.TEST_REFERENCE_FILE_NO_COMPONENTS, - OpenApiGeneratorFixtures.validateReferenceFileNoComponents()), + OpenApiGeneratorFixtures.validateReferenceFileNoComponents()), Arguments.of("testQueryParam", OpenApiGeneratorFixtures.TEST_QUERY_PARAM, - OpenApiGeneratorFixtures.validateQueryParam()), + OpenApiGeneratorFixtures.validateQueryParam()), Arguments.of("testApiWithNoComponents", OpenApiGeneratorFixtures.TEST_API_WITH_NO_COMPONENTS, - OpenApiGeneratorFixtures.validateApiWithNoComponents()), + OpenApiGeneratorFixtures.validateApiWithNoComponents()), Arguments.of("testRestrictionSchema", OpenApiGeneratorFixtures.TEST_RESTRICTION_SCHEMA, - OpenApiGeneratorFixtures.validateRestrictionsSchema()), + OpenApiGeneratorFixtures.validateRestrictionsSchema()), Arguments.of("testSimpleBuild", OpenApiGeneratorFixtures.TEST_SIMPLE_BUILD, - OpenApiGeneratorFixtures.validateSimpleBuild()), + OpenApiGeneratorFixtures.validateSimpleBuild()), Arguments.of("testFormDataMultipartGeneration", OpenApiGeneratorFixtures.TEST_FORM_DATA_MULTIPART_GENERATION, - OpenApiGeneratorFixtures.validateDataMultipartGeneration()) + OpenApiGeneratorFixtures.validateDataMultipartGeneration()) ); } @@ -145,6 +143,6 @@ void processFileSpec(final String type, final List specFileList, final @Test void testExceptionForTestGenerationWithNoOperationId() { Assertions.assertThatThrownBy(() -> openApiGenerator.processFileSpec(OpenApiGeneratorFixtures.TEST_GENERATION_WITH_NO_OPERATION_ID)) - .isInstanceOf(InvalidAPIException.class); + .isInstanceOf(InvalidAPIException.class); } } \ No newline at end of file diff --git a/multiapi-engine/src/test/java/com/sngular/api/generator/test/utils/TestUtils.java b/multiapi-engine/src/test/java/com/sngular/api/generator/test/utils/TestUtils.java index 1a625cd2..f64f26b6 100644 --- a/multiapi-engine/src/test/java/com/sngular/api/generator/test/utils/TestUtils.java +++ b/multiapi-engine/src/test/java/com/sngular/api/generator/test/utils/TestUtils.java @@ -6,6 +6,8 @@ package com.sngular.api.generator.test.utils; +import static org.assertj.core.api.Assertions.assertThat; + import java.io.File; import java.net.URISyntaxException; import java.nio.file.Paths; @@ -14,8 +16,6 @@ import java.util.List; import java.util.Objects; -import static org.assertj.core.api.Assertions.assertThat; - public class TestUtils { public static void validateFiles(final List expectedFiles, final File targetDirectory) throws URISyntaxException { @@ -26,8 +26,8 @@ public static void validateFiles(final List expectedFiles, final File ta outputFiles.removeIf(File::isDirectory); outputFiles.sort(Comparator.comparing(File::getPath)); assertThat(outputFiles) - .overridingErrorMessage("Wrong Number of files %d vs %d: %s", outputFiles.size(), expectedFiles.size(), outputFiles) - .hasSize(expectedFiles.size()); + .overridingErrorMessage("Wrong Number of files %d vs %d: %s", outputFiles.size(), expectedFiles.size(), outputFiles) + .hasSize(expectedFiles.size()); for (int i = 0; i < outputFiles.size(); i++) { reader1 = outputFiles.get(i); assertThat(reader1).overridingErrorMessage("Generated file %s should not be null", outputFiles.get(i)).isNotNull(); @@ -35,7 +35,7 @@ public static void validateFiles(final List expectedFiles, final File ta reader2 = TestUtils.resourceAsFile(sourceName); assertThat(reader2).overridingErrorMessage("Expected file %s should not be null", sourceName).isNotNull(); assertThat(reader1) - .hasSameTextualContentAs(reader2); + .hasSameTextualContentAs(reader2); } } diff --git a/scs-multiapi-gradle-plugin/build.gradle b/scs-multiapi-gradle-plugin/build.gradle index 1bbec931..f0783796 100644 --- a/scs-multiapi-gradle-plugin/build.gradle +++ b/scs-multiapi-gradle-plugin/build.gradle @@ -20,7 +20,7 @@ repositories { } group = 'com.sngular' -version = '6.2.1' +version = '6.3.0' def SCSMultiApiPluginGroupId = group def SCSMultiApiPluginVersion = version @@ -30,7 +30,7 @@ dependencies { shadow localGroovy() shadow gradleApi() - implementation 'com.sngular:multiapi-engine:6.2.1' + implementation 'com.sngular:multiapi-engine:6.3.0' testImplementation 'org.assertj:assertj-core:3.24.2' testImplementation 'com.puppycrawl.tools:checkstyle:10.12.3' testImplementation 'org.junit.platform:junit-platform-launcher:1.9.2' @@ -99,7 +99,7 @@ testing { integrationTest(JvmTestSuite) { dependencies { - implementation 'com.sngular:scs-multiapi-gradle-plugin:6.2.1' + implementation 'com.sngular:scs-multiapi-gradle-plugin:6.3.0' implementation 'org.assertj:assertj-core:3.24.2' } diff --git a/scs-multiapi-maven-plugin/pom.xml b/scs-multiapi-maven-plugin/pom.xml index bdb6824b..65613faf 100644 --- a/scs-multiapi-maven-plugin/pom.xml +++ b/scs-multiapi-maven-plugin/pom.xml @@ -4,7 +4,7 @@ com.sngular scs-multiapi-maven-plugin - 6.2.1 + 6.3.0 maven-plugin AsyncApi - OpenApi Code Generator Maven Plugin @@ -271,7 +271,7 @@ com.sngular multiapi-engine - 6.2.1 + 6.3.0 org.apache.maven From ffe36c26c4ab44f67437b837ada04aa063f46b8a Mon Sep 17 00:00:00 2001 From: Jose Enrique Date: Sun, 30 Nov 2025 02:00:16 +0100 Subject: [PATCH 2/9] Fix path handling for API files --- multiapi-engine/pom.xml | 2 +- .../common/files/ClasspathFileLocation.java | 70 +++++++++++++++---- .../plugin/common/tools/PathUtil.java | 2 +- .../plugin/common/tools/SchemaUtil.java | 17 ++++- .../plugin/common/tools/SchemaUtilTest.java | 45 ++++++++++++ 5 files changed, 119 insertions(+), 17 deletions(-) create mode 100644 multiapi-engine/src/test/java/com/sngular/api/generator/plugin/common/tools/SchemaUtilTest.java diff --git a/multiapi-engine/pom.xml b/multiapi-engine/pom.xml index c531d740..a8704160 100644 --- a/multiapi-engine/pom.xml +++ b/multiapi-engine/pom.xml @@ -11,7 +11,7 @@ 17 17 2.1.12 - 3.15.0 + 3.17.0 2.16.1 4.4 2.17.2 diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/files/ClasspathFileLocation.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/files/ClasspathFileLocation.java index cb362a7f..eb110022 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/files/ClasspathFileLocation.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/files/ClasspathFileLocation.java @@ -22,28 +22,74 @@ public InputStream getFileAtLocation(final String filename) throws IOException { } private static URI resolveInUri(URI parentUri, String relativePath) { - // Check if the path is absolute, and if so, use it directly + // If it's an absolute filesystem path: return directly if (PathUtil.isAbsolutePath(relativePath)) { return Paths.get(relativePath).toUri(); } - if ("jar".equals(parentUri.getScheme())) { - String[] parts = parentUri.getSchemeSpecificPart().split("!", 2); + + String scheme = parentUri.getScheme(); + + if ("jar".equals(scheme)) { + // Extract and + String ssp = parentUri.getSchemeSpecificPart(); + String[] parts = ssp.split("!", 2); if (parts.length != 2) { throw new IllegalArgumentException("Invalid JAR URI: " + parentUri); } - String jarPath = parts[0]; - Path parentInsideJar = Paths.get(parts[1]); - Path resolvedPath = parentInsideJar.resolve(relativePath).normalize(); - return URI.create("jar:" + jarPath + "!" + resolvedPath.toString().replace("\\\\", "/")); - } else if ("file".equals(parentUri.getScheme())) { - Path parentPath = Paths.get(parentUri); - Path resolved = parentPath.resolve(relativePath).normalize(); + + String jarPath = parts[0]; // already a valid file: URI + String inside = parts[1].replace('\\', '/'); // force forward slashes + + // Resolve inside-JAR path using Path logic + Path baseInsideJar = inside.isEmpty() || "/".equals(inside) + ? Paths.get("") // root of jar + : Paths.get(inside); + + Path resolved = baseInsideJar.resolve(relativePath).normalize(); + + // Build URI-safe entry path **fast** + String entryPath = toJarEntryPath(resolved); + + return URI.create("jar:" + jarPath + "!" + entryPath); + } + + // Normal filesystem file: + if ("file".equals(scheme)) { + Path parent = Paths.get(parentUri); + Path resolved = parent.resolve(relativePath).normalize(); return resolved.toUri(); - } else { - throw new IllegalArgumentException("Unsupported URI scheme: " + parentUri.getScheme()); } + + throw new IllegalArgumentException("Unsupported URI scheme: " + scheme); + } + + /** + * Converts a Path to a JAR-entry-safe path string using '/' separators. + * No streams, no iteration overhead, extremely fast. + */ + private static String toJarEntryPath(Path path) { + int nameCount = path.getNameCount(); + + // Root of the jar → just "/" + if (nameCount == 0) { + return "/"; + } + + // Estimate length to reduce reallocations + StringBuilder sb = new StringBuilder(path.toString().length() + nameCount + 2); + sb.append('/'); + + for (int i = 0; i < nameCount; i++) { + sb.append(path.getName(i)); + if (i < nameCount - 1) { + sb.append('/'); + } + } + + return sb.toString(); } + @Override public URI path() { return URI.create(path.toString()); diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/PathUtil.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/PathUtil.java index 18d36b7c..2c8eee6c 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/PathUtil.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/PathUtil.java @@ -21,7 +21,7 @@ private PathUtil() { } /** - * Checks if a file path is absolute. An absolute path is platform-dependent: - On Windows: C:\path, D:\path, \\server\share (UNC) - On Unix/Linux: /path + * Checks if a file path is absolute. An absolute path is platform-dependent: - On Windows: C:\\path, D:\\path, \\\\server\\share (UNC) - On Unix/Linux: /path * * @param filePath the file path to check * @return true if the path is absolute, false if relative or invalid diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/SchemaUtil.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/SchemaUtil.java index 4bc7d6c5..b713e150 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/SchemaUtil.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/SchemaUtil.java @@ -6,6 +6,8 @@ import java.net.MalformedURLException; import java.net.URI; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.Map; import java.util.Objects; @@ -69,9 +71,18 @@ private static String readFile(final URI rootFilePath, final String filePath) th // For absolute paths, convert directly to URL without resolving against rootFilePath fileURL = Paths.get(filePath).toUri().toURL(); } else { - // For relative paths, resolve against the root file path - final var parentFolder = rootFilePath.resolve(cleanUpPath(filePath)); - fileURL = parentFolder.toURL(); + try { + // Resolve against the root file path using Path to handle backslashes and .. properly + final Path rootPath = Paths.get(rootFilePath); + final Path base = Files.isDirectory(rootPath) ? rootPath : (rootPath.getParent() != null ? rootPath.getParent() : rootPath); + final Path resolved = base.resolve(filePath).normalize(); + fileURL = resolved.toUri().toURL(); + } catch (final Exception e) { + // Fallback: try to normalize slashes and resolve via URI (less preferred) + final String cleaned = cleanUpPath(filePath).replace('\\', '/'); + final URI resolvedUri = rootFilePath.resolve(cleaned); + fileURL = resolvedUri.toURL(); + } } } final var sb = new StringBuilder(); diff --git a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/common/tools/SchemaUtilTest.java b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/common/tools/SchemaUtilTest.java new file mode 100644 index 00000000..b28d25c8 --- /dev/null +++ b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/common/tools/SchemaUtilTest.java @@ -0,0 +1,45 @@ +package com.sngular.api.generator.plugin.common.tools; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; + +import com.fasterxml.jackson.databind.JsonNode; +import org.junit.jupiter.api.Test; + +class SchemaUtilTest { + + @Test + void shouldResolveBackslashRelativePath() throws Exception { + final Path tmp = Files.createTempDirectory("schema-util-test"); + try { + // Estructura: tmp/module/sub/root.yml y tmp/api-contract/openapi.yml + final Path moduleSub = tmp.resolve("module").resolve("sub"); + Files.createDirectories(moduleSub); + final Path rootFile = moduleSub.resolve("root.yml"); + Files.writeString(rootFile, "dummy: true"); + + final Path apiContract = tmp.resolve("api-contract"); + Files.createDirectories(apiContract); + final Path openapiFile = apiContract.resolve("openapi.yml"); + final String openapiContent = "components:\n schemas:\n Pet:\n type: object\n"; + Files.writeString(openapiFile, openapiContent); + + final URI rootUri = rootFile.toUri(); + // Ruta relativa con backslashes (Windows style) + final String refPath = "..\\..\\api-contract\\openapi.yml"; + final JsonNode node = SchemaUtil.getPojoFromRef(rootUri, refPath); + + assertNotNull(node, "El nodo no debe ser nulo"); + assertTrue(node.has("components"), "Debe contener 'components'"); + assertTrue(node.path("components").has("schemas"), "Debe contener 'schemas' dentro de components"); + assertTrue(node.path("components").path("schemas").has("Pet"), "Debe contener el schema 'Pet'"); + } finally { + // Limpieza (intencionalmente silenciosa) + try { Files.walk(tmp).map(Path::toFile).sorted((a,b)->-a.compareTo(b)).forEach(java.io.File::delete); } catch (Exception ignored) {} + } + } +} From 6727a50000338d2443f34c78bce97eb1a6a27dec Mon Sep 17 00:00:00 2001 From: Jose Enrique Date: Sun, 30 Nov 2025 02:21:42 +0100 Subject: [PATCH 3/9] Fix path handling for API files --- .../plugin/common/tools/ModelBuilder.java | 74 ++++++++++++++++--- .../plugin/common/tools/ModelBuilderTest.java | 46 ++++++++++++ .../assets/OrderDTO.java | 6 +- .../assets/OrderDTO.java | 6 +- 4 files changed, 116 insertions(+), 16 deletions(-) create mode 100644 multiapi-engine/src/test/java/com/sngular/api/generator/plugin/common/tools/ModelBuilderTest.java diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ModelBuilder.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ModelBuilder.java index b1d46b3f..54e39ee7 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ModelBuilder.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ModelBuilder.java @@ -287,7 +287,7 @@ private static List processObjectProperty( antiLoopList.add(typeName); fieldObjectArrayList.addAll(processFieldObjectList(buildingSchema, fieldName, typeName, refSchema, specFile, totalSchemas, compositedSchemas, antiLoopList, baseDir)); - } + } } else if (ApiTool.isEnum(refSchema)) { fieldObjectArrayList.add(processEnumField(fieldName, refSchema, specFile, ApiTool.getEnumValues(refSchema), schema)); } else if (ApiTool.isObject(refSchema) || ApiTool.isComposed(refSchema)) { @@ -782,31 +782,47 @@ private static SchemaFieldObject processEnumField( field.getDataType().setDeepType(dataType); final HashMap enumValuesMap = new HashMap<>(); + final Set usedKeys = new HashSet<>(); for (final var enumValue : enumValues) { - String valueName = enumValue; - valueName = valueName.replace(".", "_DOT_"); + String rawName = enumValue == null ? "" : enumValue; + // Build a normalized, collision-free enum constant name + final String keyBase = normalizeEnumKeyBase(rawName); + String key; switch (dataType) { case TypeConstants.INTEGER: - enumValuesMap.put("INTEGER_" + valueName, enumValue); + key = ensureUnique(usedKeys, "INTEGER_" + keyBase); + enumValuesMap.put(key, enumValue); break; case TypeConstants.LONG: - enumValuesMap.put("LONG_" + valueName, enumValue + "l"); + key = ensureUnique(usedKeys, "LONG_" + keyBase); + enumValuesMap.put(key, enumValue + "l"); break; case TypeConstants.DOUBLE: - enumValuesMap.put("DOUBLE_" + valueName, enumValue); + key = ensureUnique(usedKeys, "DOUBLE_" + keyBase); + enumValuesMap.put(key, enumValue); break; case TypeConstants.FLOAT: - enumValuesMap.put("FLOAT_" + valueName, enumValue + "f"); + key = ensureUnique(usedKeys, "FLOAT_" + keyBase); + enumValuesMap.put(key, enumValue + "f"); break; case TypeConstants.BIG_DECIMAL: - enumValuesMap.put("BIG_DECIMAL_" + valueName, "new BigDecimal(\"" + enumValue + "\")"); + key = ensureUnique(usedKeys, "BIG_DECIMAL_" + keyBase); + enumValuesMap.put(key, "new BigDecimal(\"" + enumValue + "\")"); break; case TypeConstants.STRING: default: - enumValuesMap.put(StringUtils.replace(StringUtils.upperCase(valueName), " ", "_"), - '"' + enumValue + '"'); + // For string-based enums: uppercase and ensure it starts with a non-digit + String candidate = StringUtils.upperCase(keyBase); + if (candidate.isEmpty()) { + candidate = "EMPTY"; + } + if (Character.isDigit(candidate.charAt(0))) { + candidate = "_" + candidate; + } + key = ensureUnique(usedKeys, candidate); + enumValuesMap.put(key, '"' + enumValue + '"'); break; } } @@ -818,6 +834,44 @@ private static SchemaFieldObject processEnumField( return field; } + /** + * Normaliza una cadena para que pueda ser usada como parte de una constante Java: + * - reemplaza puntos por _DOT_ + * - reemplaza cualquier caracter no alfanumérico por '_' + * - colapsa guiones bajos múltiples + * - recorta guiones bajos al inicio/fin + */ + private static String normalizeEnumKeyBase(final String raw) { + if (raw == null) { + return ""; + } + String s = raw.replace(".", "_DOT_"); + // Reemplaza cualquier caracter que no sea letra o dígito por '_' + s = s.replaceAll("[^A-Za-z0-9]", "_"); + // Colapsa múltiples '_' en uno solo + s = s.replaceAll("_+", "_"); + // Elimina '_' iniciales o finales + s = s.replaceAll("^_+|_+$", ""); + // Si queda vacío, devolver placeholder + if (s.isEmpty()) { + return "EMPTY"; + } + return s; + } + + /** + * Añade sufijo numérico si la clave ya existe para garantizar unicidad. + */ + private static String ensureUnique(final Set usedKeys, final String base) { + String candidate = base; + int idx = 1; + while (usedKeys.contains(candidate)) { + candidate = base + "_" + idx++; + } + usedKeys.add(candidate); + return candidate; + } + private static String getImportClass(final String type) { return StringUtils.isNotBlank(type) && !TypeConstants.NO_IMPORT_TYPE.contains(type) ? StringUtils.capitalize(type) : ""; } diff --git a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/common/tools/ModelBuilderTest.java b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/common/tools/ModelBuilderTest.java new file mode 100644 index 00000000..e5eec46e --- /dev/null +++ b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/common/tools/ModelBuilderTest.java @@ -0,0 +1,46 @@ +package com.sngular.api.generator.plugin.common.tools; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.nio.file.Path; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.sngular.api.generator.plugin.common.model.CommonSpecFile; +import com.sngular.api.generator.plugin.common.model.SchemaFieldObject; +import com.sngular.api.generator.plugin.common.model.SchemaObject; +import org.junit.jupiter.api.Test; + +public class ModelBuilderTest { + + @Test + void testEnumNormalizationWithHyphen() throws Exception { + final ObjectMapper mapper = new ObjectMapper(); + final String json = "{\"enum\":[\"in-course\",\"other-value\"]}"; + final JsonNode node = mapper.readTree(json); + + final Map totalSchemas = new HashMap<>(); + final Set antiLoop = new HashSet<>(); + final Map composited = new HashMap<>(); + + final CommonSpecFile specFile = CommonSpecFile.builder().modelPackage("com.sngular.test").build(); + + final SchemaObject schemaObject = ModelBuilder.buildSchemaObject(totalSchemas, "Status", node, antiLoop, composited, "parent", specFile, Path.of(".")); + + // For enum schemas ModelBuilder stores the enum field inside the SchemaObject field list + final Optional enumFieldOptional = schemaObject.getFieldObjectList().stream().findFirst(); + assertThat(enumFieldOptional).as("Enum field should be present").isPresent(); + final SchemaFieldObject enumField = enumFieldOptional.get(); + + final Map enumValues = enumField.getEnumValues(); + + // The value "in-course" must produce a constant named IN_COURSE + assertThat(enumValues).containsKey("IN_COURSE"); + assertThat(enumValues).containsEntry("IN_COURSE", '"' + "in-course" + '"'); + } +} diff --git a/multiapi-engine/src/test/resources/asyncapigenerator/v2/testRareCharsGeneration/assets/OrderDTO.java b/multiapi-engine/src/test/resources/asyncapigenerator/v2/testRareCharsGeneration/assets/OrderDTO.java index ee949f5e..03012e2d 100644 --- a/multiapi-engine/src/test/resources/asyncapigenerator/v2/testRareCharsGeneration/assets/OrderDTO.java +++ b/multiapi-engine/src/test/resources/asyncapigenerator/v2/testRareCharsGeneration/assets/OrderDTO.java @@ -19,9 +19,9 @@ public class OrderDTO { @JsonProperty(value ="_new") private New _new; public enum New { - TWO:PIECE:WORKS("two:piece:works"), - THREE:PIECE:WORKS("three:piece:works"), - ONE:PIECE:WORKS("one:piece:works"); + ONE_PIECE_WORKS("one:piece:works"), + TWO_PIECE_WORKS("two:piece:works"), + THREE_PIECE_WORKS("three:piece:works"); private String value; diff --git a/multiapi-engine/src/test/resources/asyncapigenerator/v3/testRareCharsGeneration/assets/OrderDTO.java b/multiapi-engine/src/test/resources/asyncapigenerator/v3/testRareCharsGeneration/assets/OrderDTO.java index ee949f5e..03012e2d 100644 --- a/multiapi-engine/src/test/resources/asyncapigenerator/v3/testRareCharsGeneration/assets/OrderDTO.java +++ b/multiapi-engine/src/test/resources/asyncapigenerator/v3/testRareCharsGeneration/assets/OrderDTO.java @@ -19,9 +19,9 @@ public class OrderDTO { @JsonProperty(value ="_new") private New _new; public enum New { - TWO:PIECE:WORKS("two:piece:works"), - THREE:PIECE:WORKS("three:piece:works"), - ONE:PIECE:WORKS("one:piece:works"); + ONE_PIECE_WORKS("one:piece:works"), + TWO_PIECE_WORKS("two:piece:works"), + THREE_PIECE_WORKS("three:piece:works"); private String value; From 9c0551576e19b9de2461c4f4b628e69bd6bfe2aa Mon Sep 17 00:00:00 2001 From: Jose Enrique Date: Sun, 30 Nov 2025 02:27:40 +0100 Subject: [PATCH 4/9] Fix path handling for API files --- .../v2/testRareCharsGeneration/assets/OrderDTO.java | 2 +- .../v2/testRareCharsGeneration/assets/path.yml | 2 +- .../v3/testRareCharsGeneration/assets/OrderDTO.java | 2 +- .../v3/testRareCharsGeneration/assets/path.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/multiapi-engine/src/test/resources/asyncapigenerator/v2/testRareCharsGeneration/assets/OrderDTO.java b/multiapi-engine/src/test/resources/asyncapigenerator/v2/testRareCharsGeneration/assets/OrderDTO.java index 03012e2d..e2dd8611 100644 --- a/multiapi-engine/src/test/resources/asyncapigenerator/v2/testRareCharsGeneration/assets/OrderDTO.java +++ b/multiapi-engine/src/test/resources/asyncapigenerator/v2/testRareCharsGeneration/assets/OrderDTO.java @@ -20,7 +20,7 @@ public class OrderDTO { private New _new; public enum New { ONE_PIECE_WORKS("one:piece:works"), - TWO_PIECE_WORKS("two:piece:works"), + TWO_PIECE_WORKS("two-piece-works"), THREE_PIECE_WORKS("three:piece:works"); private String value; diff --git a/multiapi-engine/src/test/resources/asyncapigenerator/v2/testRareCharsGeneration/assets/path.yml b/multiapi-engine/src/test/resources/asyncapigenerator/v2/testRareCharsGeneration/assets/path.yml index 42c21867..a59b475a 100644 --- a/multiapi-engine/src/test/resources/asyncapigenerator/v2/testRareCharsGeneration/assets/path.yml +++ b/multiapi-engine/src/test/resources/asyncapigenerator/v2/testRareCharsGeneration/assets/path.yml @@ -35,5 +35,5 @@ components: type: string enum: - "one:piece:works" - - "two:piece:works" + - "two-piece-works" - "three:piece:works" \ No newline at end of file diff --git a/multiapi-engine/src/test/resources/asyncapigenerator/v3/testRareCharsGeneration/assets/OrderDTO.java b/multiapi-engine/src/test/resources/asyncapigenerator/v3/testRareCharsGeneration/assets/OrderDTO.java index 03012e2d..e2dd8611 100644 --- a/multiapi-engine/src/test/resources/asyncapigenerator/v3/testRareCharsGeneration/assets/OrderDTO.java +++ b/multiapi-engine/src/test/resources/asyncapigenerator/v3/testRareCharsGeneration/assets/OrderDTO.java @@ -20,7 +20,7 @@ public class OrderDTO { private New _new; public enum New { ONE_PIECE_WORKS("one:piece:works"), - TWO_PIECE_WORKS("two:piece:works"), + TWO_PIECE_WORKS("two-piece-works"), THREE_PIECE_WORKS("three:piece:works"); private String value; diff --git a/multiapi-engine/src/test/resources/asyncapigenerator/v3/testRareCharsGeneration/assets/path.yml b/multiapi-engine/src/test/resources/asyncapigenerator/v3/testRareCharsGeneration/assets/path.yml index 42c21867..a59b475a 100644 --- a/multiapi-engine/src/test/resources/asyncapigenerator/v3/testRareCharsGeneration/assets/path.yml +++ b/multiapi-engine/src/test/resources/asyncapigenerator/v3/testRareCharsGeneration/assets/path.yml @@ -35,5 +35,5 @@ components: type: string enum: - "one:piece:works" - - "two:piece:works" + - "two-piece-works" - "three:piece:works" \ No newline at end of file From 99d65fac515f13c9deee80928efe93470e0d0fa4 Mon Sep 17 00:00:00 2001 From: Jose Enrique Date: Sun, 30 Nov 2025 02:53:44 +0100 Subject: [PATCH 5/9] Fix path handling for API files --- multiapi-engine/pom.xml | 16 ++++++++++++---- .../common/model/SchemaFieldObjectType.java | 2 +- .../testCoconutSchema/assets/SchemaApi.java | 2 +- .../assets/SchemaMasterApi.java | 2 +- .../testComplexAnyOf/assets/SchemaApi.java | 2 +- .../testComplexAnyOf/assets/SchemaMasterApi.java | 2 +- .../testQueryParam/assets/TestApi.java | 2 +- .../testRestrictionsSchema/assets/SchemaApi.java | 2 +- .../assets/SchemaMasterApi.java | 2 +- .../testSimpleBuild/assets/V1Api.java | 2 +- scs-multiapi-gradle-plugin/build.gradle | 4 ++-- scs-multiapi-maven-plugin/pom.xml | 4 ++-- 12 files changed, 25 insertions(+), 17 deletions(-) diff --git a/multiapi-engine/pom.xml b/multiapi-engine/pom.xml index a8704160..23bec8c7 100644 --- a/multiapi-engine/pom.xml +++ b/multiapi-engine/pom.xml @@ -8,8 +8,8 @@ jar - 17 - 17 + 21 + 21 2.1.12 3.17.0 2.16.1 @@ -69,6 +69,7 @@ org.projectlombok lombok ${lombok.version} + provided org.slf4j @@ -209,10 +210,17 @@ maven-compiler-plugin 3.14.0 - ${maven.compiler.target} - ${maven.compiler.target} + + ${maven.compiler.target} true lines,vars,source + + + org.projectlombok + lombok + ${lombok.version} + + diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaFieldObjectType.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaFieldObjectType.java index f1b5bc0d..72bed1be 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaFieldObjectType.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/model/SchemaFieldObjectType.java @@ -46,7 +46,7 @@ public class SchemaFieldObjectType { new SimpleImmutableEntry<>(TypeConstants.ARRAY, "java.util.List"), new SimpleImmutableEntry<>(TypeConstants.MAP, "java.util.Map"), new SimpleImmutableEntry<>(TypeConstants.BIG_DECIMAL, "java.math.BigDecimal"), - new SimpleImmutableEntry<>(TypeConstants.STRING, "java.util.String"), + new SimpleImmutableEntry<>(TypeConstants.STRING, "java.lang.String"), new SimpleImmutableEntry<>(TypeConstants.LOCALDATE, "java.time.LocalDate"), new SimpleImmutableEntry<>(TypeConstants.LOCALDATETIME, "java.time.LocalDateTime"), new SimpleImmutableEntry<>(TypeConstants.ZONEDDATE, "java.time." + ZONED_DATE_TIME), diff --git a/multiapi-engine/src/test/resources/openapigenerator/testCoconutSchema/assets/SchemaApi.java b/multiapi-engine/src/test/resources/openapigenerator/testCoconutSchema/assets/SchemaApi.java index a62557e1..d38c2b18 100644 --- a/multiapi-engine/src/test/resources/openapigenerator/testCoconutSchema/assets/SchemaApi.java +++ b/multiapi-engine/src/test/resources/openapigenerator/testCoconutSchema/assets/SchemaApi.java @@ -1,6 +1,6 @@ package com.sngular.multifileplugin.testCoconutSchema; -import java.util.String; +import java.lang.String; import java.util.Optional; import java.util.List; import java.util.Map; diff --git a/multiapi-engine/src/test/resources/openapigenerator/testCoconutSchema/assets/SchemaMasterApi.java b/multiapi-engine/src/test/resources/openapigenerator/testCoconutSchema/assets/SchemaMasterApi.java index 85540ca6..6b849ad1 100644 --- a/multiapi-engine/src/test/resources/openapigenerator/testCoconutSchema/assets/SchemaMasterApi.java +++ b/multiapi-engine/src/test/resources/openapigenerator/testCoconutSchema/assets/SchemaMasterApi.java @@ -1,6 +1,6 @@ package com.sngular.multifileplugin.testCoconutSchema; -import java.util.String; +import java.lang.String; import java.util.Optional; import java.util.List; import java.util.Map; diff --git a/multiapi-engine/src/test/resources/openapigenerator/testComplexAnyOf/assets/SchemaApi.java b/multiapi-engine/src/test/resources/openapigenerator/testComplexAnyOf/assets/SchemaApi.java index 4bf11f37..b4b948c3 100644 --- a/multiapi-engine/src/test/resources/openapigenerator/testComplexAnyOf/assets/SchemaApi.java +++ b/multiapi-engine/src/test/resources/openapigenerator/testComplexAnyOf/assets/SchemaApi.java @@ -1,6 +1,6 @@ package com.sngular.multifileplugin.testcomplexanyof.api; -import java.util.String; +import java.lang.String; import java.util.Optional; import java.util.List; import java.util.Map; diff --git a/multiapi-engine/src/test/resources/openapigenerator/testComplexAnyOf/assets/SchemaMasterApi.java b/multiapi-engine/src/test/resources/openapigenerator/testComplexAnyOf/assets/SchemaMasterApi.java index da7830f6..bab17dbc 100644 --- a/multiapi-engine/src/test/resources/openapigenerator/testComplexAnyOf/assets/SchemaMasterApi.java +++ b/multiapi-engine/src/test/resources/openapigenerator/testComplexAnyOf/assets/SchemaMasterApi.java @@ -1,6 +1,6 @@ package com.sngular.multifileplugin.testcomplexanyof.api; -import java.util.String; +import java.lang.String; import java.util.Optional; import java.util.List; import java.util.Map; diff --git a/multiapi-engine/src/test/resources/openapigenerator/testQueryParam/assets/TestApi.java b/multiapi-engine/src/test/resources/openapigenerator/testQueryParam/assets/TestApi.java index e6a54cfa..b83c2dbc 100644 --- a/multiapi-engine/src/test/resources/openapigenerator/testQueryParam/assets/TestApi.java +++ b/multiapi-engine/src/test/resources/openapigenerator/testQueryParam/assets/TestApi.java @@ -1,6 +1,6 @@ package com.sngular.multifileplugin.testQueryParam; -import java.util.String; +import java.lang.String; import java.util.Optional; import java.util.List; import java.util.Map; diff --git a/multiapi-engine/src/test/resources/openapigenerator/testRestrictionsSchema/assets/SchemaApi.java b/multiapi-engine/src/test/resources/openapigenerator/testRestrictionsSchema/assets/SchemaApi.java index db674f74..fc2e4206 100644 --- a/multiapi-engine/src/test/resources/openapigenerator/testRestrictionsSchema/assets/SchemaApi.java +++ b/multiapi-engine/src/test/resources/openapigenerator/testRestrictionsSchema/assets/SchemaApi.java @@ -1,6 +1,6 @@ package com.sngular.multifileplugin.testRestrictionsSchema; -import java.util.String; +import java.lang.String; import java.util.Optional; import java.util.List; import java.util.Map; diff --git a/multiapi-engine/src/test/resources/openapigenerator/testRestrictionsSchema/assets/SchemaMasterApi.java b/multiapi-engine/src/test/resources/openapigenerator/testRestrictionsSchema/assets/SchemaMasterApi.java index 517c8984..700c8b43 100644 --- a/multiapi-engine/src/test/resources/openapigenerator/testRestrictionsSchema/assets/SchemaMasterApi.java +++ b/multiapi-engine/src/test/resources/openapigenerator/testRestrictionsSchema/assets/SchemaMasterApi.java @@ -1,6 +1,6 @@ package com.sngular.multifileplugin.testRestrictionsSchema; -import java.util.String; +import java.lang.String; import java.util.Optional; import java.util.List; import java.util.Map; diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/V1Api.java b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/V1Api.java index 6e7d3148..122b4a32 100644 --- a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/V1Api.java +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/V1Api.java @@ -1,6 +1,6 @@ package com.sngular.multifileplugin.testsimplebuild; -import java.util.String; +import java.lang.String; import java.util.Optional; import java.util.List; import java.util.Map; diff --git a/scs-multiapi-gradle-plugin/build.gradle b/scs-multiapi-gradle-plugin/build.gradle index f0783796..04dd7fb3 100644 --- a/scs-multiapi-gradle-plugin/build.gradle +++ b/scs-multiapi-gradle-plugin/build.gradle @@ -9,8 +9,8 @@ plugins { } java { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } repositories { diff --git a/scs-multiapi-maven-plugin/pom.xml b/scs-multiapi-maven-plugin/pom.xml index 65613faf..0e59c322 100644 --- a/scs-multiapi-maven-plugin/pom.xml +++ b/scs-multiapi-maven-plugin/pom.xml @@ -244,8 +244,8 @@ - 17 - 17 + 21 + 21 UTF-8 3.8.5 3.6.4 From 8b9be932a6d6d9497a2573216c4f4ca47aee9280 Mon Sep 17 00:00:00 2001 From: Jose Enrique Date: Sun, 30 Nov 2025 10:26:20 +0100 Subject: [PATCH 6/9] Bump gradle version --- scs-multiapi-gradle-plugin/gradle.properties | 3 ++- .../gradle/wrapper/gradle-wrapper.jar | Bin 62076 -> 63375 bytes .../gradle/wrapper/gradle-wrapper.properties | 3 ++- scs-multiapi-gradle-plugin/gradlew | 5 ++++- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/scs-multiapi-gradle-plugin/gradle.properties b/scs-multiapi-gradle-plugin/gradle.properties index 57f32e95..13e021b0 100644 --- a/scs-multiapi-gradle-plugin/gradle.properties +++ b/scs-multiapi-gradle-plugin/gradle.properties @@ -1,2 +1,3 @@ org.gradle.daemon=false -name = 'scs-multiapi-gradle-plugin' \ No newline at end of file +name = 'scs-multiapi-gradle-plugin' +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip \ No newline at end of file diff --git a/scs-multiapi-gradle-plugin/gradle/wrapper/gradle-wrapper.jar b/scs-multiapi-gradle-plugin/gradle/wrapper/gradle-wrapper.jar index c1962a79e29d3e0ab67b14947c167a862655af9b..033e24c4cdf41af1ab109bc7f253b2b887023340 100644 GIT binary patch delta 16170 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 delta 14892 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 diff --git a/scs-multiapi-gradle-plugin/gradle/wrapper/gradle-wrapper.properties b/scs-multiapi-gradle-plugin/gradle/wrapper/gradle-wrapper.properties index 17a8ddce..1af9e093 100644 --- a/scs-multiapi-gradle-plugin/gradle/wrapper/gradle-wrapper.properties +++ b/scs-multiapi-gradle-plugin/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/scs-multiapi-gradle-plugin/gradlew b/scs-multiapi-gradle-plugin/gradlew index aeb74cbb..fcb6fca1 100755 --- a/scs-multiapi-gradle-plugin/gradlew +++ b/scs-multiapi-gradle-plugin/gradlew @@ -130,10 +130,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. From 5d7665c252aa77dfa5a85e8d2f2e826d9466193c Mon Sep 17 00:00:00 2001 From: Jose Enrique Date: Sun, 30 Nov 2025 11:26:48 +0100 Subject: [PATCH 7/9] Update CI-CD --- .github/workflows/maven-pr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven-pr.yml b/.github/workflows/maven-pr.yml index 08048f49..8fa70ffb 100644 --- a/.github/workflows/maven-pr.yml +++ b/.github/workflows/maven-pr.yml @@ -43,10 +43,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v2 with: - java-version: "17" + java-version: "21" distribution: "adopt" - name: Cache Maven packages uses: actions/cache@v4 From 1847e10cb1b6a735cfbabbfd98172e4fb9c3092e Mon Sep 17 00:00:00 2001 From: Jose Enrique Date: Sun, 30 Nov 2025 13:28:11 +0100 Subject: [PATCH 8/9] Update CI-CD --- .../plugin/common/tools/SchemaUtil.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/SchemaUtil.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/SchemaUtil.java index b713e150..5b8fb69a 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/SchemaUtil.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/SchemaUtil.java @@ -63,23 +63,26 @@ private static String readFile(final URI rootFilePath, final String filePath) th if (Objects.isNull(filePath)) { throw new IllegalArgumentException("File Path cannot be empty"); } - // First, try to find the file in the classpath - URL fileURL = SchemaUtil.class.getClassLoader().getResource(filePath); + + // Normalize the incoming filePath: remove leading './' and replace backslashes with forward slashes + final String cleaned = cleanUpPath(filePath).replace('\\', '/'); + + // First, try to find the file in the classpath using the cleaned path + URL fileURL = SchemaUtil.class.getClassLoader().getResource(cleaned); if (Objects.isNull(fileURL)) { - // Check if the path is absolute - if (PathUtil.isAbsolutePath(filePath)) { + // Check if the path is absolute (platform specific) + if (PathUtil.isAbsolutePath(cleaned)) { // For absolute paths, convert directly to URL without resolving against rootFilePath - fileURL = Paths.get(filePath).toUri().toURL(); + fileURL = Paths.get(cleaned).toUri().toURL(); } else { try { - // Resolve against the root file path using Path to handle backslashes and .. properly + // Resolve against the root file path using Path to handle '..' properly final Path rootPath = Paths.get(rootFilePath); final Path base = Files.isDirectory(rootPath) ? rootPath : (rootPath.getParent() != null ? rootPath.getParent() : rootPath); - final Path resolved = base.resolve(filePath).normalize(); + final Path resolved = base.resolve(Paths.get(cleaned)).normalize(); fileURL = resolved.toUri().toURL(); } catch (final Exception e) { - // Fallback: try to normalize slashes and resolve via URI (less preferred) - final String cleaned = cleanUpPath(filePath).replace('\\', '/'); + // Fallback: resolve the cleaned path against the rootFilePath URI final URI resolvedUri = rootFilePath.resolve(cleaned); fileURL = resolvedUri.toURL(); } From da5756580f541853842e24cba66bfd7081ec702a Mon Sep 17 00:00:00 2001 From: Jose Enrique Date: Sun, 30 Nov 2025 14:04:03 +0100 Subject: [PATCH 9/9] chore: update shadow plugin to 8.1.1 and use Gradle wrapper (8.5) in CI --- .github/workflows/gradle-pr.yml | 5 ++++- scs-multiapi-gradle-plugin/build.gradle | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/gradle-pr.yml b/.github/workflows/gradle-pr.yml index c90edfb1..84913fa3 100644 --- a/.github/workflows/gradle-pr.yml +++ b/.github/workflows/gradle-pr.yml @@ -16,7 +16,10 @@ jobs: id: get-version run: | cd scs-multiapi-gradle-plugin - echo "version=$(gradle properties -q | grep "version:" | awk '{print $2}')" | tee $GITHUB_OUTPUT + # Usar el wrapper para asegurar la versión de Gradle configurada en gradle-wrapper.properties + # Ejecutar con flags para salida determinista + version=$(./gradlew --no-daemon --console=plain properties -q | grep "version:" | awk '{print $2}') + echo "version=$version" | tee $GITHUB_OUTPUT - name: Check if plugin version has been published uses: lakuapik/gh-actions-http-status@v1 id: plugin-version-check diff --git a/scs-multiapi-gradle-plugin/build.gradle b/scs-multiapi-gradle-plugin/build.gradle index 04dd7fb3..e941a90d 100644 --- a/scs-multiapi-gradle-plugin/build.gradle +++ b/scs-multiapi-gradle-plugin/build.gradle @@ -5,7 +5,8 @@ plugins { id 'groovy' id 'jvm-test-suite' id 'checkstyle' - id 'com.github.johnrengelman.shadow' version '7.1.2' + // Actualizado a una versión compatible con Gradle 8 + id 'com.github.johnrengelman.shadow' version '8.1.1' } java { @@ -168,4 +169,3 @@ publishing { } } } -