From 31988837cfb5d036dc5e34480fcde9550100d904 Mon Sep 17 00:00:00 2001 From: William Cheng Date: Thu, 27 Feb 2025 15:23:44 +0800 Subject: [PATCH 1/3] add option to rollback accept null values --- bin/configs/spring-cloud-3-with-optional.yaml | 3 ++- .../codegen/languages/SpringCodegen.java | 8 +++++++ .../main/resources/JavaSpring/pojo.mustache | 2 +- .../java/spring/SpringCodegenTest.java | 21 +++++++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/bin/configs/spring-cloud-3-with-optional.yaml b/bin/configs/spring-cloud-3-with-optional.yaml index d9b875f072d3..d3d14bd3119b 100644 --- a/bin/configs/spring-cloud-3-with-optional.yaml +++ b/bin/configs/spring-cloud-3-with-optional.yaml @@ -1,6 +1,6 @@ generatorName: spring library: spring-cloud -outputDir: samples/openapi3/client/petstore/spring-cloud-3-with-optional +outputDir: /tmp/samples/openapi3/client/petstore/spring-cloud-3-with-optional inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml templateDir: modules/openapi-generator/src/main/resources/JavaSpring additionalProperties: @@ -12,3 +12,4 @@ additionalProperties: useSwaggerUI: "false" hideGenerationTimestamp: "true" documentationProvider: none + #optionalAcceptNullable: "false" # default to true diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java index d5466ef16db4..d0184b803d4b 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java @@ -114,6 +114,7 @@ public class SpringCodegen extends AbstractJavaCodegen public static final String USE_REQUEST_MAPPING_ON_CONTROLLER = "useRequestMappingOnController"; public static final String USE_REQUEST_MAPPING_ON_INTERFACE = "useRequestMappingOnInterface"; public static final String USE_SEALED = "useSealed"; + public static final String OPTIONAL_ACCEPT_NULLABLE = "optionalAcceptNullable"; @Getter public enum RequestMappingMode { api_interface("Generate the @RequestMapping annotation on the generated Api Interface."), @@ -167,6 +168,8 @@ public class SpringCodegen extends AbstractJavaCodegen protected boolean generatedConstructorWithRequiredArgs = true; @Getter @Setter protected RequestMappingMode requestMappingMode = RequestMappingMode.controller; + @Getter @Setter + protected boolean optionalAcceptNullable = true; public SpringCodegen() { super(); @@ -271,6 +274,9 @@ public SpringCodegen() { "Whether to generate constructors with required args for models", generatedConstructorWithRequiredArgs)); cliOptions.add(new CliOption(RESOURCE_FOLDER, RESOURCE_FOLDER_DESC).defaultValue(this.getResourceFolder())); + cliOptions.add(CliOption.newBoolean(OPTIONAL_ACCEPT_NULLABLE, + "Use `ofNullable` instead of just `of` to accept null values when using Optional.", + optionalAcceptNullable)); supportedLibraries.put(SPRING_BOOT, "Spring-boot Server application."); supportedLibraries.put(SPRING_CLOUD_LIBRARY, @@ -434,6 +440,8 @@ public void processOpts() { convertPropertyToBooleanAndWriteBack(UNHANDLED_EXCEPTION_HANDLING, this::setUnhandledException); convertPropertyToBooleanAndWriteBack(USE_RESPONSE_ENTITY, this::setUseResponseEntity); + convertPropertyToBooleanAndWriteBack(OPTIONAL_ACCEPT_NULLABLE, this::setOptionalAcceptNullable); + additionalProperties.put("springHttpStatus", new SpringHttpStatusLambda()); convertPropertyToBooleanAndWriteBack(USE_ENUM_CASE_INSENSITIVE, this::setUseEnumCaseInsensitive); diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache index 9ad38706d6ab..ac4d556fd22a 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache @@ -156,7 +156,7 @@ public {{>sealed}}class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}} {{! begin feature: fluent setter methods }} public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) { {{#openApiNullable}} - 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}}; + 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}}; {{/openApiNullable}} {{^openApiNullable}} this.{{name}} = {{name}}; diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java index ef7230270fb8..1c80a75c23fc 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java @@ -5324,4 +5324,25 @@ public void shouldAnnotateNonRequiredFieldsAsNullableWhileNotUsingOpenApiNullabl " @Nullable List nullableContainer)" ); } + + public void shouldNotAcceptNullValues() throws IOException { + SpringCodegen codegen = new SpringCodegen(); + codegen.setLibrary(SPRING_BOOT); + codegen.setUseSpringBoot3(true); + codegen.setUseOptional(true); + codegen.setOptionalAcceptNullable(true); + + Map files = generateFiles(codegen, "src/test/resources/3_0/petstore.yaml"); + var file = files.get("Category.java"); + + JavaFileAssert.assertThat(file) + .fileContains( + "this.id = Optional.of(id);" + ); + JavaFileAssert.assertThat(file) + .fileDoesNotContain( + "this.name = Optional.ofNullable(name);" + ); + + } } From c6cc503ec8a09a44c67790560e7b461db29ac415 Mon Sep 17 00:00:00 2001 From: William Cheng Date: Thu, 27 Feb 2025 15:29:16 +0800 Subject: [PATCH 2/3] update doc --- bin/configs/spring-cloud-3-with-optional.yaml | 2 +- docs/generators/java-camel.md | 1 + docs/generators/spring.md | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/configs/spring-cloud-3-with-optional.yaml b/bin/configs/spring-cloud-3-with-optional.yaml index d3d14bd3119b..7efd4ce223e0 100644 --- a/bin/configs/spring-cloud-3-with-optional.yaml +++ b/bin/configs/spring-cloud-3-with-optional.yaml @@ -1,6 +1,6 @@ generatorName: spring library: spring-cloud -outputDir: /tmp/samples/openapi3/client/petstore/spring-cloud-3-with-optional +outputDir: samples/openapi3/client/petstore/spring-cloud-3-with-optional inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml templateDir: modules/openapi-generator/src/main/resources/JavaSpring additionalProperties: diff --git a/docs/generators/java-camel.md b/docs/generators/java-camel.md index b0285c683b72..f2714febe563 100644 --- a/docs/generators/java-camel.md +++ b/docs/generators/java-camel.md @@ -73,6 +73,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |licenseUrl|The URL of the license| |http://unlicense.org| |modelPackage|package for generated models| |org.openapitools.model| |openApiNullable|Enable OpenAPI Jackson Nullable library. Not supported by `microprofile` library.| |true| +|optionalAcceptNullable|Use `ofNullable` instead of just `of` to accept null values when using Optional.| |true| |parentArtifactId|parent artifactId in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null| |parentGroupId|parent groupId in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null| |parentVersion|parent version in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null| diff --git a/docs/generators/spring.md b/docs/generators/spring.md index d44b91c69be6..954b786ebd13 100644 --- a/docs/generators/spring.md +++ b/docs/generators/spring.md @@ -66,6 +66,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl |licenseUrl|The URL of the license| |http://unlicense.org| |modelPackage|package for generated models| |org.openapitools.model| |openApiNullable|Enable OpenAPI Jackson Nullable library. Not supported by `microprofile` library.| |true| +|optionalAcceptNullable|Use `ofNullable` instead of just `of` to accept null values when using Optional.| |true| |parentArtifactId|parent artifactId in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null| |parentGroupId|parent groupId in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null| |parentVersion|parent version in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null| From 486d826bc289aa5302e6f189ecaa59627b8e0388 Mon Sep 17 00:00:00 2001 From: William Cheng Date: Thu, 27 Feb 2025 16:00:23 +0800 Subject: [PATCH 3/3] update tests --- .../java/spring/SpringCodegenTest.java | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java index 1c80a75c23fc..378ec66140e6 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java @@ -5325,24 +5325,45 @@ public void shouldAnnotateNonRequiredFieldsAsNullableWhileNotUsingOpenApiNullabl ); } + @Test public void shouldNotAcceptNullValues() throws IOException { SpringCodegen codegen = new SpringCodegen(); codegen.setLibrary(SPRING_BOOT); codegen.setUseSpringBoot3(true); codegen.setUseOptional(true); - codegen.setOptionalAcceptNullable(true); + codegen.setOptionalAcceptNullable(false); Map files = generateFiles(codegen, "src/test/resources/3_0/petstore.yaml"); var file = files.get("Category.java"); JavaFileAssert.assertThat(file) .fileContains( - "this.id = Optional.of(id);" + "this.name = Optional.of(name);" ); JavaFileAssert.assertThat(file) .fileDoesNotContain( "this.name = Optional.ofNullable(name);" ); + } + + @Test + public void shouldAcceptNullValues() throws IOException { + SpringCodegen codegen = new SpringCodegen(); + codegen.setLibrary(SPRING_BOOT); + codegen.setUseSpringBoot3(true); + codegen.setUseOptional(true); + //codegen.setOptionalAcceptNullable(true); // default to true + + Map files = generateFiles(codegen, "src/test/resources/3_0/petstore.yaml"); + var file = files.get("Category.java"); + JavaFileAssert.assertThat(file) + .fileContains( + "this.name = Optional.ofNullable(name);" + ); + JavaFileAssert.assertThat(file) + .fileDoesNotContain( + "this.name = Optional.of(name);" + ); } -} +} \ No newline at end of file