[java native][dotnetcore] Implement QueryParameter deepObject style for client generators java native and dotnetcore. (#8563)

This commit is contained in:
Reinhard-PTV
2021-02-14 04:03:08 +01:00
committed by GitHub
parent 859a066052
commit 1006d2f21e
7 changed files with 204 additions and 2 deletions

View File

@@ -27,7 +27,7 @@ import java.util.*;
public class CodegenParameter implements IJsonSchemaValidationProperties {
public boolean isFormParam, isQueryParam, isPathParam, isHeaderParam,
isCookieParam, isBodyParam, isContainer,
isCollectionFormatMulti, isPrimitiveType, isModel, isExplode;
isCollectionFormatMulti, isPrimitiveType, isModel, isExplode, isDeepObject;
public String baseName, paramName, dataType, datatypeWithEnum, dataFormat, contentType,
collectionFormat, description, unescapedDescription, baseType, defaultValue, enumName, style;
@@ -195,6 +195,7 @@ public class CodegenParameter implements IJsonSchemaValidationProperties {
output.isMap = this.isMap;
output.isExplode = this.isExplode;
output.style = this.style;
output.isDeepObject = this.isDeepObject;
output.contentType = this.contentType;
return output;
@@ -202,7 +203,7 @@ public class CodegenParameter implements IJsonSchemaValidationProperties {
@Override
public int hashCode() {
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);
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);
}
@Override
@@ -262,6 +263,7 @@ public class CodegenParameter implements IJsonSchemaValidationProperties {
Objects.equals(defaultValue, that.defaultValue) &&
Objects.equals(enumName, that.enumName) &&
Objects.equals(style, that.style) &&
Objects.equals(isDeepObject, that.isDeepObject) &&
Objects.equals(example, that.example) &&
Objects.equals(jsonSchema, that.jsonSchema) &&
Objects.equals(_enum, that._enum) &&
@@ -311,6 +313,7 @@ public class CodegenParameter implements IJsonSchemaValidationProperties {
sb.append(", defaultValue='").append(defaultValue).append('\'');
sb.append(", enumName='").append(enumName).append('\'');
sb.append(", style='").append(style).append('\'');
sb.append(", deepObject='").append(isDeepObject).append('\'');
sb.append(", example='").append(example).append('\'');
sb.append(", jsonSchema='").append(jsonSchema).append('\'');
sb.append(", isString=").append(isString);

View File

@@ -4173,6 +4173,7 @@ public class DefaultCodegen implements CodegenConfig {
if (parameter.getStyle() != null) {
codegenParameter.style = parameter.getStyle().toString();
codegenParameter.isDeepObject = Parameter.StyleEnum.DEEPOBJECT == parameter.getStyle();
}
// the default value is false
@@ -4332,6 +4333,19 @@ public class DefaultCodegen implements CodegenConfig {
codegenParameter.paramName = "UNKNOWN_PARAMETER_NAME";
}
if (codegenParameter.isQueryParam && codegenParameter.isDeepObject) {
Schema schema = ModelUtils.getSchema(openAPI, codegenParameter.dataType);
codegenParameter.items = fromProperty(codegenParameter.paramName, schema);
Map<String, Schema<?>> properties = schema.getProperties();
codegenParameter.items.vars =
properties.entrySet().stream()
.map(entry -> {
CodegenProperty property = fromProperty(entry.getKey(), entry.getValue());
property.baseName = codegenParameter.baseName + "[" + entry.getKey() + "]";
return property;
}).collect(Collectors.toList());
}
// set the parameter example value
// should be overridden by lang codegen
setParameterExampleValue(codegenParameter, parameter);

View File

@@ -283,7 +283,16 @@ public class {{classname}} {
localVarQueryParams.addAll(ApiClient.parameterToPairs("{{{collectionFormat}}}", "{{baseName}}", {{paramName}}));
{{/collectionFormat}}
{{^collectionFormat}}
{{#isDeepObject}}
if ({{paramName}} != null) {
{{#items.vars}}
localVarQueryParams.addAll(ApiClient.parameterToPairs("{{baseName}}", {{paramName}}.{{getter}}()));
{{/items.vars}}
}
{{/isDeepObject}}
{{^isDeepObject}}
localVarQueryParams.addAll(ApiClient.parameterToPairs("{{baseName}}", {{paramName}}));
{{/isDeepObject}}
{{/collectionFormat}}
{{/queryParams}}

View File

@@ -285,7 +285,17 @@ namespace {{packageName}}.{{apiPackage}}
{{^required}}
if ({{paramName}} != null)
{
{{#isDeepObject}}
{{#items.vars}}
if ({{paramName}}.{{name}} != null)
{
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}.{{name}}));
}
{{/items.vars}}
{{/isDeepObject}}
{{^isDeepObject}}
localVarRequestOptions.QueryParameters.Add({{packageName}}.Client.ClientUtils.ParameterToMultiMap("{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}", "{{baseName}}", {{paramName}}));
{{/isDeepObject}}
}
{{/required}}
{{/queryParams}}

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
* Copyright 2018 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.csharpnetcore;
import io.swagger.parser.OpenAPIParser;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.parser.core.models.ParseOptions;
import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.languages.CSharpNetCoreClientCodegen;
import org.openapitools.codegen.languages.JavaClientCodegen;
import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import static org.openapitools.codegen.TestUtils.assertFileContains;
public class CSharpNetCoreClientDeepObjectTest {
@Test
public void deepObject() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/deepobject.yaml", null, new ParseOptions()).getOpenAPI();
CSharpNetCoreClientCodegen codegen = new CSharpNetCoreClientCodegen();
codegen.setOutputDir(output.getAbsolutePath());
ClientOptInput input = new ClientOptInput();
input.openAPI(openAPI);
input.config(codegen);
DefaultGenerator generator = new DefaultGenerator();
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
generator.opts(input).generate();
assertFileContains(Paths.get(outputPath + "/src/Org.OpenAPITools/Api/DefaultApi.cs"),
"options[a]", "options[b]");
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
* Copyright 2018 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.java;
import io.swagger.parser.OpenAPIParser;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.parser.core.models.ParseOptions;
import org.openapitools.codegen.*;
import org.openapitools.codegen.languages.JavaClientCodegen;
import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import static org.openapitools.codegen.TestUtils.assertFileContains;
public class JavaClientDeepObjectTest {
@Test
public void deepObject() throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
output.deleteOnExit();
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/deepobject.yaml", null, new ParseOptions()).getOpenAPI();
JavaClientCodegen codegen = new JavaClientCodegen();
codegen.setLibrary("native");
codegen.setOutputDir(output.getAbsolutePath());
ClientOptInput input = new ClientOptInput();
input.openAPI(openAPI);
input.config(codegen);
DefaultGenerator generator = new DefaultGenerator();
generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true");
generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false");
generator.opts(input).generate();
assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/client/api/DefaultApi.java"),
"options[a]", "options[b]");
}
}

View File

@@ -0,0 +1,36 @@
openapi: 3.0.3
info:
title: deepobject-test
version: 1.0.0
paths:
/test:
get:
operationId: test
parameters:
- name: options
in: query
required: false
style: deepObject
schema:
$ref: '#/components/schemas/Options'
explode: true
responses:
'200':
description: OK
content:
text/plain:
schema:
type: string
components:
schemas:
Options:
type: object
properties:
a:
nullable: true
type: string
format: date-time
b:
type: string
nullable: true
format: date-time