Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[java][client] fix: Add static modifier to inner class in Java when useSingleRequestParameter=true #20590

Merged
merged 4 commits into from
Feb 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/generators/java-microprofile.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useRuntimeException|Use RuntimeException instead of Exception. Only jersey2, jersey3, okhttp-gson, vertx, microprofile support this option.| |false|
|useRxJava2|Whether to use the RxJava2 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option.| |false|
|useSingleRequestParameter|Setting this property to "true" will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option. Setting this property to "static" does the same as "true", but also makes the generated arguments class static. Only WebClient supports this option.| |false|
|webclientBlockingOperations|Making all WebClient operations blocking(sync). Note that if on operation 'x-webclient-blocking: false' then such operation won't be sync| |false|
|withAWSV4Signature|whether to include AWS v4 signature support (only available for okhttp-gson library)| |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|
Expand Down
2 changes: 1 addition & 1 deletion docs/generators/java.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useRuntimeException|Use RuntimeException instead of Exception. Only jersey2, jersey3, okhttp-gson, vertx, microprofile support this option.| |false|
|useRxJava2|Whether to use the RxJava2 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option.| |false|
|useSingleRequestParameter|Setting this property to "true" will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option. Setting this property to "static" does the same as "true", but also makes the generated arguments class static. Only WebClient supports this option.| |false|
|webclientBlockingOperations|Making all WebClient operations blocking(sync). Note that if on operation 'x-webclient-blocking: false' then such operation won't be sync| |false|
|withAWSV4Signature|whether to include AWS v4 signature support (only available for okhttp-gson library)| |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|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
@Setter protected boolean useOneOfDiscriminatorLookup = false; // use oneOf discriminator's mapping for model lookup
protected String rootJavaEEPackage;
protected Map<String, MpRestClientVersion> mpRestClientVersions = new LinkedHashMap<>();
@Setter(AccessLevel.PRIVATE) protected boolean useSingleRequestParameter = false;
@Setter(AccessLevel.PRIVATE) protected String useSingleRequestParameter = "false";
protected boolean webclientBlockingOperations = false;
@Setter protected boolean generateClientAsBean = false;
@Setter protected boolean useEnumCaseInsensitive = false;
Expand Down Expand Up @@ -237,7 +237,7 @@ public JavaClientCodegen() {
cliOptions.add(CliOption.newString(CONFIG_KEY_FROM_CLASS_NAME, "If true, set tag as key in @RegisterRestClient. Default to false. Only `microprofile` supports this option."));
cliOptions.add(CliOption.newBoolean(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP_DESC + " Only jersey2, jersey3, native, okhttp-gson support this option."));
cliOptions.add(CliOption.newString(MICROPROFILE_REST_CLIENT_VERSION, "Version of MicroProfile Rest Client API."));
cliOptions.add(CliOption.newBoolean(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, "Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option."));
cliOptions.add(CliOption.newString(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, "Setting this property to \"true\" will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option. Setting this property to \"static\" does the same as \"true\", but also makes the generated arguments class static. Only WebClient supports this option.").defaultValue("false"));
cliOptions.add(CliOption.newBoolean(WEBCLIENT_BLOCKING_OPERATIONS, "Making all WebClient operations blocking(sync). Note that if on operation 'x-webclient-blocking: false' then such operation won't be sync", this.webclientBlockingOperations));
cliOptions.add(CliOption.newBoolean(GENERATE_CLIENT_AS_BEAN, "For resttemplate, configure whether to create `ApiClient.java` and Apis clients as bean (with `@Component` annotation).", this.generateClientAsBean));
cliOptions.add(CliOption.newBoolean(SUPPORT_URL_QUERY, "Generate toUrlQueryString in POJO (default to true). Available on `native`, `apache-httpclient` libraries."));
Expand Down Expand Up @@ -334,7 +334,9 @@ public void processOpts() {
convertPropertyToBooleanAndWriteBack(USE_RX_JAVA3, this::setUseRxJava3);
convertPropertyToBooleanAndWriteBack(USE_RX_JAVA2, this::setUseRxJava2);
}
convertPropertyToBooleanAndWriteBack(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, this::setUseSingleRequestParameter);
convertPropertyToStringAndWriteBack(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, this::setUseSingleRequestParameter);
writePropertyBack("singleRequestParameter", getSingleRequestParameter());
writePropertyBack("staticRequest", getStaticRequest());

if (!useRxJava && !useRxJava2 && !useRxJava3) {
additionalProperties.put(DO_NOT_USE_RX, true);
Expand Down Expand Up @@ -757,7 +759,7 @@ public void processOpts() {
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> allModels) {
super.postProcessOperationsWithModels(objs, allModels);

if (useSingleRequestParameter && (JERSEY2.equals(getLibrary()) || JERSEY3.equals(getLibrary()) || OKHTTP_GSON.equals(getLibrary()))) {
if (this.getSingleRequestParameter() && (JERSEY2.equals(getLibrary()) || JERSEY3.equals(getLibrary()) || OKHTTP_GSON.equals(getLibrary()))) {
// loop through operations to set x-group-parameters extension to true if useSingleRequestParameter option is enabled
OperationMap operations = objs.getOperations();
if (operations != null) {
Expand Down Expand Up @@ -1123,7 +1125,15 @@ public boolean getUseOneOfDiscriminatorLookup() {
return this.useOneOfDiscriminatorLookup;
}

private boolean getUseSingleRequestParameter() {
public boolean getSingleRequestParameter() {
return "true".equals(getUseSingleRequestParameter()) || "static".equals(getUseSingleRequestParameter());
}

public boolean getStaticRequest() {
return "static".equals(this.getUseSingleRequestParameter());
}

private String getUseSingleRequestParameter() {
return useSingleRequestParameter;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ public interface {{classname}} {
{{#hasProduces}}
@Produces({ {{#produces}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/produces}} })
{{/hasProduces}}
{{^useSingleRequestParameter}}
{{^singleRequestParameter}}
{{^vendorExtensions.x-java-is-response-void}}{{#microprofileServer}}{{> server_operation}}{{/microprofileServer}}{{^microprofileServer}}{{> client_operation}}{{/microprofileServer}}{{/vendorExtensions.x-java-is-response-void}}{{#vendorExtensions.x-java-is-response-void}}{{#microprofileMutiny}}Uni<Void>{{/microprofileMutiny}}{{^microprofileMutiny}}void{{/microprofileMutiny}}{{/vendorExtensions.x-java-is-response-void}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}}, {{/-last}}{{/allParams}}) throws ApiException, ProcessingException;
{{/useSingleRequestParameter}}
{{#useSingleRequestParameter}}
{{/singleRequestParameter}}
{{#singleRequestParameter}}
{{^vendorExtensions.x-java-is-response-void}}{{#microprofileMutiny}}Uni<{{{returnType}}}>{{/microprofileMutiny}}{{^microprofileMutiny}}{{{returnType}}}{{/microprofileMutiny}}{{/vendorExtensions.x-java-is-response-void}}{{#vendorExtensions.x-java-is-response-void}}{{#microprofileMutiny}}Uni<Void>{{/microprofileMutiny}}{{^microprofileMutiny}}void{{/microprofileMutiny}}{{/vendorExtensions.x-java-is-response-void}} {{nickname}}({{#hasNonBodyParams}}@BeanParam {{operationIdCamelCase}}Request request{{/hasNonBodyParams}}{{#bodyParams}}{{#hasNonBodyParams}}, {{/hasNonBodyParams}}{{>bodyParams}}{{/bodyParams}}) throws ApiException, ProcessingException;
{{#hasNonBodyParams}}
public class {{operationIdCamelCase}}Request {
Expand Down Expand Up @@ -114,7 +114,7 @@ public interface {{classname}} {
{{/allParams}}
}
{{/hasNonBodyParams}}
{{/useSingleRequestParameter}}
{{/singleRequestParameter}}
{{/operation}}
}
{{/operations}}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public class {{classname}} {
}

{{#operation}}
{{#useSingleRequestParameter}}
{{#singleRequestParameter}}
{{#hasParams}}
{{^hasSingleParam}}

Expand Down Expand Up @@ -108,7 +108,7 @@ public class {{classname}} {

{{/hasSingleParam}}
{{/hasParams}}
{{/useSingleRequestParameter}}
{{/singleRequestParameter}}
/**
* {{summary}}
* {{notes}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ public class {{classname}} {
this.apiClient = apiClient;
}

{{#operation}}{{#useSingleRequestParameter}}{{#hasParams}}{{^hasSingleParam}}
public class {{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request {
{{#operation}}{{#singleRequestParameter}}{{#hasParams}}{{^hasSingleParam}}
public {{#staticRequest}}static {{/staticRequest}}class {{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request {
{{#allParams}}
private final {{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.AbstractResource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.AbstractResource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}};
{{/allParams}}
Expand Down Expand Up @@ -120,7 +120,7 @@ public class {{classname}} {
return this.{{operationId}}WithResponseSpec({{#allParams}}requestParameters.{{paramName}}(){{^-last}}, {{/-last}}{{/allParams}});
}

{{/hasSingleParam}}{{/hasParams}}{{/useSingleRequestParameter}}
{{/hasSingleParam}}{{/hasParams}}{{/singleRequestParameter}}
/**
* {{summary}}
* {{notes}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3187,7 +3187,7 @@ public void testRestClientWithUseSingleRequestParameter_issue_19406() {
.setLibrary(JavaClientCodegen.RESTCLIENT)
.setAdditionalProperties(Map.of(
CodegenConstants.API_PACKAGE, "xyz.abcdef.api",
CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, true
CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, "true"
))
.setInputSpec("src/test/resources/3_1/java/petstore.yaml")
.setOutputDir(output.toString().replace("\\", "/"));
Expand Down Expand Up @@ -3215,7 +3215,7 @@ public void testDuplicatedOperationId() {
.setLibrary(JavaClientCodegen.RESTCLIENT)
.setAdditionalProperties(Map.of(
CodegenConstants.API_PACKAGE, "xyz.abcdef.api",
CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, true
CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, "true"
))
.setInputSpec("src/test/resources/3_0/duplicated_operationid.yaml")
.setOutputDir(output.toString().replace("\\", "/"));
Expand Down Expand Up @@ -3250,7 +3250,7 @@ public void testDuplicatedOperationId() {
.setLibrary(JavaClientCodegen.WEBCLIENT)
.setAdditionalProperties(Map.of(
CodegenConstants.API_PACKAGE, "xyz.abcdef.api",
CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, true
CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, "true"
))
.setInputSpec("src/test/resources/3_1/java/petstore.yaml")
.setOutputDir(output.toString().replace("\\", "/"));
Expand All @@ -3272,6 +3272,35 @@ public void testDuplicatedOperationId() {
);
}

@Test public void testWebClientWithUseSingleRequestParameter_static() {
final Path output = newTempFolder();
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("java")
.setLibrary(JavaClientCodegen.WEBCLIENT)
.setAdditionalProperties(Map.of(
CodegenConstants.API_PACKAGE, "xyz.abcdef.api",
CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, "static"
))
.setInputSpec("src/test/resources/3_1/java/petstore.yaml")
.setOutputDir(output.toString().replace("\\", "/"));

new DefaultGenerator().opts(configurator.toClientOptInput()).generate();

TestUtils.assertFileContains(
output.resolve("src/main/java/xyz/abcdef/api/PetApi.java"),
"public static class DeletePetRequest {",
"DeletePetRequest(Long petId, String apiKey)",
"Long petId()",
"String apiKey()",
"public Mono<Void> deletePet(DeletePetRequest requestParameters) throws WebClientResponseException {",
"public Mono<ResponseEntity<Void>> deletePetWithHttpInfo(DeletePetRequest requestParameters) throws WebClientResponseException {",
"public ResponseSpec deletePetWithResponseSpec(DeletePetRequest requestParameters) throws WebClientResponseException {",
"public Mono<Void> deletePet(Long petId, String apiKey) throws WebClientResponseException {",
"public Mono<ResponseEntity<Void>> deletePetWithHttpInfo(Long petId, String apiKey) throws WebClientResponseException {",
"public ResponseSpec deletePetWithResponseSpec(Long petId, String apiKey) throws WebClientResponseException {"
);
}

@Test
public void testGenerateParameterId() {
final Path output = newTempFolder();
Expand Down
Loading