Skip to content

Commit 178ca12

Browse files
auke-rk0n
authored andcommitted
[java-micronaut] Support Optional for non-required properties (OpenAPITools#12144)
The Micronaut generator by default adds the @nullable annotation to non-required properties and allows using the Jackson JsonNullable wrapper but it is not possible to use java.util.Optional as a wrapper for optional properties. This change adds support for using the Optional wrapper for non-required properties.
1 parent eb36fc7 commit 178ca12

File tree

6 files changed

+37
-4
lines changed

6 files changed

+37
-4
lines changed

docs/generators/java-micronaut-client.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
7272
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
7373
|title|Client service name| |null|
7474
|useBeanValidation|Use BeanValidation API annotations| |true|
75+
|useOptional|Use Optional container for optional parameters| |false|
7576
|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|
7677

7778
## SUPPORTED VENDOR EXTENSIONS

docs/generators/java-micronaut-server.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
7474
|title|Client service name| |null|
7575
|useAuth|Whether to import authorization and to annotate controller methods accordingly| |true|
7676
|useBeanValidation|Use BeanValidation API annotations| |true|
77+
|useOptional|Use Optional container for optional parameters| |false|
7778
|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|
7879

7980
## SUPPORTED VENDOR EXTENSIONS

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaMicronautAbstractCodegen.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.apache.commons.lang3.StringUtils;
44
import org.openapitools.codegen.*;
55
import org.openapitools.codegen.languages.features.BeanValidationFeatures;
6+
import org.openapitools.codegen.languages.features.OptionalFeatures;
67
import org.openapitools.codegen.meta.features.DocumentationFeature;
78
import org.openapitools.codegen.meta.features.SecurityFeature;
89
import org.openapitools.codegen.model.ModelMap;
@@ -15,7 +16,7 @@
1516

1617
import static org.openapitools.codegen.CodegenConstants.INVOKER_PACKAGE;
1718

18-
public abstract class JavaMicronautAbstractCodegen extends AbstractJavaCodegen implements BeanValidationFeatures {
19+
public abstract class JavaMicronautAbstractCodegen extends AbstractJavaCodegen implements BeanValidationFeatures, OptionalFeatures {
1920
public static final String OPT_TITLE = "title";
2021
public static final String OPT_BUILD = "build";
2122
public static final String OPT_BUILD_GRADLE = "gradle";
@@ -34,6 +35,7 @@ public abstract class JavaMicronautAbstractCodegen extends AbstractJavaCodegen i
3435

3536
protected String title;
3637
protected boolean useBeanValidation;
38+
protected boolean useOptional;
3739
protected String buildTool;
3840
protected String testTool;
3941
protected boolean requiredPropertiesInConstructor = true;
@@ -52,6 +54,7 @@ public JavaMicronautAbstractCodegen() {
5254

5355
// Set all the fields
5456
useBeanValidation = true;
57+
useOptional = false;
5558
buildTool = OPT_BUILD_ALL;
5659
testTool = OPT_TEST_JUNIT;
5760
outputFolder = "generated-code/java-micronaut-client";
@@ -95,6 +98,7 @@ public JavaMicronautAbstractCodegen() {
9598
cliOptions.add(new CliOption(OPT_TITLE, "Client service name").defaultValue(title));
9699
cliOptions.add(new CliOption(OPT_MICRONAUT_VERSION, "Micronaut version, only >=3.0.0 versions are supported").defaultValue(micronautVersion));
97100
cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations", useBeanValidation));
101+
cliOptions.add(CliOption.newBoolean(USE_OPTIONAL, "Use Optional container for optional parameters", useOptional));
98102
cliOptions.add(CliOption.newBoolean(OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR, "Allow only to create models with all the required properties provided in constructor", requiredPropertiesInConstructor));
99103

100104
CliOption buildToolOption = new CliOption(OPT_BUILD, "Specify for which build tool to generate files").defaultValue(buildTool);
@@ -158,6 +162,11 @@ public void processOpts() {
158162
}
159163
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);
160164

165+
if (additionalProperties.containsKey(USE_OPTIONAL)) {
166+
this.setUseOptional(convertPropertyToBoolean(USE_OPTIONAL));
167+
}
168+
writePropertyBack(USE_OPTIONAL, useOptional);
169+
161170
if (additionalProperties.containsKey(OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR)) {
162171
this.requiredPropertiesInConstructor = convertPropertyToBoolean(OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR);
163172
}
@@ -306,6 +315,11 @@ public void setUseBeanValidation(boolean useBeanValidation) {
306315
this.useBeanValidation = useBeanValidation;
307316
}
308317

318+
@Override
319+
public void setUseOptional(boolean useOptional) {
320+
this.useOptional = useOptional;
321+
}
322+
309323
@Override
310324
public String toApiVarName(String name) {
311325
String apiVarName = super.toApiVarName(name);
@@ -319,6 +333,10 @@ public boolean isUseBeanValidation() {
319333
return useBeanValidation;
320334
}
321335

336+
public boolean isUseOptional() {
337+
return useOptional;
338+
}
339+
322340
@Override
323341
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> allModels) {
324342
objs = super.postProcessOperationsWithModels(objs, allModels);

modules/openapi-generator/src/main/resources/java-micronaut/common/model/beanValidation.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ validate all pojos and enums
55
nullable & nonnull
66
}}{{#required}}{{#isNullable}} @Nullable
77
{{/isNullable}}{{^isNullable}} @NotNull
8-
{{/isNullable}}{{/required}}{{^required}} @Nullable
9-
{{/required}}{{!
8+
{{/isNullable}}{{/required}}{{^required}}{{^useOptional}} @Nullable
9+
{{/useOptional}}{{/required}}{{!
1010
pattern
1111
}}{{#pattern}}{{^isByteArray}} @Pattern(regexp="{{{pattern}}}")
1212
{{/isByteArray}}{{/pattern}}{{!

modules/openapi-generator/src/main/resources/java-micronaut/common/model/model.mustache

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import org.apache.commons.lang3.builder.HashCodeBuilder;
77
{{/useReflectionEqualsHashCode}}
88
import java.util.Objects;
99
import java.util.Arrays;
10+
{{#useOptional}}
11+
import java.util.Optional;
12+
{{/useOptional}}
1013
{{#imports}}
1114
import {{import}};
1215
{{/imports}}

modules/openapi-generator/src/main/resources/java-micronaut/common/model/pojo.mustache

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ Declare the class with extends and implements
186186
{{/vendorExtensions.x-is-jackson-optional-nullable}}
187187
{{^vendorExtensions.x-is-jackson-optional-nullable}}
188188
{{#jackson}}
189-
{{>common/model/jackson_annotations}}{{/jackson}}{{/vendorExtensions.x-is-jackson-optional-nullable}} public {{{datatypeWithEnum}}} {{getter}}() {
189+
{{>common/model/jackson_annotations}}{{/jackson}}{{/vendorExtensions.x-is-jackson-optional-nullable}} public {{#useOptional}}{{^required}}Optional<{{/required}}{{/useOptional}}{{{datatypeWithEnum}}}{{#useOptional}}{{^required}}>{{/required}}{{/useOptional}} {{getter}}() {
190190
{{#vendorExtensions.x-is-jackson-optional-nullable}}
191191
{{#isReadOnly}}
192192
{{! A readonly attribute doesn't have setter => jackson will set null directly if explicitly returned by API, so make sure we have an empty JsonNullable}} if ({{name}} == null) {
@@ -196,7 +196,17 @@ Declare the class with extends and implements
196196
return {{name}}.orElse(null);
197197
{{/vendorExtensions.x-is-jackson-optional-nullable}}
198198
{{^vendorExtensions.x-is-jackson-optional-nullable}}
199+
{{#useOptional}}
200+
{{#required}}
199201
return {{name}};
202+
{{/required}}
203+
{{^required}}
204+
return Optional.ofNullable({{name}});
205+
{{/required}}
206+
{{/useOptional}}
207+
{{^useOptional}}
208+
return {{name}};
209+
{{/useOptional}}
200210
{{/vendorExtensions.x-is-jackson-optional-nullable}}
201211
}
202212

0 commit comments

Comments
 (0)