Skip to content
This repository has been archived by the owner on Nov 17, 2022. It is now read-only.

Commit

Permalink
Merge branch 'master' into fix_#11886_unhandled_default_enum_case
Browse files Browse the repository at this point in the history
* master:
  update gson to newer version in kotlin templates (OpenAPITools#12425)
  update gson to 2.8.9 in android httpclient (OpenAPITools#12423)
  update android dependencies to newer versions (OpenAPITools#12421)
  [Java] Update rest-assured dependencies (OpenAPITools#12420)
  update cwiki samples
  Add - Status colors in Wiki, Example per parameter (OpenAPITools#12394)
  Better support for inline schemas in parameters (OpenAPITools#12369)
  Upgrade Spring Boot to 2.5.14 / 2.7.0 (OpenAPITools#12408)
  update java samples
  Remove javadoc comment for unthrown IOException (OpenAPITools#12401)
  remove errorObjectSubtype from java client genreator (OpenAPITools#12405)
  [java][Micronaut] generator fixes (OpenAPITools#11803)
  Apply style and explode values from encoding for form-encoded request body parameters (OpenAPITools#12162)
  • Loading branch information
samuelo committed May 22, 2022
2 parents 713e788 + ccd64ce commit 72743cc
Show file tree
Hide file tree
Showing 95 changed files with 722 additions and 488 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.openapitools.codegen.api.TemplatingEngineAdapter;
import org.openapitools.codegen.config.GlobalSettings;
import org.openapitools.codegen.examples.ExampleGenerator;
import org.openapitools.codegen.languages.RustServerCodegen;
import org.openapitools.codegen.meta.FeatureSet;
import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.meta.Stability;
Expand Down Expand Up @@ -1932,16 +1933,49 @@ public void setParameterExampleValue(CodegenParameter codegenParameter, RequestB
}

/**
* Sets the content type of the parameter based on the encoding specified in the request body.
* Sets the content type, style, and explode of the parameter based on the encoding specified
* in the request body.
*
* @param codegenParameter Codegen parameter
* @param mediaType MediaType from the request body
*/
public void setParameterContentType(CodegenParameter codegenParameter, MediaType mediaType) {
public void setParameterEncodingValues(CodegenParameter codegenParameter, MediaType mediaType) {
if (mediaType != null && mediaType.getEncoding() != null) {
Encoding encoding = mediaType.getEncoding().get(codegenParameter.baseName);
if (encoding != null) {
codegenParameter.contentType = encoding.getContentType();
boolean styleGiven = true;
Encoding.StyleEnum style = encoding.getStyle();
if(style == null || style == Encoding.StyleEnum.FORM) {
// (Unfortunately, swagger-parser-v3 will always provide 'form'
// when style is not specified, so we can't detect that)
style = Encoding.StyleEnum.FORM;
styleGiven = false;
}
boolean explodeGiven = true;
Boolean explode = encoding.getExplode();
if(explode == null) {
explode = style == Encoding.StyleEnum.FORM; // Default to True when form, False otherwise
explodeGiven = false;
}

if(!styleGiven && !explodeGiven) {
// Ignore contentType if style or explode are specified.
codegenParameter.contentType = encoding.getContentType();
}

codegenParameter.style = style.toString();
codegenParameter.isDeepObject = Encoding.StyleEnum.DEEP_OBJECT == style;

if(codegenParameter.isContainer) {
codegenParameter.isExplode = explode;
String collectionFormat = getCollectionFormat(codegenParameter);
codegenParameter.collectionFormat = StringUtils.isEmpty(collectionFormat) ? "csv" : collectionFormat;
codegenParameter.isCollectionFormatMulti = "multi".equals(collectionFormat);
} else {
codegenParameter.isExplode = false;
codegenParameter.collectionFormat = null;
codegenParameter.isCollectionFormatMulti = false;
}
} else {
LOGGER.debug("encoding not specified for {}", codegenParameter.baseName);
}
Expand Down Expand Up @@ -4087,7 +4121,7 @@ public CodegenOperation fromOperation(String path,
formParams = fromRequestBodyToFormParameters(requestBody, imports);
op.isMultipart = contentType.startsWith("multipart");
for (CodegenParameter cp : formParams) {
setParameterContentType(cp, requestBody.getContent().get(contentType));
setParameterEncodingValues(cp, requestBody.getContent().get(contentType));
postProcessParameter(cp);
}
// add form parameters to the beginning of all parameter list
Expand Down Expand Up @@ -4575,9 +4609,24 @@ public CodegenParameter fromParameter(Parameter parameter, Set<String> imports)
}

Schema parameterSchema;

// the parameter model name is obtained from the schema $ref
// e.g. #/components/schemas/list_pageQuery_parameter => toModelName(list_pageQuery_parameter)
String parameterModelName = null;

if (parameter.getSchema() != null) {
parameterSchema = parameter.getSchema();
CodegenProperty prop = fromProperty(parameter.getName(), parameterSchema);
parameterModelName = getParameterDataType(parameter, parameterSchema);
CodegenProperty prop;
if (this instanceof RustServerCodegen) {
// for rust server, we need to do somethings special as it uses
// $ref (e.g. #components/schemas/Pet) to determine whether it's a model
prop = fromProperty(parameter.getName(), parameterSchema);
} else if (getUseInlineModelResolver()) {
prop = fromProperty(parameter.getName(), ModelUtils.getReferencedSchema(openAPI, parameterSchema));
} else {
prop = fromProperty(parameter.getName(), parameterSchema);
}
codegenParameter.setSchema(prop);
} else if (parameter.getContent() != null) {
Content content = parameter.getContent();
Expand All @@ -4587,6 +4636,7 @@ public CodegenParameter fromParameter(Parameter parameter, Set<String> imports)
Map.Entry<String, MediaType> entry = content.entrySet().iterator().next();
codegenParameter.contentType = entry.getKey();
parameterSchema = entry.getValue().getSchema();
parameterModelName = getParameterDataType(parameter, parameterSchema);
} else {
parameterSchema = null;
}
Expand All @@ -4613,11 +4663,17 @@ public CodegenParameter fromParameter(Parameter parameter, Set<String> imports)

parameterSchema = unaliasSchema(parameterSchema, Collections.emptyMap());
if (parameterSchema == null) {
LOGGER.warn("warning! Schema not found for parameter \" {} \", using String", parameter.getName());
parameterSchema = new StringSchema().description("//TODO automatically added by openapi-generator due to missing type definition.");
LOGGER.warn("warning! Schema not found for parameter \" {} \"", parameter.getName());
finishUpdatingParameter(codegenParameter, parameter);
return codegenParameter;
}

if (getUseInlineModelResolver() && !(this instanceof RustServerCodegen)) {
// for rust server, we cannot run the following as it uses
// $ref (e.g. #components/schemas/Pet) to determine whether it's a model
parameterSchema = ModelUtils.getReferencedSchema(openAPI, parameterSchema);
}

ModelUtils.syncValidationProperties(parameterSchema, codegenParameter);
codegenParameter.setTypeProperties(parameterSchema);
codegenParameter.setComposedSchemas(getComposedSchemas(parameterSchema));
Expand Down Expand Up @@ -4717,9 +4773,8 @@ public CodegenParameter fromParameter(Parameter parameter, Set<String> imports)
//}
//codegenProperty.required = true;

String parameterDataType = this.getParameterDataType(parameter, parameterSchema);
if (parameterDataType != null) {
codegenParameter.dataType = parameterDataType;
if (parameterModelName != null) {
codegenParameter.dataType = parameterModelName;
if (ModelUtils.isObjectSchema(parameterSchema)) {
codegenProperty.complexType = codegenParameter.dataType;
}
Expand Down Expand Up @@ -4771,13 +4826,17 @@ public CodegenParameter fromParameter(Parameter parameter, Set<String> imports)
// https://swagger.io/docs/specification/serialization/
if (schema != null) {
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());
if (properties != null) {
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());
} else {
//LOGGER.error("properties is null: {}", schema);
}
} else {
LOGGER.warn(
"No object schema found for deepObject parameter{} deepObject won't have specific properties",
Expand All @@ -4790,17 +4849,17 @@ public CodegenParameter fromParameter(Parameter parameter, Set<String> imports)
}

/**
* Returns the data type of a parameter.
* Returns the data type of parameter.
* Returns null by default to use the CodegenProperty.datatype value
*
* @param parameter Parameter
* @param schema Schema
* @return data type
*/
protected String getParameterDataType(Parameter parameter, Schema schema) {
if (parameter.get$ref() != null) {
String refName = ModelUtils.getSimpleRef(parameter.get$ref());
return toModelName(refName);
Schema unaliasSchema = ModelUtils.unaliasSchema(openAPI, schema);
if (unaliasSchema.get$ref() != null) {
return toModelName(ModelUtils.getSimpleRef(unaliasSchema.get$ref()));
}
return null;
}
Expand Down Expand Up @@ -6398,11 +6457,12 @@ public CodegenParameter fromFormProperty(String name, Schema propertySchema, Set
LOGGER.warn("Could not compute datatypeWithEnum from {}, {}", arrayInnerProperty.baseType, arrayInnerProperty.enumName);
}
// end of hoisting
//TODO fix collectionFormat for form parameters
//collectionFormat = getCollectionFormat(s);

// collectionFormat for form parameter does not consider
// style and explode from encoding at this point
String collectionFormat = getCollectionFormat(codegenParameter);
// default to csv:
codegenParameter.collectionFormat = StringUtils.isEmpty(collectionFormat) ? "csv" : collectionFormat;
codegenParameter.isCollectionFormatMulti = "multi".equals(collectionFormat);

// recursively add import
while (arrayInnerProperty != null) {
Expand Down Expand Up @@ -6444,8 +6504,6 @@ public CodegenParameter fromFormProperty(String name, Schema propertySchema, Set
// set nullable
setParameterNullable(codegenParameter, codegenProperty);

//TODO collectionFormat for form parameter not yet supported
//codegenParameter.collectionFormat = getCollectionFormat(propertySchema);
return codegenParameter;
}

Expand Down Expand Up @@ -7367,14 +7425,30 @@ protected static boolean isJsonVendorMimeType(String mime) {
}

/**
* Returns null by default but can be overwritten to return a valid collectionFormat
* Builds OAPI 2.0 collectionFormat value based on style and explode values
* for the {@link CodegenParameter}.
*
* @param codegenParameter parameter
* @return string for a collectionFormat.
*/
protected String getCollectionFormat(CodegenParameter codegenParameter) {
return null;
if ("form".equals(codegenParameter.style)) {
// Ref: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#style-values
if (codegenParameter.isExplode) {
return "multi";
} else {
return "csv";
}
} else if ("simple".equals(codegenParameter.style)) {
return "csv";
} else if ("pipeDelimited".equals(codegenParameter.style)) {
return "pipes";
} else if ("spaceDelimited".equals(codegenParameter.style)) {
return "ssv";
} else {
// Doesn't map to any of the collectionFormat strings
return null;
}
}

private CodegenComposedSchemas getComposedSchemas(Schema schema) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ public interface IJsonSchemaValidationProperties {
default void setTypeProperties(Schema p) {
if (ModelUtils.isTypeObjectSchema(p)) {
setIsMap(true);
if (ModelUtils.isModelWithPropertiesOnly(p)) {
setIsModel(true);
}
} else if (ModelUtils.isArraySchema(p)) {
setIsArray(true);
} else if (ModelUtils.isFileSchema(p) && !ModelUtils.isStringSchema(p)) {
Expand Down Expand Up @@ -219,6 +222,9 @@ default void setTypeProperties(Schema p) {
setIsNull(true);
} else if (ModelUtils.isAnyType(p)) {
setIsAnyType(true);
if (ModelUtils.isModelWithPropertiesOnly(p)) {
setIsModel(true);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -408,10 +408,10 @@ private void flattenRequestBody(String modelName, Operation operation) {
/**
* Flatten inline models in parameters
*
* @param pathname target pathname
* @param modelName model name
* @param operation target operation
*/
private void flattenParameters(String pathname, Operation operation) {
private void flattenParameters(String modelName, Operation operation) {
List<Parameter> parameters = operation.getParameters();
if (parameters == null) {
return;
Expand All @@ -422,39 +422,19 @@ private void flattenParameters(String pathname, Operation operation) {
continue;
}

Schema model = parameter.getSchema();
if (model instanceof ObjectSchema) {
Schema obj = model;
if (obj.getType() == null || "object".equals(obj.getType())) {
if (obj.getProperties() != null && obj.getProperties().size() > 0) {
flattenProperties(openAPI, obj.getProperties(), pathname);
String modelName = resolveModelName(obj.getTitle(), parameter.getName());
modelName = addSchemas(modelName, model);
parameter.$ref(modelName);
}
}
} else if (model instanceof ArraySchema) {
ArraySchema am = (ArraySchema) model;
Schema inner = am.getItems();
if (inner instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) inner;
if (op.getProperties() != null && op.getProperties().size() > 0) {
flattenProperties(openAPI, op.getProperties(), pathname);
String modelName = resolveModelName(op.getTitle(), parameter.getName());
Schema innerModel = modelFromProperty(openAPI, op, modelName);
String existing = matchGenerated(innerModel);
if (existing != null) {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
am.setItems(schema);
} else {
modelName = addSchemas(modelName, innerModel);
Schema schema = new Schema().$ref(modelName);
schema.setRequired(op.getRequired());
am.setItems(schema);
}
}
}
Schema parameterSchema = parameter.getSchema();

if (parameterSchema == null) {
continue;
}
String schemaName = resolveModelName(parameterSchema.getTitle(),
(operation.getOperationId() == null ? modelName : operation.getOperationId()) + "_" + parameter.getName() + "_parameter");
// Recursively gather/make inline models within this schema if any
gatherInlineModels(parameterSchema, schemaName);
if (isModelNeeded(parameterSchema)) {
// If this schema should be split into its own model, do so
Schema refSchema = this.makeSchemaInComponents(schemaName, parameterSchema);
parameter.setSchema(refSchema);
}
}
}
Expand Down Expand Up @@ -564,29 +544,7 @@ private void flattenComponents() {
flattenComposedChildren(modelName + "_oneOf", m.getOneOf());
} else if (model instanceof Schema) {
gatherInlineModels(model, modelName);
} /*else if (ModelUtils.isArraySchema(model)) {
ArraySchema m = (ArraySchema) model;
Schema inner = m.getItems();
if (inner instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) inner;
if (op.getProperties() != null && op.getProperties().size() > 0) {
String innerModelName = resolveModelName(op.getTitle(), modelName + "_inner");
Schema innerModel = modelFromProperty(openAPI, op, innerModelName);
String existing = matchGenerated(innerModel);
if (existing == null) {
openAPI.getComponents().addSchemas(innerModelName, innerModel);
addGenerated(innerModelName, innerModel);
Schema schema = new Schema().$ref(innerModelName);
schema.setRequired(op.getRequired());
m.setItems(schema);
} else {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
m.setItems(schema);
}
}
}
}*/
}
}
}

Expand Down
Loading

0 comments on commit 72743cc

Please sign in to comment.