Skip to content

Commit 73bdf41

Browse files
authored
[JAVA] add JSpecify @nullable in builder and singleRequestParameter (#24648)
* add jspecify @nullable annotation to builder and toIndentedString for java clients * include more use cases in jspecify.yaml * include more use cases in jspecify.yaml * Regenerate test samples * Regenerate test samples * Fix extra space in webclient single_request_parameter for toIndentedString * Invalid sha for JSONTest.java !!! * Support space at the end of the @nullable annotation to avoid handling @NullableCustom * generate all arg constructor on restTemplate and webclient * Remove @nullable on private toIndentedString Regenerate samples with more tags, useSingleRequestParameter... * Fix unit test * Fix unit test * Add regenerated samples with tags * Add regenerated samples with tags * Force rebuild * Force rebuild * Handling of resttemplate api Nullable arguments * Handling of resttemplate api Nullable arguments * Rollback resttemplate api: not for this PR * Add @nullable on single_request_parameter * Add @nullable on useAbstractionForFiles * Fix unittest * Merge master and fix use useAbstractionForFiles=true for restclient api_test * fix restclient api_test * Add sample for array of file * Fix unit tests
1 parent 37e5901 commit 73bdf41

135 files changed

Lines changed: 8912 additions & 1442 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/samples-java-client-jdk17.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ on:
1111
- samples/client/petstore/java/apache-httpclient-jackson3/**
1212
- samples/client/petstore/java/native-jackson3-jspecify/**
1313
- samples/client/petstore/java/restclient-springBoot4-jackson3-jspecify/**
14+
- samples/client/petstore/java/restclient-springBoot4-jackson3-jspecify-openapiNullable/**
1415
- samples/client/others/java/webclient-sealedInterface/**
1516
- samples/client/others/java/webclient-sealedInterface_3_1/**
1617
- samples/client/petstore/java/webclient-useSingleRequestParameter/**
@@ -30,6 +31,7 @@ on:
3031
- samples/client/petstore/java/apache-httpclient-jackson3/**
3132
- samples/client/petstore/java/native-jackson3-jspecify/**
3233
- samples/client/petstore/java/restclient-springBoot4-jackson3-jspecify/**
34+
- samples/client/petstore/java/restclient-springBoot4-jackson3-jspecify-openapiNullable/**
3335
- samples/client/others/java/webclient-sealedInterface/**
3436
- samples/client/others/java/webclient-sealedInterface_3_1/**
3537
- samples/client/petstore/java/webclient-useSingleRequestParameter/**
@@ -57,6 +59,7 @@ jobs:
5759
- samples/client/petstore/java/restclient-springBoot4-jackson2
5860
- samples/client/petstore/java/restclient-springBoot4-jackson3
5961
- samples/client/petstore/java/restclient-springBoot4-jackson3-jspecify
62+
- samples/client/petstore/java/restclient-springBoot4-jackson3-jspecify-openapiNullable
6063
- samples/client/petstore/java/native-jackson3-jspecify
6164
- samples/client/petstore/java/restclient-swagger2
6265
- samples/client/petstore/java/restclient-useSingleRequestParameter

bin/configs/java-native-jackson3-jspecify.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ validateSpec: false
77
additionalProperties:
88
artifactId: petstore-native-jackson3
99
hideGenerationTimestamp: "true"
10-
generateBuilders: true
1110
useReflectionEqualsHashCode: "true"
1211
useJackson3: "true"
1312
openApiNullable: "false"
1413
useJspecify: true
14+
generateBuilders: true
1515
typeMappings:
1616
OffsetDateTime: java.time.Instant
17-
BigDecimal: java.math.BigDecimal
17+
BigDecimal: java.math.BigDecimal
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
generatorName: java
2+
outputDir: samples/client/petstore/java/restclient-springBoot4-jackson3-jspecify-openapiNullable
3+
library: restclient
4+
inputSpec: modules/openapi-generator/src/test/resources/3_0/java/jspecify.yaml
5+
templateDir: modules/openapi-generator/src/main/resources/Java
6+
validateSpec: false
7+
additionalProperties:
8+
artifactId: petstore-restclient
9+
hideGenerationTimestamp: "true"
10+
containerDefaultToNull: "true"
11+
useSpringBoot4: true
12+
useJackson3: true
13+
openApiNullable: true
14+
useJspecify: true
15+
generateBuilders: true
16+
generateConstructorWithAllArgs: true
17+
useSingleRequestParameter: true
18+
useTags: true
19+
typeMappings:
20+
OffsetDateTime: java.time.Instant
21+
BigDecimal: java.math.BigDecimal

bin/configs/java-restclient-springBoot4-jackson3-jspecify.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ additionalProperties:
1212
useJackson3: true
1313
openApiNullable: false
1414
useJspecify: true
15+
generateBuilders: true
16+
generateConstructorWithAllArgs: true
17+
useSingleRequestParameter: true
18+
useAbstractionForFiles: true
19+
useTags: true
1520
typeMappings:
1621
OffsetDateTime: java.time.Instant
1722
BigDecimal: java.math.BigDecimal

bin/configs/java-resttemplate-springBoot4-jackson2.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,3 @@ additionalProperties:
99
containerDefaultToNull: "true"
1010
useJakartaEe: true
1111
useSpringBoot4: true
12-

bin/configs/java-resttemplate-springBoot4-jackson3-jspecify.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ additionalProperties:
1313
useJackson3: true
1414
openApiNullable: false
1515
useJspecify: true
16+
generateBuilders: true
17+
generateConstructorWithAllArgs: true
18+
useSingleRequestParameter: true
19+
useTags: true
1620
typeMappings:
1721
OffsetDateTime: java.time.Instant
1822
BigDecimal: java.math.BigDecimal

bin/configs/java-webclient-springBoot4-jackson3-jspecify.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ additionalProperties:
1212
useJackson3: true
1313
openApiNullable: false
1414
useJspecify: true
15+
generateBuilders: true
16+
generateConstructorWithAllArgs: true
17+
useSingleRequestParameter: true
18+
useAbstractionForFiles: true
1519
typeMappings:
1620
OffsetDateTime: java.time.Instant
1721
BigDecimal: java.math.BigDecimal

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2895,9 +2895,11 @@ public void execute(Template.Fragment fragment, Writer writer) throws IOExceptio
28952895
keptNullable = null;
28962896
String value = fragment.execute();
28972897
if (useJspecify) {
2898-
if (value.startsWith(nullableAnnotation)) {
2898+
// extract @Nullable annotation (starting with @ and ending with space)
2899+
String patternToFind = nullableAnnotation + " ";
2900+
if (value.startsWith(patternToFind)) {
28992901
keptNullable = value;
2900-
int idx = nullableAnnotation.length();
2902+
int idx = patternToFind.length();
29012903
// trim left
29022904
while (idx < value.length() && value.charAt(idx) == ' ') {
29032905
idx ++;

modules/openapi-generator/src/main/resources/Java/javaBuilder.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public static class Builder {{#parentModel}}extends {{classname}}.Builder {{/par
1414
}
1515

1616
{{#vars}}
17-
public {{classname}}.Builder {{name}}({{#removeAnnotations}}{{{datatypeWithEnum}}}{{/removeAnnotations}} {{name}}) {
17+
public {{classname}}.Builder {{name}}({{>nullableArgument_builder}} {{name}}) {
1818
{{#vendorExtensions.x-is-jackson-optional-nullable}}
1919
this.instance.{{name}} = JsonNullable.<{{#removeAnnotations}}{{{datatypeWithEnum}}}{{/removeAnnotations}}>of({{name}});
2020
{{/vendorExtensions.x-is-jackson-optional-nullable}}
@@ -32,7 +32,7 @@ public static class Builder {{#parentModel}}extends {{classname}}.Builder {{/par
3232
{{/vars}}
3333

3434
{{#parentVars}}
35-
public {{classname}}.Builder {{name}}({{#removeAnnotations}}{{{datatypeWithEnum}}}{{/removeAnnotations}} {{name}}) { // inherited: {{isInherited}}
35+
public {{classname}}.Builder {{name}}({{>nullableArgument_builder}} {{name}}) { // inherited: {{isInherited}}
3636
super.{{name}}({{name}});
3737
return this;
3838
}

modules/openapi-generator/src/main/resources/Java/libraries/restclient/api.mustache

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public class {{classname}} {
7777
* @see <a href="{{url}}">{{summary}} Documentation</a>
7878
{{/externalDocs}}
7979
*/
80-
private ResponseSpec {{operationId}}RequestCreation({{#allParams}}{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.Resource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.Resource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{>nullableArgument}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{>nullableArgument}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws RestClientResponseException {
80+
private ResponseSpec {{operationId}}RequestCreation({{#allParams}}{{>nullableArgumentForApi}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws RestClientResponseException {
8181
Object postBody = {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}};
8282
{{#allParams}}
8383
{{#required}}
@@ -180,7 +180,7 @@ public class {{classname}} {
180180
{{#isDeprecated}}
181181
@Deprecated
182182
{{/isDeprecated}}
183-
public {{#returnType}}{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{returnType}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{returnType}}}{{/isResponseFile}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.Resource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.Resource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{>nullableArgument}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{>nullableArgument}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws RestClientResponseException {
183+
public {{#returnType}}{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{returnType}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{returnType}}}{{/isResponseFile}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{>nullableArgumentForApi}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws RestClientResponseException {
184184
{{#returnType}}ParameterizedTypeReference<{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{returnType}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{returnType}}}{{/isResponseFile}}> localVarReturnType = new ParameterizedTypeReference<>() {};{{/returnType}}{{^returnType}}ParameterizedTypeReference<Void> localVarReturnType = new ParameterizedTypeReference<>() {};{{/returnType}}
185185
{{#returnType}}return {{/returnType}}{{operationId}}RequestCreation({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}).body(localVarReturnType);
186186
}
@@ -203,7 +203,7 @@ public class {{classname}} {
203203
{{#isDeprecated}}
204204
@Deprecated
205205
{{/isDeprecated}}
206-
public {{#returnType}}ResponseEntity<{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{returnType}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{returnType}}}{{/isResponseFile}}>{{/returnType}}{{^returnType}}ResponseEntity<Void>{{/returnType}} {{operationId}}WithHttpInfo({{#allParams}}{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.Resource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.Resource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{>nullableArgument}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{>nullableArgument}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws RestClientResponseException {
206+
public {{#returnType}}ResponseEntity<{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{returnType}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{returnType}}}{{/isResponseFile}}>{{/returnType}}{{^returnType}}ResponseEntity<Void>{{/returnType}} {{operationId}}WithHttpInfo({{#allParams}}{{>nullableArgumentForApi}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws RestClientResponseException {
207207
{{#returnType}}ParameterizedTypeReference<{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{returnType}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{returnType}}}{{/isResponseFile}}> localVarReturnType = new ParameterizedTypeReference<>() {};{{/returnType}}{{^returnType}}ParameterizedTypeReference<Void> localVarReturnType = new ParameterizedTypeReference<>() {};{{/returnType}}
208208
return {{operationId}}RequestCreation({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}).toEntity(localVarReturnType);
209209
}
@@ -227,7 +227,7 @@ public class {{classname}} {
227227
{{#isDeprecated}}
228228
@Deprecated
229229
{{/isDeprecated}}
230-
public ResponseSpec {{operationId}}WithResponseSpec({{#allParams}}{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.Resource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.Resource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{>nullableArgument}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{>nullableArgument}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws RestClientResponseException {
230+
public ResponseSpec {{operationId}}WithResponseSpec({{#allParams}}{{>nullableArgumentForApi}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws RestClientResponseException {
231231
return {{operationId}}RequestCreation({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
232232
}
233233
{{/operation}}

0 commit comments

Comments
 (0)