Skip to content

Commit 1006d2f

Browse files
authored
[java native][dotnetcore] Implement QueryParameter deepObject style for client generators java native and dotnetcore. (#8563)
1 parent 859a066 commit 1006d2f

File tree

7 files changed

+204
-2
lines changed

7 files changed

+204
-2
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenParameter.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
public class CodegenParameter implements IJsonSchemaValidationProperties {
2828
public boolean isFormParam, isQueryParam, isPathParam, isHeaderParam,
2929
isCookieParam, isBodyParam, isContainer,
30-
isCollectionFormatMulti, isPrimitiveType, isModel, isExplode;
30+
isCollectionFormatMulti, isPrimitiveType, isModel, isExplode, isDeepObject;
3131
public String baseName, paramName, dataType, datatypeWithEnum, dataFormat, contentType,
3232
collectionFormat, description, unescapedDescription, baseType, defaultValue, enumName, style;
3333

@@ -195,14 +195,15 @@ public CodegenParameter copy() {
195195
output.isMap = this.isMap;
196196
output.isExplode = this.isExplode;
197197
output.style = this.style;
198+
output.isDeepObject = this.isDeepObject;
198199
output.contentType = this.contentType;
199200

200201
return output;
201202
}
202203

203204
@Override
204205
public int hashCode() {
205-
return Objects.hash(isFormParam, isQueryParam, isPathParam, isHeaderParam, isCookieParam, isBodyParam, isContainer, isCollectionFormatMulti, isPrimitiveType, isModel, isExplode, baseName, paramName, dataType, datatypeWithEnum, dataFormat, collectionFormat, description, unescapedDescription, baseType, defaultValue, enumName, style, example, jsonSchema, isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isDecimal, isByteArray, isBinary, isBoolean, isDate, isDateTime, isUuid, isUri, isEmail, isFreeFormObject, isAnyType, isArray, isMap, isFile, isEnum, _enum, allowableValues, items, mostInnerItems, additionalProperties, vars, requiredVars, vendorExtensions, hasValidation, getMaxProperties(), getMinProperties(), isNullable, required, getMaximum(), getExclusiveMaximum(), getMinimum(), getExclusiveMinimum(), getMaxLength(), getMinLength(), getPattern(), getMaxItems(), getMinItems(), getUniqueItems(), contentType, multipleOf, isNull);
206+
return Objects.hash(isFormParam, isQueryParam, isPathParam, isHeaderParam, isCookieParam, isBodyParam, isContainer, isCollectionFormatMulti, isPrimitiveType, isModel, isExplode, baseName, paramName, dataType, datatypeWithEnum, dataFormat, collectionFormat, description, unescapedDescription, baseType, defaultValue, enumName, style, isDeepObject, example, jsonSchema, isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isDecimal, isByteArray, isBinary, isBoolean, isDate, isDateTime, isUuid, isUri, isEmail, isFreeFormObject, isAnyType, isArray, isMap, isFile, isEnum, _enum, allowableValues, items, mostInnerItems, additionalProperties, vars, requiredVars, vendorExtensions, hasValidation, getMaxProperties(), getMinProperties(), isNullable, required, getMaximum(), getExclusiveMaximum(), getMinimum(), getExclusiveMinimum(), getMaxLength(), getMinLength(), getPattern(), getMaxItems(), getMinItems(), getUniqueItems(), contentType, multipleOf, isNull);
206207
}
207208

208209
@Override
@@ -262,6 +263,7 @@ public boolean equals(Object o) {
262263
Objects.equals(defaultValue, that.defaultValue) &&
263264
Objects.equals(enumName, that.enumName) &&
264265
Objects.equals(style, that.style) &&
266+
Objects.equals(isDeepObject, that.isDeepObject) &&
265267
Objects.equals(example, that.example) &&
266268
Objects.equals(jsonSchema, that.jsonSchema) &&
267269
Objects.equals(_enum, that._enum) &&
@@ -311,6 +313,7 @@ public String toString() {
311313
sb.append(", defaultValue='").append(defaultValue).append('\'');
312314
sb.append(", enumName='").append(enumName).append('\'');
313315
sb.append(", style='").append(style).append('\'');
316+
sb.append(", deepObject='").append(isDeepObject).append('\'');
314317
sb.append(", example='").append(example).append('\'');
315318
sb.append(", jsonSchema='").append(jsonSchema).append('\'');
316319
sb.append(", isString=").append(isString);

modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4173,6 +4173,7 @@ public CodegenParameter fromParameter(Parameter parameter, Set<String> imports)
41734173

41744174
if (parameter.getStyle() != null) {
41754175
codegenParameter.style = parameter.getStyle().toString();
4176+
codegenParameter.isDeepObject = Parameter.StyleEnum.DEEPOBJECT == parameter.getStyle();
41764177
}
41774178

41784179
// the default value is false
@@ -4332,6 +4333,19 @@ public CodegenParameter fromParameter(Parameter parameter, Set<String> imports)
43324333
codegenParameter.paramName = "UNKNOWN_PARAMETER_NAME";
43334334
}
43344335

4336+
if (codegenParameter.isQueryParam && codegenParameter.isDeepObject) {
4337+
Schema schema = ModelUtils.getSchema(openAPI, codegenParameter.dataType);
4338+
codegenParameter.items = fromProperty(codegenParameter.paramName, schema);
4339+
Map<String, Schema<?>> properties = schema.getProperties();
4340+
codegenParameter.items.vars =
4341+
properties.entrySet().stream()
4342+
.map(entry -> {
4343+
CodegenProperty property = fromProperty(entry.getKey(), entry.getValue());
4344+
property.baseName = codegenParameter.baseName + "[" + entry.getKey() + "]";
4345+
return property;
4346+
}).collect(Collectors.toList());
4347+
}
4348+
43354349
// set the parameter example value
43364350
// should be overridden by lang codegen
43374351
setParameterExampleValue(codegenParameter, parameter);

modules/openapi-generator/src/main/resources/Java/libraries/native/api.mustache

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,16 @@ public class {{classname}} {
283283
localVarQueryParams.addAll(ApiClient.parameterToPairs("{{{collectionFormat}}}", "{{baseName}}", {{paramName}}));
284284
{{/collectionFormat}}
285285
{{^collectionFormat}}
286+
{{#isDeepObject}}
287+
if ({{paramName}} != null) {
288+
{{#items.vars}}
289+
localVarQueryParams.addAll(ApiClient.parameterToPairs("{{baseName}}", {{paramName}}.{{getter}}()));
290+
{{/items.vars}}
291+
}
292+
{{/isDeepObject}}
293+
{{^isDeepObject}}
286294
localVarQueryParams.addAll(ApiClient.parameterToPairs("{{baseName}}", {{paramName}}));
295+
{{/isDeepObject}}
287296
{{/collectionFormat}}
288297
{{/queryParams}}
289298

modules/openapi-generator/src/main/resources/csharp-netcore/api.mustache

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,17 @@ namespace {{packageName}}.{{apiPackage}}
285285
{{^required}}
286286
if ({{paramName}} != null)
287287
{
288+
{{#isDeepObject}}
289+
{{#items.vars}}
290+
if ({{paramName}}.{{name}} != null)
291+
{
292+
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}.{{name}}));
293+
}
294+
{{/items.vars}}
295+
{{/isDeepObject}}
296+
{{^isDeepObject}}
288297
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));
298+
{{/isDeepObject}}
289299
}
290300
{{/required}}
291301
{{/queryParams}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
3+
* Copyright 2018 SmartBear Software
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.openapitools.codegen.csharpnetcore;
19+
20+
import io.swagger.parser.OpenAPIParser;
21+
import io.swagger.v3.oas.models.OpenAPI;
22+
import io.swagger.v3.parser.core.models.ParseOptions;
23+
import org.openapitools.codegen.ClientOptInput;
24+
import org.openapitools.codegen.CodegenConstants;
25+
import org.openapitools.codegen.DefaultGenerator;
26+
import org.openapitools.codegen.languages.CSharpNetCoreClientCodegen;
27+
import org.openapitools.codegen.languages.JavaClientCodegen;
28+
import org.testng.annotations.Test;
29+
30+
import java.io.File;
31+
import java.io.IOException;
32+
import java.nio.file.Files;
33+
import java.nio.file.Paths;
34+
35+
import static org.openapitools.codegen.TestUtils.assertFileContains;
36+
37+
public class CSharpNetCoreClientDeepObjectTest {
38+
39+
@Test
40+
public void deepObject() throws IOException {
41+
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
42+
output.deleteOnExit();
43+
String outputPath = output.getAbsolutePath().replace('\\', '/');
44+
45+
OpenAPI openAPI = new OpenAPIParser()
46+
.readLocation("src/test/resources/3_0/deepobject.yaml", null, new ParseOptions()).getOpenAPI();
47+
48+
CSharpNetCoreClientCodegen codegen = new CSharpNetCoreClientCodegen();
49+
codegen.setOutputDir(output.getAbsolutePath());
50+
51+
ClientOptInput input = new ClientOptInput();
52+
input.openAPI(openAPI);
53+
input.config(codegen);
54+
55+
DefaultGenerator generator = new DefaultGenerator();
56+
57+
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true");
58+
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
59+
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
60+
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
61+
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
62+
generator.opts(input).generate();
63+
assertFileContains(Paths.get(outputPath + "/src/Org.OpenAPITools/Api/DefaultApi.cs"),
64+
"options[a]", "options[b]");
65+
}
66+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
3+
* Copyright 2018 SmartBear Software
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.openapitools.codegen.java;
19+
20+
import io.swagger.parser.OpenAPIParser;
21+
import io.swagger.v3.oas.models.OpenAPI;
22+
import io.swagger.v3.parser.core.models.ParseOptions;
23+
import org.openapitools.codegen.*;
24+
import org.openapitools.codegen.languages.JavaClientCodegen;
25+
import org.testng.annotations.Test;
26+
27+
import java.io.File;
28+
import java.io.IOException;
29+
import java.nio.file.Files;
30+
import java.nio.file.Paths;
31+
import static org.openapitools.codegen.TestUtils.assertFileContains;
32+
33+
public class JavaClientDeepObjectTest {
34+
35+
@Test
36+
public void deepObject() throws IOException {
37+
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
38+
output.deleteOnExit();
39+
String outputPath = output.getAbsolutePath().replace('\\', '/');
40+
41+
OpenAPI openAPI = new OpenAPIParser()
42+
.readLocation("src/test/resources/3_0/deepobject.yaml", null, new ParseOptions()).getOpenAPI();
43+
44+
JavaClientCodegen codegen = new JavaClientCodegen();
45+
codegen.setLibrary("native");
46+
codegen.setOutputDir(output.getAbsolutePath());
47+
48+
ClientOptInput input = new ClientOptInput();
49+
input.openAPI(openAPI);
50+
input.config(codegen);
51+
52+
DefaultGenerator generator = new DefaultGenerator();
53+
54+
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true");
55+
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
56+
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
57+
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
58+
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
59+
generator.opts(input).generate();
60+
61+
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/client/api/DefaultApi.java"),
62+
"options[a]", "options[b]");
63+
}
64+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
openapi: 3.0.3
2+
info:
3+
title: deepobject-test
4+
version: 1.0.0
5+
paths:
6+
/test:
7+
get:
8+
operationId: test
9+
parameters:
10+
- name: options
11+
in: query
12+
required: false
13+
style: deepObject
14+
schema:
15+
$ref: '#/components/schemas/Options'
16+
explode: true
17+
responses:
18+
'200':
19+
description: OK
20+
content:
21+
text/plain:
22+
schema:
23+
type: string
24+
components:
25+
schemas:
26+
Options:
27+
type: object
28+
properties:
29+
a:
30+
nullable: true
31+
type: string
32+
format: date-time
33+
b:
34+
type: string
35+
nullable: true
36+
format: date-time

0 commit comments

Comments
 (0)