Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

package org.openapitools.codegen;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.Ticker;
Expand Down Expand Up @@ -1088,7 +1087,7 @@ public void preprocessOpenAPI(OpenAPI openAPI) {
addOneOfNameExtension(s, n);
}
} else if (ModelUtils.isArraySchema(s)) {
Schema items = ((ArraySchema) s).getItems();
Schema items = s.getItems();
if (ModelUtils.isComposedSchema(items)) {
addOneOfNameExtension(items, nOneOf);
addOneOfInterfaceModel(items, nOneOf);
Expand Down Expand Up @@ -2057,8 +2056,7 @@ public String toInstantiationType(Schema schema) {
String inner = getSchemaType(additionalProperties);
return instantiationTypes.get("map") + "<String, " + inner + ">";
} else if (ModelUtils.isArraySchema(schema)) {
ArraySchema arraySchema = (ArraySchema) schema;
String inner = getSchemaType(getSchemaItems(arraySchema));
String inner = getSchemaType(getSchemaItems(schema));
String parentType;
if (ModelUtils.isSet(schema)) {
parentType = "set";
Expand Down Expand Up @@ -2364,8 +2362,13 @@ public String getSchemaType(Schema schema) {

}

protected Schema<?> getSchemaItems(ArraySchema schema) {
Schema<?> items = schema.getItems();
protected Schema<?> getSchemaItems(Schema schema) {
Schema<?> items = null;
if (schema instanceof ArraySchema) {
items = ((ArraySchema) schema).getItems();
} else if (schema instanceof JsonSchema) {
items = ((JsonSchema) schema).getItems();
}
if (items == null) {
LOGGER.error("Undefined array inner type for `{}`. Default to String.", schema.getName());
items = new StringSchema().description("TODO default missing array inner type to string");
Expand Down Expand Up @@ -2486,10 +2489,10 @@ protected String getSingleSchemaType(Schema schema) {
private String getPrimitiveType(Schema schema) {
if (schema == null) {
throw new RuntimeException("schema cannot be null in getPrimitiveType");
} else if (typeMapping.containsKey(schema.getType() + "+" + schema.getFormat())) {
} else if (typeMapping.containsKey(ModelUtils.getSchemaType(schema) + "+" + schema.getFormat())) {
// allows custom type_format mapping.
// use {type}+{format}
return typeMapping.get(schema.getType() + "+" + schema.getFormat());
return typeMapping.get(ModelUtils.getSchemaType(schema) + "+" + schema.getFormat());
} else if (ModelUtils.isNullType(schema)) {
// The 'null' type is allowed in OAS 3.1 and above. It is not supported by OAS 3.0.x,
// though this tooling supports it.
Expand Down Expand Up @@ -2530,7 +2533,7 @@ private String getPrimitiveType(Schema schema) {
} else if (ModelUtils.isShortSchema(schema)) {// int32
return "integer";
} else {
return schema.getType(); // integer
return ModelUtils.getSchemaType(schema); // integer
}
} else if (ModelUtils.isMapSchema(schema)) {
return "map";
Expand Down Expand Up @@ -2561,11 +2564,11 @@ private String getPrimitiveType(Schema schema) {
return "object";
} else if (ModelUtils.isAnyType(schema)) {
return "AnyType";
} else if (StringUtils.isNotEmpty(schema.getType())) {
if (!schemaMapping.containsKey(schema.getType())) {
LOGGER.warn("Unknown type found in the schema: {}. To map it, please use the schema mapping option (e.g. --schema-mappings in CLI)", schema.getType());
} else if (StringUtils.isNotEmpty(ModelUtils.getSchemaType(schema))) {
if (!schemaMapping.containsKey(ModelUtils.getSchemaType(schema))) {
LOGGER.warn("Unknown type found in the schema: {}. To map it, please use the schema mapping option (e.g. --schema-mappings in CLI)", ModelUtils.getSchemaType(schema));
}
return schema.getType();
return ModelUtils.getSchemaType(schema);
}
// The 'type' attribute has not been set in the OAS schema, which means the value
// can be an arbitrary type, e.g. integer, string, object, array, number...
Expand Down Expand Up @@ -4005,11 +4008,12 @@ public CodegenProperty fromProperty(String name, Schema p, boolean required, boo

property.name = toVarName(name);
property.baseName = name;
if (p.getType() == null) {
property.openApiType = getSchemaType(p);
} else {
property.openApiType = p.getType();

String propertyType = ModelUtils.getSchemaType(p);
if (propertyType == null) {
propertyType = getSchemaType(p);
}
property.openApiType = propertyType;
property.nameInCamelCase = camelize(property.name);
property.nameInSnakeCase = CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, property.nameInCamelCase);
property.description = escapeText(p.getDescription());
Expand Down Expand Up @@ -4166,8 +4170,7 @@ public CodegenProperty fromProperty(String name, Schema p, boolean required, boo

// handle inner property
String itemName = getItemsName(p, name);
ArraySchema arraySchema = (ArraySchema) p;
Schema innerSchema = unaliasSchema(getSchemaItems(arraySchema));
Schema innerSchema = unaliasSchema(getSchemaItems(p));
CodegenProperty cp = fromProperty(itemName, innerSchema, false);
updatePropertyForArray(property, cp);
} else if (ModelUtils.isTypeObjectSchema(p)) {
Expand Down Expand Up @@ -4477,8 +4480,7 @@ protected void handleMethodResponse(Operation operation,
CodegenProperty cm = fromProperty("response", responseSchema, false);

if (ModelUtils.isArraySchema(responseSchema)) {
ArraySchema as = (ArraySchema) responseSchema;
CodegenProperty innerProperty = fromProperty("response", getSchemaItems(as), false);
CodegenProperty innerProperty = fromProperty("response", getSchemaItems(responseSchema), false);
op.returnBaseType = innerProperty.baseType;
} else if (ModelUtils.isMapSchema(responseSchema)) {
CodegenProperty innerProperty = fromProperty("response", ModelUtils.getAdditionalProperties(responseSchema), false);
Expand Down Expand Up @@ -5005,8 +5007,7 @@ public CodegenResponse fromResponse(String responseCode, ApiResponse response) {
r.isArray = true;
r.containerType = cp.containerType;
r.containerTypeMapped = typeMapping.get(cp.containerType);
ArraySchema as = (ArraySchema) responseSchema;
CodegenProperty items = fromProperty("response", getSchemaItems(as), false);
CodegenProperty items = fromProperty("response", getSchemaItems(responseSchema), false);
r.setItems(items);
CodegenProperty innerCp = items;

Expand Down Expand Up @@ -5382,8 +5383,7 @@ public CodegenParameter fromParameter(Parameter parameter, Set<String> imports)
}
addVarsRequiredVarsAdditionalProps(parameterSchema, codegenParameter);
} else if (ModelUtils.isArraySchema(parameterSchema)) {
final ArraySchema arraySchema = (ArraySchema) parameterSchema;
Schema inner = getSchemaItems(arraySchema);
Schema inner = getSchemaItems(parameterSchema);

collectionFormat = getCollectionFormat(parameter);
// default to csv:
Expand Down Expand Up @@ -7111,7 +7111,7 @@ public List<CodegenParameter> fromRequestBodyToFormParameters(RequestBody body,
Schema original = null;
// check if it's allOf (only 1 sub schema) with or without default/nullable/etc set in the top level
if (ModelUtils.isAllOf(schema) && schema.getAllOf().size() == 1 &&
schema.getType() == null && schema.getTypes() == null) {
ModelUtils.getSchemaType(schema) == null) {
if (schema.getAllOf().get(0) instanceof Schema) {
original = schema;
schema = (Schema) schema.getAllOf().get(0);
Expand Down Expand Up @@ -7256,7 +7256,7 @@ public CodegenParameter fromFormProperty(String name, Schema propertySchema, Set
} else if (ModelUtils.isAnyType(ps)) {
// any schema with no type set, composed schemas often do this
} else if (ModelUtils.isArraySchema(ps)) {
Schema inner = getSchemaItems((ArraySchema) ps);
Schema inner = getSchemaItems(ps);
CodegenProperty arrayInnerProperty = fromProperty("inner", inner, false);
codegenParameter.items = arrayInnerProperty;
codegenParameter.mostInnerItems = arrayInnerProperty.mostInnerItems;
Expand Down Expand Up @@ -7537,11 +7537,10 @@ protected void updateRequestBodyForArray(CodegenParameter codegenParameter, Sche
if (ModelUtils.isGenerateAliasAsModel(schema) && StringUtils.isNotBlank(name)) {
this.addBodyModelSchema(codegenParameter, name, schema, imports, bodyParameterName, true);
} else {
final ArraySchema arraySchema = (ArraySchema) schema;
Schema inner = getSchemaItems(arraySchema);
CodegenProperty codegenProperty = fromProperty("property", arraySchema, false);
Schema inner = getSchemaItems(schema);
CodegenProperty codegenProperty = fromProperty("property", schema, false);
if (codegenProperty == null) {
throw new RuntimeException("CodegenProperty cannot be null. arraySchema for debugging: " + arraySchema);
throw new RuntimeException("CodegenProperty cannot be null. arraySchema for debugging: " + schema);
}

imports.add(codegenProperty.baseType);
Expand Down Expand Up @@ -7569,7 +7568,7 @@ protected void updateRequestBodyForArray(CodegenParameter codegenParameter, Sche
codegenParameter.paramName = toArrayModelParamName(codegenParameter.baseName);
codegenParameter.items = codegenProperty.items;
codegenParameter.mostInnerItems = codegenProperty.mostInnerItems;
codegenParameter.dataType = getTypeDeclaration(arraySchema);
codegenParameter.dataType = getTypeDeclaration(schema);
codegenParameter.baseType = getSchemaType(inner);
codegenParameter.isContainer = Boolean.TRUE;
codegenParameter.isNullable = codegenProperty.isNullable;
Expand Down Expand Up @@ -7745,7 +7744,7 @@ public CodegenParameter fromRequestBody(RequestBody body, Set<String> imports, S
Schema original = null;
// check if it's allOf (only 1 sub schema) with or without default/nullable/etc set in the top level
if (ModelUtils.isAllOf(schema) && schema.getAllOf().size() == 1 &&
schema.getType() == null && schema.getTypes() == null) {
ModelUtils.getSchemaType(schema) == null) {
if (schema.getAllOf().get(0) instanceof Schema) {
original = schema;
schema = (Schema) schema.getAllOf().get(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ private boolean isModelNeeded(Schema schema, Set<Schema> visitedSchemas) {
if (resolveInlineEnums && schema.getEnum() != null && schema.getEnum().size() > 0) {
return true;
}
if (schema.getType() == null || "object".equals(schema.getType())) {
if (ModelUtils.getSchemaType(schema) == null || ModelUtils.isTypeObjectSchema(schema)) {
// object or undeclared type with properties
if (schema.getProperties() != null && schema.getProperties().size() > 0) {
return true;
Expand Down Expand Up @@ -269,7 +269,7 @@ private void gatherInlineModels(Schema schema, String modelPrefix) {
if (schema.get$ref() != null) {
// if ref already, no inline schemas should be present but check for
// any to catch OpenAPI violations
if (isModelNeeded(schema) || "object".equals(schema.getType()) ||
if (isModelNeeded(schema) || ModelUtils.isTypeObjectSchema(schema) ||
schema.getProperties() != null || schema.getAdditionalProperties() != null ||
ModelUtils.isComposedSchema(schema)) {
LOGGER.error("Illegal schema found with $ref combined with other properties," +
Expand All @@ -280,7 +280,7 @@ private void gatherInlineModels(Schema schema, String modelPrefix) {
// Check object models / any type models / composed models for properties,
// if the schema has a type defined that is not "object" it should not define
// any properties
if (schema.getType() == null || "object".equals(schema.getType())) {
if (ModelUtils.getSchemaType(schema) == null || ModelUtils.isTypeObjectSchema(schema)) {
// Check properties and recurse, each property could be its own inline model
Map<String, Schema> props = schema.getProperties();
if (props != null) {
Expand All @@ -300,8 +300,8 @@ private void gatherInlineModels(Schema schema, String modelPrefix) {
props.put(propName, refSchema);
} else if (ModelUtils.isComposedSchema(prop)) {
if (prop.getAllOf() != null && prop.getAllOf().size() == 1 &&
!(((Schema) prop.getAllOf().get(0)).getType() == null ||
"object".equals(((Schema) prop.getAllOf().get(0)).getType()))) {
!(ModelUtils.getSchemaType((Schema) prop.getAllOf().get(0)) == null) ||
ModelUtils.isTypeObjectSchema((Schema) prop.getAllOf().get(0))) {
// allOf with only 1 type (non-model)
LOGGER.info("allOf schema used by the property `{}` replaced by its only item (a type)", propName);
props.put(propName, (Schema) prop.getAllOf().get(0));
Expand Down Expand Up @@ -338,10 +338,9 @@ private void gatherInlineModels(Schema schema, String modelPrefix) {
return;
}
// Check array items
if (schema instanceof ArraySchema) {
ArraySchema array = (ArraySchema) schema;
Schema items = array.getItems();
if (items == null && array.getPrefixItems() == null) {
if (ModelUtils.isArraySchema(schema)) {
Schema items = schema.getItems();
if (items == null && schema.getPrefixItems() == null) {
LOGGER.debug("Incorrect array schema with no items, prefixItems: {}", schema.toString());
return;
}
Expand All @@ -357,7 +356,7 @@ private void gatherInlineModels(Schema schema, String modelPrefix) {

if (isModelNeeded(items)) {
// If this schema should be split into its own model, do so
array.setItems(this.makeSchemaInComponents(schemaName, items));
schema.setItems(this.makeSchemaInComponents(schemaName, items));
}
}
// Check allOf, anyOf, oneOf for inline models
Expand Down Expand Up @@ -666,18 +665,14 @@ private void flattenComponents() {
* @param m Schema implementation
*/
private void fixStringModel(Schema m) {
if (schemaIsOfType(m, "string") && schemaContainsExample(m)) {
if (ModelUtils.isStringSchema(m) && schemaContainsExample(m)) {
String example = m.getExample().toString();
if (example.startsWith("\"") && example.endsWith("\"")) {
m.setExample(example.substring(1, example.length() - 1));
}
}
}

private boolean schemaIsOfType(Schema m, String type) {
return m.getType() != null && m.getType().equals(type);
}

private boolean schemaContainsExample(Schema m) {
return m.getExample() != null && m.getExample() != "";
}
Expand Down Expand Up @@ -788,9 +783,8 @@ private void flattenProperties(OpenAPI openAPI, Map<String, Schema> properties,
propsToUpdate.put(key, schema);
modelsToAdd.put(modelName, model);
}
} else if (property instanceof ArraySchema) {
ArraySchema ap = (ArraySchema) property;
Schema inner = ap.getItems();
} else if (ModelUtils.isArraySchema(property)) {
Schema inner = property.getItems();
if (inner instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) inner;
if (op.getProperties() != null && op.getProperties().size() > 0) {
Expand All @@ -801,12 +795,12 @@ private void flattenProperties(OpenAPI openAPI, Map<String, Schema> properties,
if (existing != null) {
Schema schema = new Schema().$ref(existing);
schema.setRequired(op.getRequired());
ap.setItems(schema);
property.setItems(schema);
} else {
modelName = addSchemas(modelName, innerModel);
Schema schema = new Schema().$ref(modelName);
schema.setRequired(op.getRequired());
ap.setItems(schema);
property.setItems(schema);
}
}
} else if (ModelUtils.isComposedSchema(inner)) {
Expand All @@ -815,7 +809,7 @@ private void flattenProperties(OpenAPI openAPI, Map<String, Schema> properties,
innerModelName = addSchemas(innerModelName, inner);
Schema schema = new Schema().$ref(innerModelName);
schema.setRequired(inner.getRequired());
ap.setItems(schema);
property.setItems(schema);
} else {
LOGGER.debug("Schema not yet handled in model resolver: {}", inner);
}
Expand Down Expand Up @@ -892,7 +886,7 @@ private Schema modelFromProperty(OpenAPI openAPI, Schema object, String path) {
// NOTE:
// No need to null check setters below. All defaults in the new'd Schema are null, so setting to null would just be a noop.
Schema model = new Schema();
model.setType(object.getType());
model.setType(ModelUtils.getSchemaType(object));

// Even though the `format` keyword typically applies to primitive types only,
// the JSON schema specification states `format` can be used for any model type instance
Expand All @@ -908,7 +902,7 @@ private Schema modelFromProperty(OpenAPI openAPI, Schema object, String path) {
model.setRequired(object.getRequired());
model.setNullable(object.getNullable());
model.setEnum(object.getEnum());
model.setType(object.getType());
model.setType(ModelUtils.getSchemaType(object));
model.setDiscriminator(object.getDiscriminator());
model.setWriteOnly(object.getWriteOnly());
model.setUniqueItems(object.getUniqueItems());
Expand Down
Loading