{{code}}{{#message}} - {{.}}{{/message}} +{{/responses}} + * + * @param params parameters for the {{operationId}} operation +{{#returnType}} + * @return {{.}} +{{/returnType}} + * @throws RestClientException if an error occurs while attempting to invoke the API +{{#externalDocs}} + * {{description}} + * @see {{summary}} Documentation +{{/externalDocs}} +{{#isDeprecated}} + * @deprecated +{{/isDeprecated}} + */ +{{#isDeprecated}} + @Deprecated +{{/isDeprecated}} + public {{#returnType}}{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{.}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{.}}}{{/isResponseFile}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}( +{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Param params + ) throws RestClientException { +{{#returnType}} + return {{operationId}}WithHttpInfo(params).getBody(); +{{/returnType}} +{{^returnType}} + {{operationId}}WithHttpInfo(params); +{{/returnType}} + } + + /** + * {{summary}} + * {{notes}} +{{#responses}} + *
{{code}}{{#message}} - {{.}}{{/message}}
+{{/responses}}
+ *
+ * @param params parameters for the {{operationId}} operation
+ * @return ResponseEntity<{{returnType}}{{^returnType}}Void{{/returnType}}>
+ * @throws RestClientException if an error occurs while attempting to invoke the API
+{{#externalDocs}}
+ * {{description}}
+ * @see {{summary}} Documentation
+{{/externalDocs}}
+{{#isDeprecated}}
+ * @deprecated
+{{/isDeprecated}}
+ */
+{{#isDeprecated}}
+ @Deprecated
+{{/isDeprecated}}
+ public ResponseEntity<{{#returnType}}{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{.}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{.}}}{{/isResponseFile}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{operationId}}WithHttpInfo(
+ {{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Param params
+ ) throws RestClientException {
+ java.util.Objects.requireNonNull(
+ params,
+ "params must not be null"
+ );
+
+ return {{operationId}}WithHttpInfo(
+ {{#allParams}}
+ params.get{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}(){{^-last}},{{/-last}}
+ {{/allParams}}
+ );
+ }
\ No newline at end of file
diff --git a/boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatJavaCodeGenTests.java b/boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatJavaCodeGenTests.java
index 5d9e49e20..a0ef488ee 100644
--- a/boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatJavaCodeGenTests.java
+++ b/boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatJavaCodeGenTests.java
@@ -7,30 +7,41 @@
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openapitools.codegen.languages.JavaClientCodegen.GENERATE_CLIENT_AS_BEAN;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.stmt.Statement;
import io.swagger.parser.OpenAPIParser;
import io.swagger.v3.parser.core.models.ParseOptions;
import java.io.File;
import java.io.FileNotFoundException;
+import java.nio.file.Path;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.function.Function;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.DefaultGenerator;
+import org.openapitools.codegen.config.CodegenConfigurator;
class BoatJavaCodeGenTests {
static final String PROP_BASE = BoatJavaCodeGenTests.class.getSimpleName() + ".";
static final String TEST_OUTPUT = System.getProperty(PROP_BASE + "output", "target/boat-java-codegen-tests");
+
@Test
void clientOptsUnicity() {
final BoatJavaCodeGen gen = new BoatJavaCodeGen();
@@ -168,4 +179,118 @@ void shouldHonourBeanValidationOption(boolean useBeanValidation) throws FileNotF
assertThat("Expect jakarta Valid import", compilationUnit.getImports().stream().anyMatch(
id -> id.getNameAsString().equals("jakarta.validation.Valid")), is(useBeanValidation));
}
+
+ @Test
+ void shouldGenerateBackwardCompatibleSingleRequestParameterOverloads(@TempDir Path temporaryDirectory) throws FileNotFoundException {
+ ClassOrInterfaceDeclaration api = generateRestTemplateClient(
+ temporaryDirectory.resolve("generated-enabled"),
+ true
+ );
+
+ ClassOrInterfaceDeclaration parameters = findNestedClass(api, "ListPetsParam").orElseThrow();
+ assertTrue(parameters.isStatic());
+ assertTrue(findNestedClass(api, "ShowPetByIdParam").isEmpty());
+
+ findMethod(api, "listPets", "Integer", "String");
+ findMethod(api, "listPetsWithHttpInfo", "Integer", "String");
+
+ MethodDeclaration listPets = findMethod(api, "listPets", "ListPetsParam");
+ assertEquals("listPetsWithHttpInfo(params).getBody()", returnExpression(listPets));
+
+ MethodDeclaration listPetsWithHttpInfo = findMethod(api, "listPetsWithHttpInfo", "ListPetsParam");
+ assertEquals(
+ "listPetsWithHttpInfo(params.getLimit(), params.getStatus())",
+ returnExpression(listPetsWithHttpInfo)
+ );
+ }
+
+ @Test
+ void shouldNotGenerateSingleRequestParameterOverloadsByDefault(
+ @TempDir Path temporaryDirectory
+ ) throws FileNotFoundException {
+ ClassOrInterfaceDeclaration api = generateRestTemplateClient(
+ temporaryDirectory.resolve("generated-disabled"),
+ false
+ );
+
+ assertFalse(findNestedClass(api, "ListPetsParam").isPresent());
+ assertEquals(1, api.getMethodsByName("listPets").size());
+ assertEquals(1, api.getMethodsByName("listPetsWithHttpInfo").size());
+ findMethod(api, "listPets", "Integer", "String");
+ findMethod(api, "listPetsWithHttpInfo", "Integer", "String");
+ }
+
+ private ClassOrInterfaceDeclaration generateRestTemplateClient(Path outputDirectory, boolean useSingleRequestParameter)
+ throws FileNotFoundException {
+ CodegenConfigurator configurator = getCodegenConfigurator(outputDirectory);
+
+ if (useSingleRequestParameter) {
+ configurator.addAdditionalProperty("useSingleRequestParameter", true);
+ }
+
+ File generatedApi = new DefaultGenerator()
+ .opts(configurator.toClientOptInput())
+ .generate()
+ .stream()
+ .filter(file -> file.getName().equals("PetsApi.java"))
+ .findFirst()
+ .orElseThrow();
+
+ return StaticJavaParser.parse(generatedApi)
+ .getClassByName("PetsApi")
+ .orElseThrow();
+ }
+
+ private CodegenConfigurator getCodegenConfigurator(Path outputDirectory) {
+ CodegenConfigurator configurator = new CodegenConfigurator();
+ configurator.setGeneratorName("boat-java");
+ configurator.setLibrary("resttemplate");
+ configurator.setInputSpec(
+ getFile("/boat-java/petstore-single-request-parameter.yaml")
+ .getAbsolutePath()
+ );
+ configurator.setOutputDir(outputDirectory.toAbsolutePath().toString());
+ configurator.setApiPackage("com.example.api");
+ configurator.setModelPackage("com.example.model");
+ return configurator;
+ }
+
+ private static MethodDeclaration findMethod(ClassOrInterfaceDeclaration api, String name, String... parameterTypes) {
+ List