Skip to content

Commit 8506f7a

Browse files
committed
Fix #6391. Avoid Retrofit crashing because of @path params defined after @query params
1 parent 49974c5 commit 8506f7a

2 files changed

Lines changed: 91 additions & 6 deletions

File tree

modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/JavaClientCodegen.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package io.swagger.codegen.languages;
22

3+
import static java.util.Collections.sort;
4+
35
import com.google.common.collect.LinkedListMultimap;
46
import io.swagger.codegen.*;
57
import io.swagger.codegen.languages.features.BeanValidationFeatures;
68
import io.swagger.codegen.languages.features.GzipFeatures;
79
import io.swagger.codegen.languages.features.PerformBeanValidationFeatures;
10+
811
import org.apache.commons.lang3.BooleanUtils;
912
import org.apache.commons.lang3.StringUtils;
1013
import org.slf4j.Logger;
@@ -49,6 +52,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
4952
protected boolean useGzipFeature = false;
5053
protected boolean useRuntimeException = false;
5154

55+
5256
public JavaClientCodegen() {
5357
super();
5458
outputFolder = "generated-code" + File.separator + "java";
@@ -316,10 +320,34 @@ public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
316320
if (operation.returnType == null) {
317321
operation.returnType = "Void";
318322
}
319-
if (usesRetrofit2Library() && StringUtils.isNotEmpty(operation.path) && operation.path.startsWith("/"))
323+
if (usesRetrofit2Library() && StringUtils.isNotEmpty(operation.path) && operation.path.startsWith("/")){
320324
operation.path = operation.path.substring(1);
325+
}
326+
327+
// sorting operation parameters to make sure path params are parsed before query params
328+
if (operation.allParams != null) {
329+
sort(operation.allParams, new Comparator<CodegenParameter>() {
330+
@Override
331+
public int compare(CodegenParameter one, CodegenParameter another) {
332+
if (one.isPathParam && another.isQueryParam) {
333+
return -1;
334+
}
335+
if (one.isQueryParam && another.isPathParam){
336+
return 1;
337+
}
338+
339+
return 0;
340+
}
341+
});
342+
Iterator<CodegenParameter> iterator = operation.allParams.iterator();
343+
while (iterator.hasNext()){
344+
CodegenParameter param = iterator.next();
345+
param.hasMore = iterator.hasNext();
346+
}
347+
}
321348
}
322349
}
350+
323351
}
324352

325353
// camelize path variables for Feign client

modules/swagger-codegen/src/test/java/io/swagger/codegen/languages/JavaClientCodegenTest.java

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package io.swagger.codegen.languages;
22

3+
import static io.swagger.codegen.languages.JavaClientCodegen.RETROFIT_2;
4+
5+
import java.util.ArrayList;
36
import java.util.Arrays;
47
import java.util.Collections;
58
import java.util.HashMap;
@@ -9,6 +12,11 @@
912
import org.testng.Assert;
1013
import org.testng.annotations.Test;
1114

15+
import com.google.common.collect.ImmutableMap;
16+
17+
import io.swagger.codegen.CodegenOperation;
18+
import io.swagger.codegen.CodegenParameter;
19+
1220
public class JavaClientCodegenTest {
1321

1422
private static final String VENDOR_MIME_TYPE = "application/vnd.company.v1+json";
@@ -51,15 +59,15 @@ public void testContentTypePrioritization() {
5159
Assert.assertEquals(JavaClientCodegen.prioritizeContentTypes(Arrays.asList(jsonMimeType)), Arrays.asList(jsonMimeType));
5260
Assert.assertEquals(JavaClientCodegen.prioritizeContentTypes(Arrays.asList(vendorMimeType)), Arrays.asList(vendorMimeType));
5361

54-
Assert.assertEquals(JavaClientCodegen.prioritizeContentTypes(Arrays.asList(xmlMimeType, jsonMimeType)),
62+
Assert.assertEquals(JavaClientCodegen.prioritizeContentTypes(Arrays.asList(xmlMimeType, jsonMimeType)),
5563
Arrays.asList(jsonMimeType, xmlMimeType));
56-
Assert.assertEquals(JavaClientCodegen.prioritizeContentTypes(Arrays.asList(jsonMimeType, xmlMimeType)),
64+
Assert.assertEquals(JavaClientCodegen.prioritizeContentTypes(Arrays.asList(jsonMimeType, xmlMimeType)),
5765
Arrays.asList(jsonMimeType, xmlMimeType));
58-
Assert.assertEquals(JavaClientCodegen.prioritizeContentTypes(Arrays.asList(jsonMimeType, vendorMimeType)),
66+
Assert.assertEquals(JavaClientCodegen.prioritizeContentTypes(Arrays.asList(jsonMimeType, vendorMimeType)),
5967
Arrays.asList(vendorMimeType, jsonMimeType));
60-
Assert.assertEquals(JavaClientCodegen.prioritizeContentTypes(Arrays.asList(textMimeType, xmlMimeType)),
68+
Assert.assertEquals(JavaClientCodegen.prioritizeContentTypes(Arrays.asList(textMimeType, xmlMimeType)),
6169
Arrays.asList(textMimeType, xmlMimeType));
62-
Assert.assertEquals(JavaClientCodegen.prioritizeContentTypes(Arrays.asList(xmlMimeType, textMimeType)),
70+
Assert.assertEquals(JavaClientCodegen.prioritizeContentTypes(Arrays.asList(xmlMimeType, textMimeType)),
6371
Arrays.asList(xmlMimeType, textMimeType));
6472

6573
System.out.println(JavaClientCodegen.prioritizeContentTypes(Arrays.asList(
@@ -74,4 +82,53 @@ public void testContentTypePrioritization() {
7482

7583
Assert.assertNull(priContentTypes.get(3).get("hasMore"));
7684
}
85+
86+
@Test
87+
public void testParametersAreCorrectlyOrderedWhenUsingRetrofit(){
88+
JavaClientCodegen javaClientCodegen = new JavaClientCodegen();
89+
javaClientCodegen.setLibrary(RETROFIT_2);
90+
91+
CodegenOperation codegenOperation = new CodegenOperation();
92+
CodegenParameter queryParamRequired = createQueryParam("queryParam1", true);
93+
CodegenParameter queryParamOptional = createQueryParam("queryParam2", false);
94+
CodegenParameter pathParam1 = createPathParam("pathParam1");
95+
CodegenParameter pathParam2 = createPathParam("pathParam2");
96+
97+
codegenOperation.allParams = Arrays.asList(queryParamRequired, pathParam1, pathParam2, queryParamOptional);
98+
Map<String, Object> operations = ImmutableMap.<String, Object>of("operation", Arrays.asList(codegenOperation));
99+
100+
Map<String, Object> objs = ImmutableMap.of("operations", operations, "imports", new ArrayList<Map<String, String>>());
101+
102+
javaClientCodegen.postProcessOperations(objs);
103+
104+
Assert.assertEquals(Arrays.asList(pathParam1, pathParam2, queryParamRequired, queryParamOptional), codegenOperation.allParams);
105+
Assert.assertTrue(pathParam1.hasMore);
106+
Assert.assertTrue(pathParam2.hasMore);
107+
Assert.assertTrue(queryParamRequired.hasMore);
108+
Assert.assertFalse(queryParamOptional.hasMore);
109+
110+
}
111+
112+
private CodegenParameter createPathParam(String name) {
113+
CodegenParameter codegenParameter = createStringParam(name);
114+
codegenParameter.isPathParam = true;
115+
return codegenParameter;
116+
}
117+
118+
private CodegenParameter createQueryParam(String name, boolean required) {
119+
CodegenParameter codegenParameter = createStringParam(name);
120+
codegenParameter.isQueryParam = true;
121+
codegenParameter.required = required;
122+
return codegenParameter;
123+
}
124+
125+
private CodegenParameter createStringParam(String name){
126+
CodegenParameter codegenParameter = new CodegenParameter();
127+
codegenParameter.paramName = name;
128+
codegenParameter.baseName = name;
129+
codegenParameter.dataType = "String";
130+
return codegenParameter;
131+
}
132+
133+
77134
}

0 commit comments

Comments
 (0)