Skip to content

Commit

Permalink
[all] Support for Free-Form Objects
Browse files Browse the repository at this point in the history
Consider "additionalProperties: true"

Fixes OpenAPITools#796
  • Loading branch information
jmini committed Aug 20, 2018
1 parent a3e5edc commit 3814535
Show file tree
Hide file tree
Showing 58 changed files with 172 additions and 95 deletions.
Expand Up @@ -75,7 +75,6 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
Expand Down Expand Up @@ -1094,7 +1093,7 @@ public String generateExamplePath(String path, Operation operation) {
*/
public String toInstantiationType(Schema schema) {
if (ModelUtils.isMapSchema(schema)) {
Schema additionalProperties = (Schema) schema.getAdditionalProperties();
Schema additionalProperties = ModelUtils.getAdditionalProperties(schema);
String type = additionalProperties.getType();
if (null == type) {
LOGGER.error("No Type defined for Additional Property " + additionalProperties + "\n" //
Expand Down Expand Up @@ -1998,7 +1997,7 @@ public CodegenProperty fromProperty(String name, Schema p) {
property.maxItems = p.getMaxProperties();

// handle inner property
CodegenProperty cp = fromProperty("inner", (Schema) p.getAdditionalProperties());
CodegenProperty cp = fromProperty("inner", ModelUtils.getAdditionalProperties(p));
updatePropertyForMap(property, cp);
} else { // model
// TODO revise the logic below
Expand Down Expand Up @@ -2288,7 +2287,7 @@ public CodegenOperation fromOperation(String path,
CodegenProperty innerProperty = fromProperty("response", as.getItems());
op.returnBaseType = innerProperty.baseType;
} else if (ModelUtils.isMapSchema(responseSchema)) {
CodegenProperty innerProperty = fromProperty("response", (Schema) responseSchema.getAdditionalProperties());
CodegenProperty innerProperty = fromProperty("response", ModelUtils.getAdditionalProperties(responseSchema));
op.returnBaseType = innerProperty.baseType;
} else {
if (cm.complexType != null) {
Expand Down Expand Up @@ -2674,7 +2673,7 @@ public CodegenParameter fromParameter(Parameter parameter, Set<String> imports)
}

} else if (ModelUtils.isMapSchema(parameterSchema)) { // for map parameter
CodegenProperty codegenProperty = fromProperty("inner", (Schema) parameterSchema.getAdditionalProperties());
CodegenProperty codegenProperty = fromProperty("inner", ModelUtils.getAdditionalProperties(parameterSchema));
codegenParameter.items = codegenProperty;
codegenParameter.mostInnerItems = codegenProperty.mostInnerItems;
codegenParameter.baseType = codegenProperty.dataType;
Expand Down Expand Up @@ -4381,7 +4380,7 @@ public CodegenParameter fromRequestBody(RequestBody body, Map<String, Schema> sc
}

if (ModelUtils.isMapSchema(schema)) {
Schema inner = (Schema) schema.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(schema);
if (inner == null) {
inner = new StringSchema().description("//TODO automatically added by openapi-generator");
schema.setAdditionalProperties(inner);
Expand Down Expand Up @@ -4469,7 +4468,7 @@ public CodegenParameter fromRequestBody(RequestBody body, Map<String, Schema> sc
imports.add(codegenParameter.baseType);
} else {
CodegenProperty codegenProperty = fromProperty("property", schema);
if (schema.getAdditionalProperties() != null) {// http body is map
if (ModelUtils.getAdditionalProperties(schema) != null) {// http body is map
LOGGER.error("Map should be supported. Please report to openapi-generator github repo about the issue.");
} else if (codegenProperty != null) {
String codegenModelName, codegenModelDescription;
Expand Down
Expand Up @@ -238,7 +238,7 @@ public void flatten(OpenAPI openapi) {
}
} else if (property instanceof MapSchema) {
MapSchema mp = (MapSchema) property;
Schema innerProperty = (Schema) mp.getAdditionalProperties();
Schema innerProperty = ModelUtils.getAdditionalProperties(mp);
if (innerProperty instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) innerProperty;
if (op.getProperties() != null && op.getProperties().size() > 0) {
Expand Down Expand Up @@ -431,7 +431,7 @@ public void flattenProperties(Map<String, Schema> properties, String path) {
}
}
if (ModelUtils.isMapSchema(property)) {
Schema inner = (Schema) property.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(property);
if (inner instanceof ObjectSchema) {
ObjectSchema op = (ObjectSchema) inner;
if (op.getProperties() != null && op.getProperties().size() > 0) {
Expand Down Expand Up @@ -519,7 +519,7 @@ public Schema modelFromProperty(MapSchema object, @SuppressWarnings("unused") St
model.setDescription(description);
model.setName(object.getName());
model.setExample(example);
model.setItems((Schema) object.getAdditionalProperties());
model.setItems(ModelUtils.getAdditionalProperties(object));
return model;
}

Expand Down
Expand Up @@ -236,10 +236,10 @@ private Object resolvePropertyToExample(String propertyName, String mediaType, S
Map<String, Object> mp = new HashMap<String, Object>();
if (property.getName() != null) {
mp.put(property.getName(),
resolvePropertyToExample(propertyName, mediaType, (Schema) property.getAdditionalProperties(), processedModels));
resolvePropertyToExample(propertyName, mediaType, ModelUtils.getAdditionalProperties(property), processedModels));
} else {
mp.put("key",
resolvePropertyToExample(propertyName, mediaType, (Schema) property.getAdditionalProperties(), processedModels));
resolvePropertyToExample(propertyName, mediaType, ModelUtils.getAdditionalProperties(property), processedModels));
}
return mp;
} else if (ModelUtils.isUUIDSchema(property)) {
Expand Down
Expand Up @@ -329,7 +329,7 @@ public String getTypeDeclaration(Schema p) {
return getTypeDeclaration(inner) + "_Vectors.Vector";
}
if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(p);
String name = getTypeDeclaration(inner) + "_Map";
if (name.startsWith("Swagger.")) {
return name;
Expand Down
Expand Up @@ -18,12 +18,12 @@
package org.openapitools.codegen.languages;

import java.util.*;
import org.apache.commons.lang3.StringUtils;
import com.google.common.base.Strings;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenParameter;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.DefaultCodegen;
Expand Down Expand Up @@ -196,7 +196,7 @@ public String getTypeDeclaration(Schema p) {
}
return getSchemaType(p) + "<" + getTypeDeclaration(inner) + ">";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(p);

if (inner == null) {
LOGGER.warn(p.getName() + "(map property) does not have a proper inner type defined");
Expand Down Expand Up @@ -229,11 +229,11 @@ public String toDefaultValue(Schema p) {
} else if (ModelUtils.isMapSchema(p)) {
final MapSchema ap = (MapSchema) p;
final String pattern = "new HashMap<%s>()";
if (ap.getAdditionalProperties() == null) {
if (ModelUtils.getAdditionalProperties(ap) == null) {
return null;
}

return String.format(pattern, String.format("String, %s", getTypeDeclaration((Schema) ap.getAdditionalProperties())));
return String.format(pattern, String.format("String, %s", getTypeDeclaration(ModelUtils.getAdditionalProperties(ap))));
} else if (ModelUtils.isLongSchema(p)) {
if (p.getDefault() != null) {
return p.getDefault().toString() + "l";
Expand Down Expand Up @@ -366,7 +366,7 @@ public String toExampleValue(Schema p) {
} else if (ModelUtils.isLongSchema(p)) {
example = example.isEmpty() ? "123456789L" : example + "L";
} else if (ModelUtils.isMapSchema(p)) {
example = "new " + getTypeDeclaration(p) + "{'key'=>" + toExampleValue((Schema) p.getAdditionalProperties()) + "}";
example = "new " + getTypeDeclaration(p) + "{'key'=>" + toExampleValue(ModelUtils.getAdditionalProperties(p)) + "}";

} else if (ModelUtils.isPasswordSchema(p)) {
example = example.isEmpty() ? "password123" : escapeText(example);
Expand Down
Expand Up @@ -811,7 +811,7 @@ public String getTypeDeclaration(Schema p) {
return getArrayTypeDeclaration((ArraySchema) p);
} else if (ModelUtils.isMapSchema(p)) {
// Should we also support maps of maps?
Schema inner = (Schema) p.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(p);
return getSchemaType(p) + "<string, " + getTypeDeclaration(inner) + ">";
}
return super.getTypeDeclaration(p);
Expand Down
Expand Up @@ -290,7 +290,7 @@ public String getTypeDeclaration(Schema p) {
Schema inner = ap.getItems();
return "LIST [" + getTypeDeclaration(inner) + "]";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(p);

return getSchemaType(p) + "[" + getTypeDeclaration(inner) + "]";
}
Expand Down Expand Up @@ -557,7 +557,7 @@ public Map<String, String> createMapping(String key, String value) {
@Override
public String toInstantiationType(Schema p) {
if (ModelUtils.isMapSchema(p)) {
Schema additionalProperties2 = (Schema) p.getAdditionalProperties();
Schema additionalProperties2 = ModelUtils.getAdditionalProperties(p);
String type = additionalProperties2.getType();
if (null == type) {
LOGGER.error("No Type defined for Additional Schema " + additionalProperties2 + "\n" //
Expand Down
Expand Up @@ -258,7 +258,7 @@ public String getTypeDeclaration(Schema p) {
Schema inner = ap.getItems();
return "[]" + getTypeDeclaration(inner);
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(p);
return getSchemaType(p) + "[string]" + getTypeDeclaration(inner);
}
//return super.getTypeDeclaration(p);
Expand Down
Expand Up @@ -679,7 +679,7 @@ public String getTypeDeclaration(Schema p) {
}
return getSchemaType(p) + "<" + getTypeDeclaration(inner) + ">";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(p);
if (inner == null) {
LOGGER.warn(p.getName() + "(map property) does not have a proper inner type defined. Default to string");
inner = new StringSchema().description("TODO default missing array inner type to string");
Expand Down Expand Up @@ -728,11 +728,11 @@ public String toDefaultValue(Schema p) {
} else {
pattern = "new HashMap<%s>()";
}
if (p.getAdditionalProperties() == null) {
if (ModelUtils.getAdditionalProperties(p) == null) {
return null;
}

String typeDeclaration = String.format("String, %s", getTypeDeclaration((Schema) p.getAdditionalProperties()));
String typeDeclaration = String.format("String, %s", getTypeDeclaration(ModelUtils.getAdditionalProperties(p)));
Object java8obj = additionalProperties.get("java8");
if (java8obj != null) {
Boolean java8 = Boolean.valueOf(java8obj.toString());
Expand Down
Expand Up @@ -282,7 +282,7 @@ public String getTypeDeclaration(Schema p) {
if (ModelUtils.isArraySchema(p)) {
return getArrayTypeDeclaration((ArraySchema) p);
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(p);

// Maps will be keyed only by primitive Kotlin string
return getSchemaType(p) + "<kotlin.String, " + getTypeDeclaration(inner) + ">";
Expand Down
Expand Up @@ -328,7 +328,7 @@ public String getTypeDeclaration(Schema p) {
Schema inner = ap.getItems();
return getTypeDeclaration(inner) + "[]";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(p);
return getSchemaType(p) + "[string," + getTypeDeclaration(inner) + "]";
} else if (StringUtils.isNotBlank(p.get$ref())) { // model
String type = super.getTypeDeclaration(p);
Expand Down
Expand Up @@ -88,7 +88,7 @@ public String getTypeDeclaration(Schema schema) {
Schema inner = ((ArraySchema) schema).getItems();
return getSchemaType(schema) + "<" + getTypeDeclaration(inner) + ">";
} else if (ModelUtils.isMapSchema(schema)) {
Schema inner = (Schema) schema.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(schema);
return getSchemaType(schema) + "<String, " + getTypeDeclaration(inner) + ">";
}

Expand Down
Expand Up @@ -181,7 +181,7 @@ public String getTypeDeclaration(Schema p) {
Schema inner = ap.getItems();
return getSchemaType(p) + "[" + getTypeDeclaration(inner) + "]";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(p);

return getSchemaType(p) + "[String, " + getTypeDeclaration(inner) + "]";
}
Expand All @@ -206,7 +206,7 @@ public String getSchemaType(Schema p) {
@Override
public String toInstantiationType(Schema p) {
if (ModelUtils.isMapSchema(p)) {
String inner = getSchemaType((Schema) p.getAdditionalProperties());
String inner = getSchemaType(ModelUtils.getAdditionalProperties(p));
return instantiationTypes.get("map") + "[String, " + inner + "]";
} else if (ModelUtils.isArraySchema(p)) {
ArraySchema ap = (ArraySchema) p;
Expand Down Expand Up @@ -235,7 +235,7 @@ public String toDefaultValue(Schema p) {
} else if (ModelUtils.isIntegerSchema(p)) {
return null;
} else if (ModelUtils.isMapSchema(p)) {
String inner = getSchemaType((Schema) p.getAdditionalProperties());
String inner = getSchemaType(ModelUtils.getAdditionalProperties(p));
return "new HashMap[String, " + inner + "]() ";
} else if (ModelUtils.isArraySchema(p)) {
ArraySchema ap = (ArraySchema) p;
Expand Down
Expand Up @@ -227,7 +227,7 @@ public String getTypeDeclaration(Schema p) {
Schema inner = ap.getItems();
return getSchemaType(p) + "<" + getTypeDeclaration(inner) + ">";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(p);
return "{ [key: string]: " + getTypeDeclaration(inner) + "; }";
} else if (ModelUtils.isFileSchema(p)) {
return "any";
Expand All @@ -246,7 +246,7 @@ protected String getParameterDataType(Parameter parameter, Schema p) {
inner = mp1.getItems();
return this.getSchemaType(p) + "<" + this.getParameterDataType(parameter, inner) + ">";
} else if (ModelUtils.isMapSchema(p)) {
inner = (Schema) p.getAdditionalProperties();
inner = ModelUtils.getAdditionalProperties(p);
return "{ [key: string]: " + this.getParameterDataType(parameter, inner) + "; }";
} else if (ModelUtils.isStringSchema(p)) {
// Handle string enums
Expand Down
Expand Up @@ -189,7 +189,7 @@ public String getTypeDeclaration(Schema p) {
Schema inner = ap.getItems();
return getSchemaType(p) + "<" + getTypeDeclaration(inner) + ">";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(p);

return getSchemaType(p) + "<String, " + getTypeDeclaration(inner) + ">";
}
Expand Down
Expand Up @@ -227,7 +227,7 @@ public String toDefaultValue(Schema p) {
Long def = (Long) p.getDefault();
out = def == null ? out : def.toString() + "L";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(p);
String s = inner == null ? "Object" : getTypeDeclaration(inner);
out = String.format("new Map<String, %s>()", s);
} else if (ModelUtils.isStringSchema(p)) {
Expand Down
Expand Up @@ -388,7 +388,7 @@ public String getTypeDeclaration(Schema p) {
Schema inner = ap.getItems();
return getSchemaType(p) + "[" + getTypeDeclaration(inner) + "]";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(p);
return getSchemaType(p) + "[String, " + getTypeDeclaration(inner) + "]";
}
return super.getTypeDeclaration(p);
Expand Down
Expand Up @@ -99,7 +99,7 @@ public String getTypeDeclaration(Schema p) {
Schema inner = ap.getItems();
return getSchemaType(p) + "[" + getTypeDeclaration(inner) + "]";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(p);
return getSchemaType(p) + "[String, " + getTypeDeclaration(inner) + "]";
}
return super.getTypeDeclaration(p);
Expand Down
Expand Up @@ -305,7 +305,7 @@ public String getTypeDeclaration(Schema p) {
return getSchemaType(p) + "<" + getTypeDeclaration(inner) + ">";
}
if (ModelUtils.isMapSchema(p)) {
Schema inner = (Schema) p.getAdditionalProperties();
Schema inner = ModelUtils.getAdditionalProperties(p);
return getSchemaType(p) + "<std::string, " + getTypeDeclaration(inner) + ">";
}
else if (ModelUtils.isByteArraySchema(p)) {
Expand Down Expand Up @@ -343,7 +343,7 @@ public String toDefaultValue(Schema p) {
else if (ModelUtils.isByteArraySchema(p)) {
return "\"\"";
} else if (ModelUtils.isMapSchema(p)) {
String inner = getSchemaType((Schema) p.getAdditionalProperties());
String inner = getSchemaType(ModelUtils.getAdditionalProperties(p));
return "std::map<std::string, " + inner + ">()";
} else if (ModelUtils.isArraySchema(p)) {
ArraySchema ap = (ArraySchema) p;
Expand Down

0 comments on commit 3814535

Please sign in to comment.