Skip to content

Commit 1c3eade

Browse files
authored
[java][spring] Add option optionalAcceptNullable to accept null values (#20746)
* add option to rollback accept null values * update doc * update tests
1 parent fc00a66 commit 1c3eade

File tree

6 files changed

+55
-2
lines changed

6 files changed

+55
-2
lines changed

bin/configs/spring-cloud-3-with-optional.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ additionalProperties:
1212
useSwaggerUI: "false"
1313
hideGenerationTimestamp: "true"
1414
documentationProvider: none
15+
#optionalAcceptNullable: "false" # default to true

docs/generators/java-camel.md

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
7373
|licenseUrl|The URL of the license| |http://unlicense.org|
7474
|modelPackage|package for generated models| |org.openapitools.model|
7575
|openApiNullable|Enable OpenAPI Jackson Nullable library. Not supported by `microprofile` library.| |true|
76+
|optionalAcceptNullable|Use `ofNullable` instead of just `of` to accept null values when using Optional.| |true|
7677
|parentArtifactId|parent artifactId in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null|
7778
|parentGroupId|parent groupId in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null|
7879
|parentVersion|parent version in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null|

docs/generators/spring.md

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
6666
|licenseUrl|The URL of the license| |http://unlicense.org|
6767
|modelPackage|package for generated models| |org.openapitools.model|
6868
|openApiNullable|Enable OpenAPI Jackson Nullable library. Not supported by `microprofile` library.| |true|
69+
|optionalAcceptNullable|Use `ofNullable` instead of just `of` to accept null values when using Optional.| |true|
6970
|parentArtifactId|parent artifactId in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null|
7071
|parentGroupId|parent groupId in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null|
7172
|parentVersion|parent version in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null|

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

+8
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ public class SpringCodegen extends AbstractJavaCodegen
114114
public static final String USE_REQUEST_MAPPING_ON_CONTROLLER = "useRequestMappingOnController";
115115
public static final String USE_REQUEST_MAPPING_ON_INTERFACE = "useRequestMappingOnInterface";
116116
public static final String USE_SEALED = "useSealed";
117+
public static final String OPTIONAL_ACCEPT_NULLABLE = "optionalAcceptNullable";
117118

118119
@Getter public enum RequestMappingMode {
119120
api_interface("Generate the @RequestMapping annotation on the generated Api Interface."),
@@ -167,6 +168,8 @@ public class SpringCodegen extends AbstractJavaCodegen
167168
protected boolean generatedConstructorWithRequiredArgs = true;
168169
@Getter @Setter
169170
protected RequestMappingMode requestMappingMode = RequestMappingMode.controller;
171+
@Getter @Setter
172+
protected boolean optionalAcceptNullable = true;
170173

171174
public SpringCodegen() {
172175
super();
@@ -271,6 +274,9 @@ public SpringCodegen() {
271274
"Whether to generate constructors with required args for models",
272275
generatedConstructorWithRequiredArgs));
273276
cliOptions.add(new CliOption(RESOURCE_FOLDER, RESOURCE_FOLDER_DESC).defaultValue(this.getResourceFolder()));
277+
cliOptions.add(CliOption.newBoolean(OPTIONAL_ACCEPT_NULLABLE,
278+
"Use `ofNullable` instead of just `of` to accept null values when using Optional.",
279+
optionalAcceptNullable));
274280

275281
supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application.");
276282
supportedLibraries.put(SPRING_CLOUD_LIBRARY,
@@ -434,6 +440,8 @@ public void processOpts() {
434440

435441
convertPropertyToBooleanAndWriteBack(UNHANDLED_EXCEPTION_HANDLING, this::setUnhandledException);
436442
convertPropertyToBooleanAndWriteBack(USE_RESPONSE_ENTITY, this::setUseResponseEntity);
443+
convertPropertyToBooleanAndWriteBack(OPTIONAL_ACCEPT_NULLABLE, this::setOptionalAcceptNullable);
444+
437445
additionalProperties.put("springHttpStatus", new SpringHttpStatusLambda());
438446

439447
convertPropertyToBooleanAndWriteBack(USE_ENUM_CASE_INSENSITIVE, this::setUseEnumCaseInsensitive);

modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ public {{>sealed}}class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}}
156156
{{! begin feature: fluent setter methods }}
157157
public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) {
158158
{{#openApiNullable}}
159-
this.{{name}} = {{#isNullable}}JsonNullable.of({{/isNullable}}{{#useOptional}}{{^required}}{{^isNullable}}{{^isContainer}}Optional.ofNullable({{/isContainer}}{{/isNullable}}{{/required}}{{/useOptional}}{{name}}{{#isNullable}}){{/isNullable}}{{#useOptional}}{{^required}}{{^isNullable}}{{^isContainer}}){{/isContainer}}{{/isNullable}}{{/required}}{{/useOptional}};
159+
this.{{name}} = {{#isNullable}}JsonNullable.of({{/isNullable}}{{#useOptional}}{{^required}}{{^isNullable}}{{^isContainer}}Optional.of{{#optionalAcceptNullable}}Nullable{{/optionalAcceptNullable}}({{/isContainer}}{{/isNullable}}{{/required}}{{/useOptional}}{{name}}{{#isNullable}}){{/isNullable}}{{#useOptional}}{{^required}}{{^isNullable}}{{^isContainer}}){{/isContainer}}{{/isNullable}}{{/required}}{{/useOptional}};
160160
{{/openApiNullable}}
161161
{{^openApiNullable}}
162162
this.{{name}} = {{name}};

modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java

+43-1
Original file line numberDiff line numberDiff line change
@@ -5324,4 +5324,46 @@ public void shouldAnnotateNonRequiredFieldsAsNullableWhileNotUsingOpenApiNullabl
53245324
" @Nullable List<String> nullableContainer)"
53255325
);
53265326
}
5327-
}
5327+
5328+
@Test
5329+
public void shouldNotAcceptNullValues() throws IOException {
5330+
SpringCodegen codegen = new SpringCodegen();
5331+
codegen.setLibrary(SPRING_BOOT);
5332+
codegen.setUseSpringBoot3(true);
5333+
codegen.setUseOptional(true);
5334+
codegen.setOptionalAcceptNullable(false);
5335+
5336+
Map<String, File> files = generateFiles(codegen, "src/test/resources/3_0/petstore.yaml");
5337+
var file = files.get("Category.java");
5338+
5339+
JavaFileAssert.assertThat(file)
5340+
.fileContains(
5341+
"this.name = Optional.of(name);"
5342+
);
5343+
JavaFileAssert.assertThat(file)
5344+
.fileDoesNotContain(
5345+
"this.name = Optional.ofNullable(name);"
5346+
);
5347+
}
5348+
5349+
@Test
5350+
public void shouldAcceptNullValues() throws IOException {
5351+
SpringCodegen codegen = new SpringCodegen();
5352+
codegen.setLibrary(SPRING_BOOT);
5353+
codegen.setUseSpringBoot3(true);
5354+
codegen.setUseOptional(true);
5355+
//codegen.setOptionalAcceptNullable(true); // default to true
5356+
5357+
Map<String, File> files = generateFiles(codegen, "src/test/resources/3_0/petstore.yaml");
5358+
var file = files.get("Category.java");
5359+
5360+
JavaFileAssert.assertThat(file)
5361+
.fileContains(
5362+
"this.name = Optional.ofNullable(name);"
5363+
);
5364+
JavaFileAssert.assertThat(file)
5365+
.fileDoesNotContain(
5366+
"this.name = Optional.of(name);"
5367+
);
5368+
}
5369+
}

0 commit comments

Comments
 (0)