diff --git a/bin/configs/java-micronaut-client.yaml b/bin/configs/java-micronaut-client.yaml index bf0720a69131..247c139afb44 100644 --- a/bin/configs/java-micronaut-client.yaml +++ b/bin/configs/java-micronaut-client.yaml @@ -8,3 +8,4 @@ additionalProperties: build: "all" test: "spock" requiredPropertiesInConstructor: "false" + visitable: "true" diff --git a/docs/generators/java-micronaut-client.md b/docs/generators/java-micronaut-client.md index 93cd69d91005..65a92b40c6fd 100644 --- a/docs/generators/java-micronaut-client.md +++ b/docs/generators/java-micronaut-client.md @@ -73,6 +73,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |title|Client service name| |null| |useBeanValidation|Use BeanValidation API annotations| |true| |useOptional|Use Optional container for optional parameters| |false| +|visitable|Generate visitor for subtypes with a discriminator| |false| |withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false| ## SUPPORTED VENDOR EXTENSIONS diff --git a/docs/generators/java-micronaut-server.md b/docs/generators/java-micronaut-server.md index 08a13ffb624a..6cfb9b58fa12 100644 --- a/docs/generators/java-micronaut-server.md +++ b/docs/generators/java-micronaut-server.md @@ -75,6 +75,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |useAuth|Whether to import authorization and to annotate controller methods accordingly| |true| |useBeanValidation|Use BeanValidation API annotations| |true| |useOptional|Use Optional container for optional parameters| |false| +|visitable|Generate visitor for subtypes with a discriminator| |false| |withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false| ## SUPPORTED VENDOR EXTENSIONS diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaMicronautAbstractCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaMicronautAbstractCodegen.java index 6ef455d894fc..29ea5e7f3cdf 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaMicronautAbstractCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaMicronautAbstractCodegen.java @@ -28,6 +28,7 @@ public abstract class JavaMicronautAbstractCodegen extends AbstractJavaCodegen i public static final String OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR = "requiredPropertiesInConstructor"; public static final String OPT_MICRONAUT_VERSION = "micronautVersion"; public static final String OPT_USE_AUTH = "useAuth"; + public static final String OPT_VISITABLE = "visitable"; public static final String OPT_DATE_LIBRARY_JAVA8 = "java8"; public static final String OPT_DATE_LIBRARY_JAVA8_LOCAL_DATETIME = "java8-localdatetime"; public static final String OPT_DATE_FORMAT = "dateFormat"; @@ -36,6 +37,7 @@ public abstract class JavaMicronautAbstractCodegen extends AbstractJavaCodegen i protected String title; protected boolean useBeanValidation; protected boolean useOptional; + protected boolean visitable; protected String buildTool; protected String testTool; protected boolean requiredPropertiesInConstructor = true; @@ -55,6 +57,7 @@ public JavaMicronautAbstractCodegen() { // Set all the fields useBeanValidation = true; useOptional = false; + visitable = false; buildTool = OPT_BUILD_ALL; testTool = OPT_TEST_JUNIT; outputFolder = "generated-code/java-micronaut-client"; @@ -99,6 +102,7 @@ public JavaMicronautAbstractCodegen() { cliOptions.add(new CliOption(OPT_MICRONAUT_VERSION, "Micronaut version, only >=3.0.0 versions are supported").defaultValue(micronautVersion)); cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations", useBeanValidation)); cliOptions.add(CliOption.newBoolean(USE_OPTIONAL, "Use Optional container for optional parameters", useOptional)); + cliOptions.add(CliOption.newBoolean(OPT_VISITABLE, "Generate visitor for subtypes with a discriminator", visitable)); cliOptions.add(CliOption.newBoolean(OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR, "Allow only to create models with all the required properties provided in constructor", requiredPropertiesInConstructor)); CliOption buildToolOption = new CliOption(OPT_BUILD, "Specify for which build tool to generate files").defaultValue(buildTool); @@ -167,6 +171,11 @@ public void processOpts() { } writePropertyBack(USE_OPTIONAL, useOptional); + if (additionalProperties.containsKey(OPT_VISITABLE)) { + this.setVisitable(convertPropertyToBoolean(OPT_VISITABLE)); + } + writePropertyBack(OPT_VISITABLE, visitable); + if (additionalProperties.containsKey(OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR)) { this.requiredPropertiesInConstructor = convertPropertyToBoolean(OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR); } @@ -320,6 +329,10 @@ public void setUseOptional(boolean useOptional) { this.useOptional = useOptional; } + public void setVisitable(boolean visitable) { + this.visitable = visitable; + } + @Override public String toApiVarName(String name) { String apiVarName = super.toApiVarName(name); @@ -337,6 +350,10 @@ public boolean isUseOptional() { return useOptional; } + public boolean isVisitable() { + return visitable; + } + @Override public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List allModels) { objs = super.postProcessOperationsWithModels(objs, allModels); diff --git a/modules/openapi-generator/src/main/resources/java-micronaut/common/model/pojo.mustache b/modules/openapi-generator/src/main/resources/java-micronaut/common/model/pojo.mustache index 254dfff365ff..ebae2af0124c 100644 --- a/modules/openapi-generator/src/main/resources/java-micronaut/common/model/pojo.mustache +++ b/modules/openapi-generator/src/main/resources/java-micronaut/common/model/pojo.mustache @@ -355,4 +355,36 @@ Declare the class with extends and implements } }; {{/parcelableModel}} + {{#visitable}} + {{#discriminator}} + /** + * Accept the visitor and invoke it for the specific {{classname}} type. + * + * @param visitor the {{classname}} visitor + * @param the return type of the visitor + * @return the result from the visitor + */ + public abstract T accept(Visitor visitor); + + /** + * A {{classname}} visitor implementation allows visiting the various {{classname}} types. + * + * @param the return type of the visitor + */ + public interface Visitor { + {{#discriminator.mappedModels}} + R visit{{modelName}}({{modelName}} value); + {{/discriminator.mappedModels}} + } + + {{/discriminator}} + {{#parent}} + {{#interfaces.0}} + @Override + public T accept({{{parent}}}.Visitor visitor) { + return visitor.visit{{classname}}(this); + } + {{/interfaces.0}} + {{/parent}} + {{/visitable}} } \ No newline at end of file diff --git a/samples/client/petstore/java-micronaut-client/src/main/java/org/openapitools/model/Animal.java b/samples/client/petstore/java-micronaut-client/src/main/java/org/openapitools/model/Animal.java index ecff8e9eebd7..f8515029ed3a 100644 --- a/samples/client/petstore/java-micronaut-client/src/main/java/org/openapitools/model/Animal.java +++ b/samples/client/petstore/java-micronaut-client/src/main/java/org/openapitools/model/Animal.java @@ -141,4 +141,24 @@ private String toIndentedString(Object o) { return o.toString().replace("\n", "\n "); } + /** + * Accept the visitor and invoke it for the specific Animal type. + * + * @param visitor the Animal visitor + * @param the return type of the visitor + * @return the result from the visitor + */ + public abstract T accept(Visitor visitor); + + /** + * A Animal visitor implementation allows visiting the various Animal types. + * + * @param the return type of the visitor + */ + public interface Visitor { + R visitBigCat(BigCat value); + R visitCat(Cat value); + R visitDog(Dog value); + } + } diff --git a/samples/client/petstore/java-micronaut-client/src/main/java/org/openapitools/model/BigCat.java b/samples/client/petstore/java-micronaut-client/src/main/java/org/openapitools/model/BigCat.java index aa47991c28eb..2b32767ca005 100644 --- a/samples/client/petstore/java-micronaut-client/src/main/java/org/openapitools/model/BigCat.java +++ b/samples/client/petstore/java-micronaut-client/src/main/java/org/openapitools/model/BigCat.java @@ -138,4 +138,8 @@ private String toIndentedString(Object o) { return o.toString().replace("\n", "\n "); } + @Override + public T accept(Cat.Visitor visitor) { + return visitor.visitBigCat(this); + } } diff --git a/samples/client/petstore/java-micronaut-client/src/main/java/org/openapitools/model/Cat.java b/samples/client/petstore/java-micronaut-client/src/main/java/org/openapitools/model/Cat.java index 3c54e82990f3..27967982a7f2 100644 --- a/samples/client/petstore/java-micronaut-client/src/main/java/org/openapitools/model/Cat.java +++ b/samples/client/petstore/java-micronaut-client/src/main/java/org/openapitools/model/Cat.java @@ -103,4 +103,8 @@ private String toIndentedString(Object o) { return o.toString().replace("\n", "\n "); } + @Override + public T accept(Animal.Visitor visitor) { + return visitor.visitCat(this); + } } diff --git a/samples/client/petstore/java-micronaut-client/src/main/java/org/openapitools/model/Dog.java b/samples/client/petstore/java-micronaut-client/src/main/java/org/openapitools/model/Dog.java index 08f0f4c5bb7d..fd967f283601 100644 --- a/samples/client/petstore/java-micronaut-client/src/main/java/org/openapitools/model/Dog.java +++ b/samples/client/petstore/java-micronaut-client/src/main/java/org/openapitools/model/Dog.java @@ -103,4 +103,8 @@ private String toIndentedString(Object o) { return o.toString().replace("\n", "\n "); } + @Override + public T accept(Animal.Visitor visitor) { + return visitor.visitDog(this); + } }