Skip to content

Commit 8d616c0

Browse files
authored
Merge pull request #961 from swagger-api/issue-541
Issue 541
2 parents 06863bf + 7c3ed54 commit 8d616c0

File tree

4 files changed

+240
-65
lines changed

4 files changed

+240
-65
lines changed

src/main/java/io/swagger/codegen/v3/generators/DefaultCodegenConfig.java

Lines changed: 21 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -2117,17 +2117,7 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
21172117
}
21182118

21192119
List<Parameter> parameters = operation.getParameters();
2120-
CodegenParameter bodyParam = null;
2121-
List<CodegenParameter> allParams = new ArrayList<>();
2122-
List<CodegenParameter> bodyParams = new ArrayList<>();
2123-
List<CodegenParameter> pathParams = new ArrayList<>();
2124-
List<CodegenParameter> queryParams = new ArrayList<>();
2125-
List<CodegenParameter> headerParams = new ArrayList<>();
2126-
List<CodegenParameter> cookieParams = new ArrayList<>();
2127-
List<CodegenParameter> formParams = new ArrayList<>();
2128-
List<CodegenParameter> requiredParams = new ArrayList<>();
2129-
2130-
List<CodegenContent> codegenContents = new ArrayList<>();
2120+
final OperationParameters operationParameters = new OperationParameters();
21312121

21322122
RequestBody body = operation.getRequestBody();
21332123
if (body != null) {
@@ -2188,20 +2178,20 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
21882178
}
21892179
// todo: this segment is only to support the "older" template design. it should be removed once all templates are updated with the new {{#contents}} tag.
21902180
formParameter.getVendorExtensions().put(CodegenConstants.IS_FORM_PARAM_EXT_NAME, Boolean.TRUE);
2191-
formParams.add(formParameter.copy());
2181+
operationParameters.addFormParam(formParameter.copy());
21922182
if (body.getRequired() != null && body.getRequired()) {
2193-
requiredParams.add(formParameter.copy());
2183+
operationParameters.addRequiredParam(formParameter.copy());
21942184
}
2195-
allParams.add(formParameter);
2185+
operationParameters.addAllParams(formParameter);
21962186
}
2197-
codegenContents.add(codegenContent);
2187+
operationParameters.addCodegenContents(codegenContent);
21982188
}
21992189
} else {
2200-
bodyParam = fromRequestBody(body, schemaName, schema, schemas, imports);
2190+
CodegenParameter bodyParam = fromRequestBody(body, schemaName, schema, schemas, imports);
2191+
operationParameters.setBodyParam(bodyParam);
22012192
if (foundSchemas.isEmpty()) {
2202-
// todo: this segment is only to support the "older" template design. it should be removed once all templates are updated with the new {{#contents}} tag.
2203-
bodyParams.add(bodyParam.copy());
2204-
allParams.add(bodyParam);
2193+
operationParameters.addBodyParams(bodyParam.copy());
2194+
operationParameters.addAllParams(bodyParam);
22052195
} else {
22062196
boolean alreadyAdded = false;
22072197
for (Schema usedSchema : foundSchemas) {
@@ -2214,7 +2204,7 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
22142204
}
22152205
}
22162206
foundSchemas.add(schema);
2217-
codegenContents.add(codegenContent);
2207+
operationParameters.addCodegenContents(codegenContent);
22182208
}
22192209
}
22202210
}
@@ -2224,53 +2214,30 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
22242214
if (StringUtils.isNotBlank(param.get$ref())) {
22252215
param = getParameterFromRef(param.get$ref(), openAPI);
22262216
}
2227-
CodegenParameter codegenParameter = fromParameter(param, imports);
2228-
allParams.add(codegenParameter);
2229-
// Issue #2561 (neilotoole) : Moved setting of is<Type>Param flags
2230-
// from here to fromParameter().
2231-
if (param instanceof QueryParameter || "query".equalsIgnoreCase(param.getIn())) {
2232-
queryParams.add(codegenParameter.copy());
2233-
} else if (param instanceof PathParameter || "path".equalsIgnoreCase(param.getIn())) {
2234-
pathParams.add(codegenParameter.copy());
2235-
} else if (param instanceof HeaderParameter || "header".equalsIgnoreCase(param.getIn())) {
2236-
headerParams.add(codegenParameter.copy());
2237-
} else if (param instanceof CookieParameter || "cookie".equalsIgnoreCase(param.getIn())) {
2238-
cookieParams.add(codegenParameter.copy());
2239-
}
2240-
if (codegenParameter.required) {
2241-
requiredParams.add(codegenParameter.copy());
2217+
if ((param instanceof QueryParameter || "query".equalsIgnoreCase(param.getIn()))
2218+
&& param.getStyle() != null && param.getStyle().equals(Parameter.StyleEnum.DEEPOBJECT)) {
2219+
operationParameters.parseNestedObjects(param.getName(), param.getSchema(), imports, this, openAPI);
2220+
continue;
22422221
}
2222+
CodegenParameter codegenParameter = fromParameter(param, imports);
2223+
operationParameters.addParameters(param, codegenParameter);
22432224
}
22442225
}
22452226

22462227
addOperationImports(codegenOperation, imports);
22472228

2248-
codegenOperation.bodyParam = bodyParam;
2229+
codegenOperation.bodyParam = operationParameters.getBodyParam();
22492230
codegenOperation.httpMethod = httpMethod.toUpperCase();
22502231

22512232
// move "required" parameters in front of "optional" parameters
22522233
if (sortParamsByRequiredFlag) {
2253-
Collections.sort(allParams, new Comparator<CodegenParameter>() {
2254-
@Override
2255-
public int compare(CodegenParameter one, CodegenParameter another) {
2256-
if (one.required == another.required) return 0;
2257-
else if (one.required) return -1;
2258-
else return 1;
2259-
}
2260-
});
2234+
operationParameters.sortRequiredAllParams();
22612235
}
22622236

2263-
codegenOperation.allParams = addHasMore(allParams);
2264-
codegenOperation.bodyParams = addHasMore(bodyParams);
2265-
codegenOperation.pathParams = addHasMore(pathParams);
2266-
codegenOperation.queryParams = addHasMore(queryParams);
2267-
codegenOperation.headerParams = addHasMore(headerParams);
2268-
codegenOperation.cookieParams = addHasMore(cookieParams);
2269-
codegenOperation.formParams = addHasMore(formParams);
2270-
codegenOperation.requiredParams = addHasMore(requiredParams);
2237+
operationParameters.addHasMore(codegenOperation);
22712238
codegenOperation.externalDocs = operation.getExternalDocs();
22722239

2273-
configuresParameterForMediaType(codegenOperation, codegenContents);
2240+
configuresParameterForMediaType(codegenOperation, operationParameters.getCodegenContents());
22742241
// legacy support
22752242
codegenOperation.nickname = codegenOperation.operationId;
22762243

@@ -3002,16 +2969,6 @@ private void addHeaders(ApiResponse response, List<CodegenProperty> target, Map<
30022969
}
30032970
}
30042971

3005-
protected static List<CodegenParameter> addHasMore(List<CodegenParameter> objs) {
3006-
if (objs != null) {
3007-
for (int i = 0; i < objs.size(); i++) {
3008-
objs.get(i).secondaryParam = i > 0;
3009-
objs.get(i).getVendorExtensions().put(CodegenConstants.HAS_MORE_EXT_NAME, i < objs.size() - 1);
3010-
}
3011-
}
3012-
return objs;
3013-
}
3014-
30152972
private static Map<String, Object> addHasMore(Map<String, Object> objs) {
30162973
if (objs != null) {
30172974
for (int i = 0; i < objs.size() - 1; i++) {
@@ -4379,7 +4336,7 @@ protected void configuresParameterForMediaType(CodegenOperation codegenOperation
43794336
}
43804337
}
43814338
);
4382-
addHasMore(content.getParameters());
4339+
OperationParameters.addHasMore(content.getParameters());
43834340
}
43844341
codegenOperation.getContents().addAll(codegenContents);
43854342
}
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
package io.swagger.codegen.v3.generators;
2+
3+
import io.swagger.codegen.v3.CodegenConstants;
4+
import io.swagger.codegen.v3.CodegenContent;
5+
import io.swagger.codegen.v3.CodegenOperation;
6+
import io.swagger.codegen.v3.CodegenParameter;
7+
import io.swagger.codegen.v3.generators.util.OpenAPIUtil;
8+
import io.swagger.v3.oas.models.OpenAPI;
9+
import io.swagger.v3.oas.models.media.ArraySchema;
10+
import io.swagger.v3.oas.models.media.Schema;
11+
import io.swagger.v3.oas.models.parameters.CookieParameter;
12+
import io.swagger.v3.oas.models.parameters.HeaderParameter;
13+
import io.swagger.v3.oas.models.parameters.Parameter;
14+
import io.swagger.v3.oas.models.parameters.PathParameter;
15+
import io.swagger.v3.oas.models.parameters.QueryParameter;
16+
17+
import java.util.ArrayList;
18+
import java.util.Collections;
19+
import java.util.List;
20+
import java.util.Map;
21+
import java.util.Set;
22+
23+
public class OperationParameters {
24+
25+
private CodegenParameter bodyParam = null;
26+
private List<CodegenParameter> allParams = new ArrayList<>();
27+
private List<CodegenParameter> bodyParams = new ArrayList<>();
28+
private List<CodegenParameter> pathParams = new ArrayList<>();
29+
private List<CodegenParameter> queryParams = new ArrayList<>();
30+
private List<CodegenParameter> headerParams = new ArrayList<>();
31+
private List<CodegenParameter> cookieParams = new ArrayList<>();
32+
private List<CodegenParameter> formParams = new ArrayList<>();
33+
private List<CodegenParameter> requiredParams = new ArrayList<>();
34+
private List<CodegenContent> codegenContents = new ArrayList<>();
35+
36+
public void setBodyParam(CodegenParameter bodyParam) {
37+
this.bodyParam = bodyParam;
38+
}
39+
40+
public CodegenParameter getBodyParam() {
41+
return bodyParam;
42+
}
43+
44+
public List<CodegenParameter> getAllParams() {
45+
return allParams;
46+
}
47+
48+
public List<CodegenParameter> getBodyParams() {
49+
return bodyParams;
50+
}
51+
52+
public List<CodegenParameter> getPathParams() {
53+
return pathParams;
54+
}
55+
56+
public List<CodegenParameter> getQueryParams() {
57+
return queryParams;
58+
}
59+
60+
public List<CodegenParameter> getHeaderParams() {
61+
return headerParams;
62+
}
63+
64+
public List<CodegenParameter> getCookieParams() {
65+
return cookieParams;
66+
}
67+
68+
public List<CodegenParameter> getFormParams() {
69+
return formParams;
70+
}
71+
72+
public List<CodegenParameter> getRequiredParams() {
73+
return requiredParams;
74+
}
75+
76+
public List<CodegenContent> getCodegenContents() {
77+
return codegenContents;
78+
}
79+
80+
public void addAllParams(CodegenParameter codegenParameter) {
81+
allParams.add(codegenParameter);
82+
}
83+
84+
public void addBodyParams(CodegenParameter codegenParameter) {
85+
bodyParams.add(codegenParameter);
86+
}
87+
88+
public void addPathParams(CodegenParameter codegenParameter) {
89+
pathParams.add(codegenParameter);
90+
}
91+
92+
public void addQueryParams(CodegenParameter codegenParameter) {
93+
queryParams.add(codegenParameter);
94+
}
95+
96+
public void addHeaderParams(CodegenParameter codegenParameter) {
97+
headerParams.add(codegenParameter);
98+
}
99+
100+
public void addCookieParams(CodegenParameter codegenParameter) {
101+
cookieParams.add(codegenParameter);
102+
}
103+
104+
public void addFormParam(CodegenParameter codegenParameter) {
105+
formParams.add(codegenParameter);
106+
}
107+
108+
public void addRequiredParam(CodegenParameter codegenParameter) {
109+
requiredParams.add(codegenParameter);
110+
}
111+
112+
public void addCodegenContents(CodegenContent codegenContent) {
113+
codegenContents.add(codegenContent);
114+
}
115+
116+
public void addParameters(Parameter parameter, CodegenParameter codegenParameter) {
117+
allParams.add(codegenParameter);
118+
119+
if (parameter instanceof QueryParameter || "query".equalsIgnoreCase(parameter.getIn())) {
120+
queryParams.add(codegenParameter.copy());
121+
} else if (parameter instanceof PathParameter || "path".equalsIgnoreCase(parameter.getIn())) {
122+
pathParams.add(codegenParameter.copy());
123+
} else if (parameter instanceof HeaderParameter || "header".equalsIgnoreCase(parameter.getIn())) {
124+
headerParams.add(codegenParameter.copy());
125+
} else if (parameter instanceof CookieParameter || "cookie".equalsIgnoreCase(parameter.getIn())) {
126+
cookieParams.add(codegenParameter.copy());
127+
}
128+
if (codegenParameter.required) {
129+
requiredParams.add(codegenParameter.copy());
130+
}
131+
}
132+
133+
public void addHasMore(CodegenOperation codegenOperation) {
134+
codegenOperation.allParams = addHasMore(allParams);
135+
codegenOperation.bodyParams = addHasMore(bodyParams);
136+
codegenOperation.pathParams = addHasMore(pathParams);
137+
codegenOperation.queryParams = addHasMore(queryParams);
138+
codegenOperation.headerParams = addHasMore(headerParams);
139+
codegenOperation.cookieParams = addHasMore(cookieParams);
140+
codegenOperation.formParams = addHasMore(formParams);
141+
codegenOperation.requiredParams = addHasMore(requiredParams);
142+
}
143+
144+
public void sortRequiredAllParams() {
145+
Collections.sort(allParams, (one, another) -> {
146+
if (one.required == another.required) {
147+
return 0;
148+
} else if (one.required) {
149+
return -1;
150+
} else {
151+
return 1;
152+
}
153+
});
154+
}
155+
156+
public void parseNestedObjects(String name, Schema schema, Set<String> imports, DefaultCodegenConfig codegenConfig, OpenAPI openAPI) {
157+
schema = OpenAPIUtil.getRefSchemaIfExists(schema, openAPI);
158+
if (schema == null || !isObjectWithProperties(schema)) {
159+
return;
160+
}
161+
final Map<String, Schema> properties = schema.getProperties();
162+
for (String key : properties.keySet()) {
163+
Schema property = properties.get(key);
164+
property = OpenAPIUtil.getRefSchemaIfExists(property, openAPI);
165+
boolean required;
166+
if (schema.getRequired() == null || schema.getRequired().isEmpty()) {
167+
required = false;
168+
} else {
169+
required = schema.getRequired().stream().anyMatch(propertyName -> key.equalsIgnoreCase(propertyName.toString()));
170+
}
171+
final String parameterName;
172+
if (property instanceof ArraySchema) {
173+
parameterName = String.format("%s[%s][]", name, key);
174+
} else {
175+
parameterName = String.format("%s[%s]", name, key);
176+
}
177+
if (isObjectWithProperties(property)) {
178+
parseNestedObjects(parameterName, property, imports, codegenConfig, openAPI);
179+
continue;
180+
}
181+
final Parameter queryParameter = new QueryParameter()
182+
.name(parameterName)
183+
.required(required)
184+
.schema(property);
185+
final CodegenParameter codegenParameter = codegenConfig.fromParameter(queryParameter, imports);
186+
addParameters(queryParameter, codegenParameter);
187+
}
188+
}
189+
190+
public static List<CodegenParameter> addHasMore(List<CodegenParameter> codegenParameters) {
191+
if (codegenParameters == null || codegenParameters.isEmpty()) {
192+
return codegenParameters;
193+
}
194+
for (int i = 0; i < codegenParameters.size(); i++) {
195+
codegenParameters.get(i).secondaryParam = i > 0;
196+
codegenParameters.get(i).getVendorExtensions().put(CodegenConstants.HAS_MORE_EXT_NAME, i < codegenParameters.size() - 1);
197+
}
198+
return codegenParameters;
199+
}
200+
201+
private boolean isObjectWithProperties(Schema schema) {
202+
return ("object".equalsIgnoreCase(schema.getType()) || schema.getType() == null)
203+
&& schema.getProperties() != null
204+
&& !schema.getProperties().isEmpty();
205+
}
206+
}

src/main/java/io/swagger/codegen/v3/generators/nodejs/NodeJSServerCodegen.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.google.common.collect.ArrayListMultimap;
1111
import com.google.common.collect.Lists;
1212
import com.google.common.collect.Multimap;
13+
import io.swagger.codegen.v3.generators.OperationParameters;
1314
import io.swagger.codegen.v3.utils.URLPathUtil;
1415
import io.swagger.v3.oas.models.OpenAPI;
1516
import io.swagger.v3.oas.models.Operation;
@@ -452,7 +453,7 @@ protected void configuresParameterForMediaType(CodegenOperation codegenOperation
452453
addParameters(content, codegenOperation.cookieParams);
453454
}
454455
for (CodegenContent content : codegenContents) {
455-
addHasMore(content.getParameters());
456+
OperationParameters.addHasMore(content.getParameters());
456457
}
457458
codegenOperation.getContents().addAll(codegenContents);
458459
}

src/main/java/io/swagger/codegen/v3/generators/util/OpenAPIUtil.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,17 @@ public static Schema getSchemaFromName(String name, OpenAPI openAPI) {
5151
return mapSchema.get(name);
5252
}
5353

54+
public static Schema getRefSchemaIfExists(Schema schema, OpenAPI openAPI) {
55+
if (schema == null) {
56+
return null;
57+
}
58+
if (StringUtils.isBlank(schema.get$ref()) || openAPI == null || openAPI.getComponents() == null) {
59+
return schema;
60+
}
61+
final String name = getSimpleRef(schema.get$ref());
62+
return getSchemaFromName(name, openAPI);
63+
}
64+
5465
public static Schema getSchemaFromRefSchema(Schema refSchema, OpenAPI openAPI) {
5566
if (StringUtils.isBlank(refSchema.get$ref())) {
5667
return null;

0 commit comments

Comments
 (0)