Skip to content

Commit eb5bf17

Browse files
authored
Merge pull request #987 from Backbase/986-form-style-query-params
Issue 986 form style query params
2 parents 8ecb928 + 8ca9f2b commit eb5bf17

File tree

4 files changed

+110
-19
lines changed

4 files changed

+110
-19
lines changed

boat-scaffold/src/main/templates/boat-java/libraries/resttemplate/api.mustache

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,12 @@ public class {{classname}} {
131131
final MultiValueMap<String, String> localVarCookieParams = new LinkedMultiValueMap<String, String>();
132132
final MultiValueMap<String, Object> localVarFormParams = new LinkedMultiValueMap<String, Object>();{{#hasQueryParams}}
133133

134-
{{#queryParams}}localVarQueryParams.putAll(apiClient.parameterToMultiValueMap({{#collectionFormat}}ApiClient.CollectionFormat.valueOf("{{{.}}}".toUpperCase(Locale.ROOT)){{/collectionFormat}}{{^collectionFormat}}null{{/collectionFormat}}, "{{baseName}}", {{paramName}}));{{^-last}}
135-
{{/-last}}{{/queryParams}}{{/hasQueryParams}}{{#hasHeaderParams}}
134+
{{#queryParams}}{{#isExplode}}{{#hasVars}}
135+
if ({{paramName}} != null) {
136+
{{#vars}} localVarQueryParams.putAll(apiClient.parameterToMultiValueMap({{#collectionFormat}}ApiClient.CollectionFormat.valueOf("{{{.}}}".toUpperCase(Locale.ROOT)){{/collectionFormat}}{{^collectionFormat}}null{{/collectionFormat}}, "{{baseName}}", {{paramName}}.{{getter}}()));
137+
{{/vars}}}{{/hasVars}}{{^hasVars}}localVarQueryParams.putAll(apiClient.parameterToMultiValueMap({{#collectionFormat}}ApiClient.CollectionFormat.valueOf("{{{.}}}".toUpperCase(Locale.ROOT)){{/collectionFormat}}{{^collectionFormat}}null{{/collectionFormat}}, "{{baseName}}", {{paramName}}));
138+
{{/hasVars}}{{/isExplode}}{{^isExplode}}localVarQueryParams.putAll(apiClient.parameterToMultiValueMap({{#collectionFormat}}ApiClient.CollectionFormat.valueOf("{{{.}}}".toUpperCase(Locale.ROOT)){{/collectionFormat}}{{^collectionFormat}}null{{/collectionFormat}}, "{{baseName}}", {{paramName}}));
139+
{{/isExplode}}{{/queryParams}}{{/hasQueryParams}}{{#hasHeaderParams}}
136140

137141
{{#headerParams}}if ({{paramName}} != null)
138142
localVarHeaderParams.add("{{baseName}}", apiClient.parameterToString({{paramName}}));{{^-last}}

boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatCommonJavaCodeGenTests.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.backbase.oss.codegen.java;
22

3+
import static org.assertj.core.api.Assertions.assertThat;
34
import static org.junit.jupiter.api.Assertions.assertEquals;
45
import static org.junit.jupiter.api.Assertions.assertFalse;
56
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -19,10 +20,12 @@
1920
import java.nio.file.Files;
2021
import java.nio.file.Paths;
2122
import java.util.List;
23+
import java.util.stream.Collectors;
2224
import lombok.SneakyThrows;
2325
import org.apache.commons.io.FileUtils;
2426
import org.apache.commons.lang3.StringUtils;
2527
import org.junit.jupiter.api.BeforeAll;
28+
import org.junit.jupiter.api.Test;
2629
import org.junit.jupiter.params.ParameterizedTest;
2730
import org.junit.jupiter.params.provider.ValueSource;
2831
import org.openapitools.codegen.ClientOptInput;
@@ -49,6 +52,42 @@ void shouldGenerateArrayField(String containerDefaultToNull) {
4952
generateAndAssert(springCodeGen(), containerDefaultToNull);
5053
}
5154

55+
@Test
56+
void shouldExplodePojoQueryParam() throws IOException {
57+
58+
BoatJavaCodeGen codegen = javaCodeGenWithLib(RESTTEMPLATE);
59+
60+
var input = new File("src/test/resources/boat-spring/openapi.yaml");
61+
var outputDir = TEST_OUTPUT + "/shouldExplodePojoQueryParam";
62+
63+
codegen.setInputSpec(input.getAbsolutePath());
64+
codegen.setOutputDir(outputDir);
65+
66+
OpenAPI openApiInput = new OpenAPIParser()
67+
.readLocation(input.getAbsolutePath(), null, new ParseOptions())
68+
.getOpenAPI();
69+
var clientOptInput = new ClientOptInput();
70+
clientOptInput.config(codegen);
71+
clientOptInput.openAPI(openApiInput);
72+
73+
List<File> files = new DefaultGenerator().opts(clientOptInput).generate();
74+
75+
File pojosInQueryApi = files.stream()
76+
.filter(it -> it.getName().equals("PojosInQueryApi.java"))
77+
.findFirst()
78+
.orElseThrow();
79+
80+
List<String> lines = Files.readAllLines(pojosInQueryApi.toPath()).stream()
81+
.map(String::trim)
82+
.collect(Collectors.toList());
83+
84+
assertThat(lines)
85+
.contains("public ResponseEntity<Void> getWithPojosInQueryWithHttpInfo(String simpleParam, MyPojo pojoParam) throws RestClientException {")
86+
.contains("localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, \"simpleParam\", simpleParam));")
87+
.contains("localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, \"field1\", pojoParam.getField1()));")
88+
.contains("localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, \"field2\", pojoParam.getField2()));");
89+
}
90+
5291
private static BoatJavaCodeGen javaCodeGenWithLib(String library) {
5392
var codeGen = new BoatJavaCodeGen();
5493
codeGen.setLibrary(library);
@@ -115,7 +154,7 @@ private void assertVariableDeclarator(CompilationUnit requestClass, String field
115154
.findAll(FieldDeclaration.class)
116155
.stream()
117156
.flatMap(field -> field.getChildNodes().stream())
118-
.filter(node -> node instanceof VariableDeclarator)
157+
.filter(VariableDeclarator.class::isInstance)
119158
.map(VariableDeclarator.class::cast)
120159
.filter(declarator -> declarator.getName().getIdentifier().equals(fieldName))
121160
.findFirst()

boat-scaffold/src/test/java/com/backbase/oss/codegen/java/BoatJavaCodeGenTests.java

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,37 @@
11
package com.backbase.oss.codegen.java;
22

3+
import static com.backbase.oss.codegen.java.BoatJavaCodeGen.CREATE_API_COMPONENT;
4+
import static com.backbase.oss.codegen.java.BoatJavaCodeGen.REST_TEMPLATE_BEAN_NAME;
5+
import static com.backbase.oss.codegen.java.BoatJavaCodeGen.USE_CLASS_LEVEL_BEAN_VALIDATION;
6+
import static com.backbase.oss.codegen.java.BoatJavaCodeGen.USE_DEFAULT_API_CLIENT;
7+
import static com.backbase.oss.codegen.java.BoatJavaCodeGen.USE_JACKSON_CONVERSION;
8+
import static com.backbase.oss.codegen.java.BoatJavaCodeGen.USE_PROTECTED_FIELDS;
9+
import static com.backbase.oss.codegen.java.BoatJavaCodeGen.USE_WITH_MODIFIERS;
10+
import static java.util.stream.Collectors.groupingBy;
11+
import static org.hamcrest.MatcherAssert.assertThat;
12+
import static org.hamcrest.Matchers.hasEntry;
13+
import static org.hamcrest.Matchers.is;
14+
import static org.hamcrest.Matchers.nullValue;
15+
import static org.junit.jupiter.api.Assertions.assertEquals;
16+
317
import com.github.javaparser.StaticJavaParser;
418
import com.github.javaparser.ast.CompilationUnit;
519
import com.github.javaparser.ast.body.MethodDeclaration;
620
import com.github.javaparser.ast.body.TypeDeclaration;
721
import io.swagger.parser.OpenAPIParser;
822
import io.swagger.v3.parser.core.models.ParseOptions;
23+
import java.io.File;
24+
import java.io.FileNotFoundException;
25+
import java.util.List;
26+
import java.util.Map;
27+
import java.util.function.Function;
928
import org.junit.jupiter.api.Test;
1029
import org.junit.jupiter.params.ParameterizedTest;
1130
import org.junit.jupiter.params.provider.ValueSource;
1231
import org.openapitools.codegen.CliOption;
1332
import org.openapitools.codegen.ClientOptInput;
1433
import org.openapitools.codegen.DefaultGenerator;
1534

16-
import java.io.File;
17-
import java.io.FileNotFoundException;
18-
import java.util.function.Function;
19-
import java.util.List;
20-
import java.util.Map;
21-
22-
import static com.backbase.oss.codegen.java.BoatJavaCodeGen.*;
23-
import static java.util.stream.Collectors.groupingBy;
24-
import static org.hamcrest.MatcherAssert.assertThat;
25-
import static org.hamcrest.Matchers.*;
26-
import static org.junit.jupiter.api.Assertions.assertEquals;
27-
2835
class BoatJavaCodeGenTests {
2936

3037
static final String PROP_BASE = BoatJavaCodeGenTests.class.getSimpleName() + ".";
@@ -115,10 +122,10 @@ void processOptsUseProtectedFields() {
115122

116123
@ParameterizedTest
117124
@ValueSource(booleans = {true, false})
118-
void shouldHonourGenerateComponentAnnotation(boolean generate) throws InterruptedException, FileNotFoundException {
125+
void shouldHonourGenerateComponentAnnotation(boolean generate) throws FileNotFoundException {
119126

120127
var input = new File("src/test/resources/boat-spring/openapi.yaml");
121-
var output = TEST_OUTPUT + "/shouldNotGenerateComponentAnnotation/" + String.valueOf(generate);
128+
var output = TEST_OUTPUT + "/shouldNotGenerateComponentAnnotation/" + generate;
122129

123130
final BoatJavaCodeGen gen = new BoatJavaCodeGen();
124131
gen.setOutputDir(output);
@@ -162,10 +169,10 @@ void shouldHonourGenerateComponentAnnotation(boolean generate) throws Interrupte
162169

163170
@ParameterizedTest
164171
@ValueSource(booleans = {true, false})
165-
void shouldHonourBeanValidationOption(boolean useBeanValidation) throws InterruptedException, FileNotFoundException {
172+
void shouldHonourBeanValidationOption(boolean useBeanValidation) throws FileNotFoundException {
166173

167174
var input = new File("src/test/resources/boat-spring/openapi.yaml");
168-
var output = TEST_OUTPUT + "/shouldHonourBeanValidationOption/" + String.valueOf(useBeanValidation);
175+
var output = TEST_OUTPUT + "/shouldHonourBeanValidationOption/" + useBeanValidation;
169176

170177
final BoatJavaCodeGen gen = new BoatJavaCodeGen();
171178
gen.setOutputDir(output);

boat-scaffold/src/test/resources/boat-spring/openapi.yaml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,49 @@ paths:
188188
format: number
189189
number-typed-value:
190190
type: number
191+
192+
/use-pojo-as-query-param:
193+
get:
194+
tags:
195+
- pojosInQuery
196+
operationId: getWithPojosInQuery
197+
parameters:
198+
- name: simpleParam
199+
in: query
200+
required: true
201+
style: form
202+
explode: true
203+
schema:
204+
type: string
205+
- name: pojoParam
206+
in: query
207+
required: true
208+
style: form
209+
explode: true
210+
schema:
211+
$ref: "#/components/schemas/MyPojo"
212+
responses:
213+
"200":
214+
description: OK
215+
191216
components:
192217
schemas:
218+
MyPojo:
219+
required:
220+
- field1
221+
- field2
222+
type: object
223+
properties:
224+
field1:
225+
maxLength: 32
226+
minLength: 1
227+
pattern: ^\S.*$
228+
type: string
229+
field2:
230+
maxLength: 50
231+
minLength: 1
232+
pattern: ^\S.*$
233+
type: string
193234
Additions:
194235
title: Additions
195236
type: object

0 commit comments

Comments
 (0)