From c847f34f53e12da38c59ef936d7438c9b2e56281 Mon Sep 17 00:00:00 2001 From: William Cheng Date: Sun, 28 Oct 2018 20:30:32 +0800 Subject: [PATCH 1/4] add utility methods for models --- .../openapitools/codegen/CodegenResponse.java | 139 +++++++++--------- .../openapitools/codegen/DefaultCodegen.java | 3 +- .../codegen/utils/ModelUtils.java | 67 ++++++++- 3 files changed, 139 insertions(+), 70 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java index 642e44a810f6..808a52da87dc 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java @@ -17,11 +17,7 @@ package org.openapitools.codegen; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; +import java.util.*; public class CodegenResponse { public final List headers = new ArrayList(); @@ -30,7 +26,8 @@ public class CodegenResponse { public List> examples; public String dataType, baseType, containerType; public boolean hasHeaders; - public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBoolean, isDate, isDateTime, isUuid, isEmail; + public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBoolean, isDate, + isDateTime, isUuid, isEmail, isModel; public boolean isDefault; public boolean simpleType; public boolean primitiveType; @@ -48,76 +45,86 @@ public boolean isWildcard() { @Override public String toString() { - return String.format(Locale.ROOT, "%s(%s)", code, containerType); + return "CodegenResponse{" + + "headers=" + headers + + ", code='" + code + '\'' + + ", message='" + message + '\'' + + ", hasMore=" + hasMore + + ", examples=" + examples + + ", dataType='" + dataType + '\'' + + ", baseType='" + baseType + '\'' + + ", containerType='" + containerType + '\'' + + ", hasHeaders=" + hasHeaders + + ", isString=" + isString + + ", isNumeric=" + isNumeric + + ", isInteger=" + isInteger + + ", isLong=" + isLong + + ", isNumber=" + isNumber + + ", isFloat=" + isFloat + + ", isDouble=" + isDouble + + ", isByteArray=" + isByteArray + + ", isBoolean=" + isBoolean + + ", isDate=" + isDate + + ", isDateTime=" + isDateTime + + ", isUuid=" + isUuid + + ", isEmail=" + isEmail + + ", isModel=" + isModel + + ", isDefault=" + isDefault + + ", simpleType=" + simpleType + + ", primitiveType=" + primitiveType + + ", isMapContainer=" + isMapContainer + + ", isListContainer=" + isListContainer + + ", isBinary=" + isBinary + + ", isFile=" + isFile + + ", schema=" + schema + + ", jsonSchema='" + jsonSchema + '\'' + + ", vendorExtensions=" + vendorExtensions + + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - CodegenResponse that = (CodegenResponse) o; - - if (!headers.equals(that.headers)) - return false; - if (code != null ? !code.equals(that.code) : that.code != null) - return false; - if (message != null ? !message.equals(that.message) : that.message != null) - return false; - if (hasMore != that.hasMore) - return false; - if (examples != null ? !examples.equals(that.examples) : that.examples != null) - return false; - if (dataType != null ? !dataType.equals(that.dataType) : that.dataType != null) - return false; - if (baseType != null ? !baseType.equals(that.baseType) : that.baseType != null) - return false; - if (containerType != null ? !containerType.equals(that.containerType) : that.containerType != null) - return false; - if (isDefault != that.isDefault) - return false; - if (simpleType != that.simpleType) - return false; - if (primitiveType != that.primitiveType) - return false; - if (isMapContainer != that.isMapContainer) - return false; - if (isListContainer != that.isListContainer) - return false; - if (isBinary != that.isBinary) - return false; - if (isFile != that.isFile) - return false; - if (isNumeric != that.isNumeric) - return false; - if (schema != null ? !schema.equals(that.schema) : that.schema != null) - return false; - if (vendorExtensions != null ? !vendorExtensions.equals(that.vendorExtensions) : that.vendorExtensions != null) - return false; - return jsonSchema != null ? jsonSchema.equals(that.jsonSchema) : that.jsonSchema == null; + return hasMore == that.hasMore && + hasHeaders == that.hasHeaders && + isString == that.isString && + isNumeric == that.isNumeric && + isInteger == that.isInteger && + isLong == that.isLong && + isNumber == that.isNumber && + isFloat == that.isFloat && + isDouble == that.isDouble && + isByteArray == that.isByteArray && + isBoolean == that.isBoolean && + isDate == that.isDate && + isDateTime == that.isDateTime && + isUuid == that.isUuid && + isEmail == that.isEmail && + isModel == that.isModel && + isDefault == that.isDefault && + simpleType == that.simpleType && + primitiveType == that.primitiveType && + isMapContainer == that.isMapContainer && + isListContainer == that.isListContainer && + isBinary == that.isBinary && + isFile == that.isFile && + Objects.equals(headers, that.headers) && + Objects.equals(code, that.code) && + Objects.equals(message, that.message) && + Objects.equals(examples, that.examples) && + Objects.equals(dataType, that.dataType) && + Objects.equals(baseType, that.baseType) && + Objects.equals(containerType, that.containerType) && + Objects.equals(schema, that.schema) && + Objects.equals(jsonSchema, that.jsonSchema) && + Objects.equals(vendorExtensions, that.vendorExtensions); } @Override public int hashCode() { - int result = headers.hashCode(); - result = 31 * result + (code != null ? code.hashCode() : 0); - result = 31 * result + (message != null ? message.hashCode() : 0); - result = 31 * result + (hasMore ? 13:31); - result = 31 * result + (examples != null ? examples.hashCode() : 0); - result = 31 * result + (dataType != null ? dataType.hashCode() : 0); - result = 31 * result + (baseType != null ? baseType.hashCode() : 0); - result = 31 * result + (containerType != null ? containerType.hashCode() : 0); - result = 31 * result + (isDefault ? 13:31); - result = 31 * result + (isNumeric ? 13:31); - result = 31 * result + (simpleType ? 13:31); - result = 31 * result + (primitiveType ? 13:31); - result = 31 * result + (isMapContainer ? 13:31); - result = 31 * result + (isListContainer ? 13:31); - result = 31 * result + (isBinary ? 13:31); - result = 31 * result + (isFile ? 13:31); - result = 31 * result + (schema != null ? schema.hashCode() : 0); - result = 31 * result + (jsonSchema != null ? jsonSchema.hashCode() : 0); - result = 31 * result + (vendorExtensions != null ? vendorExtensions.hashCode() : 0); - return result; + + return Objects.hash(headers, code, message, hasMore, examples, dataType, baseType, containerType, hasHeaders, isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBoolean, isDate, isDateTime, isUuid, isEmail, isModel, isDefault, simpleType, primitiveType, isMapContainer, isListContainer, isBinary, isFile, schema, jsonSchema, vendorExtensions); } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index b1adc8ffa84a..1869fbd413c0 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -2576,6 +2576,7 @@ public CodegenResponse fromResponse(OpenAPI openAPI, String responseCode, ApiRes } else { if (cp.complexType != null) { r.baseType = cp.complexType; + r.isModel = true; } else { r.baseType = cp.baseType; } @@ -4729,7 +4730,7 @@ public boolean isEnablePostProcessFile() { /** * Set the boolean value indicating the state of the option for post-processing file using envirionment variables. * - * @param enablePostProcessFile true to enable post-processing file + * @param enablePostProcessFile true to enable post-processing file */ public void setEnablePostProcessFile(boolean enablePostProcessFile) { this.enablePostProcessFile = enablePostProcessFile; diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java index 4a1dd19ee602..4bd891240636 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java @@ -501,7 +501,68 @@ public static boolean isEmailSchema(Schema schema) { } /** - * If a Schema contains a reference to an other Schema with '$ref', returns the referenced Schema if it is found or the actual Schema in the other cases. + * Check to see if the schema is a model with at least one properties + * + * @param schema potentially containing a '$ref' + * @return true if it's a model with at least one properties + */ + public static boolean isModel(Schema schema) { + if (schema == null) { + LOGGER.error("Schema cannot be null in isModel check"); + return false; + } + + // has at least one property + if (schema.getProperties() != null && !schema.getProperties().isEmpty()) { + return true; + } + + // composed schema is a model + if (schema instanceof ComposedSchema) { + return true; + } + + return false; + } + + /** + * Check to see if the schema is a free form object + * + * @param schema potentially containing a '$ref' + * @return true if it's a free-form object + */ + public static boolean isFreeFormObject(Schema schema) { + if (schema == null) { + LOGGER.error("Schema cannot be null in isFreeFormObject check"); + return false; + } + + // has at least one property + if ("object".equals(schema.getType())) { + // no properties + if ((schema.getProperties() == null || schema.getProperties().isEmpty())) { + + if (schema.getAdditionalProperties() == null) { + return true; + } else { + // additionalProperties set to true + if (schema.getAdditionalProperties() instanceof Boolean && (Boolean) schema.getAdditionalProperties()) { + return true; + } + + // additionalProperties is set to {} + if (schema.getAdditionalProperties() instanceof Schema && schema.getAdditionalProperties() != null) { + return true; + } + } + } + } + + return false; + } + + /** + * If a Schema contains a reference to another Schema with '$ref', returns the referenced Schema if it is found or the actual Schema in the other cases. * * @param openAPI specification being checked * @param schema potentially containing a '$ref' @@ -623,7 +684,7 @@ public static Parameter getParameter(OpenAPI openAPI, String name) { /** * If a Callback contains a reference to an other Callback with '$ref', returns the referenced Callback if it is found or the actual Callback in the other cases. * - * @param openAPI specification being checked + * @param openAPI specification being checked * @param callback potentially containing a '$ref' * @return callback without '$ref' */ @@ -642,7 +703,7 @@ public static Callback getCallback(OpenAPI openAPI, String name) { if (name == null) { return null; } - + if (openAPI != null && openAPI.getComponents() != null && openAPI.getComponents().getCallbacks() != null) { return openAPI.getComponents().getCallbacks().get(name); } From dedcea43c57ff639ed48152ac21c291d3cd3a2ed Mon Sep 17 00:00:00 2001 From: William Cheng Date: Sat, 10 Nov 2018 12:20:40 +0800 Subject: [PATCH 2/4] add isFreeFormObject tag --- .../codegen/CodegenParameter.java | 84 +++++++++-------- .../openapitools/codegen/CodegenProperty.java | 93 ++++++++++--------- .../openapitools/codegen/CodegenResponse.java | 10 +- .../openapitools/codegen/DefaultCodegen.java | 41 ++++++-- .../codegen/utils/ModelUtils.java | 9 +- .../kotlin/KotlinClientCodegenModelTest.java | 2 +- 6 files changed, 142 insertions(+), 97 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenParameter.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenParameter.java index 62aa1f22b8bb..7624815b9489 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenParameter.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenParameter.java @@ -27,11 +27,12 @@ public class CodegenParameter { isCookieParam, isBodyParam, hasMore, isContainer, secondaryParam, isCollectionFormatMulti, isPrimitiveType, isModel; public String baseName, paramName, dataType, datatypeWithEnum, dataFormat, - collectionFormat, description, unescapedDescription, baseType, defaultValue, enumName; + collectionFormat, description, unescapedDescription, baseType, defaultValue, enumName; public String example; // example value (x-example) public String jsonSchema; - public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBinary, isBoolean, isDate, isDateTime, isUuid, isEmail; + public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBinary, + isBoolean, isDate, isDateTime, isUuid, isEmail, isFreeFormObject; public boolean isListContainer, isMapContainer; public boolean isFile; public boolean isEnum; @@ -94,7 +95,7 @@ public class CodegenParameter { * See http://json-schema.org/latest/json-schema-validation.html#anchor14 */ public Number multipleOf; - + public CodegenParameter copy() { CodegenParameter output = new CodegenParameter(); output.isFile = this.isFile; @@ -148,7 +149,7 @@ public CodegenParameter copy() { if (this.mostInnerItems != null) { output.mostInnerItems = this.mostInnerItems; } - if(this.vendorExtensions != null){ + if (this.vendorExtensions != null) { output.vendorExtensions = new HashMap(this.vendorExtensions); } output.hasValidation = this.hasValidation; @@ -167,6 +168,7 @@ public CodegenParameter copy() { output.isDateTime = this.isDateTime; output.isUuid = this.isUuid; output.isEmail = this.isEmail; + output.isFreeFormObject = this.isFreeFormObject; output.isListContainer = this.isListContainer; output.isMapContainer = this.isMapContainer; @@ -259,6 +261,8 @@ public boolean equals(Object o) { return false; if (isEmail != that.isEmail) return false; + if (isFreeFormObject != that.isFreeFormObject) + return false; if (isListContainer != that.isListContainer) return false; if (isMapContainer != that.isMapContainer) @@ -307,18 +311,18 @@ public boolean equals(Object o) { @Override public int hashCode() { - int result = isFormParam ? 13:31; - result = 31 * result + (isQueryParam ? 13:31); - result = 31 * result + (isPathParam ? 13:31); - result = 31 * result + (isHeaderParam ? 13:31); - result = 31 * result + (isCookieParam ? 13:31); - result = 31 * result + (isBodyParam ? 13:31); - result = 31 * result + (hasMore ? 13:31); - result = 31 * result + (isContainer ? 13:31); - result = 31 * result + (secondaryParam ? 13:31); - result = 31 * result + (isCollectionFormatMulti ? 13:31); - result = 31 * result + (isPrimitiveType ? 13:31); - result = 31 * result + (isModel ? 13:31); + int result = isFormParam ? 13 : 31; + result = 31 * result + (isQueryParam ? 13 : 31); + result = 31 * result + (isPathParam ? 13 : 31); + result = 31 * result + (isHeaderParam ? 13 : 31); + result = 31 * result + (isCookieParam ? 13 : 31); + result = 31 * result + (isBodyParam ? 13 : 31); + result = 31 * result + (hasMore ? 13 : 31); + result = 31 * result + (isContainer ? 13 : 31); + result = 31 * result + (secondaryParam ? 13 : 31); + result = 31 * result + (isCollectionFormatMulti ? 13 : 31); + result = 31 * result + (isPrimitiveType ? 13 : 31); + result = 31 * result + (isModel ? 13 : 31); result = 31 * result + (baseName != null ? baseName.hashCode() : 0); result = 31 * result + (paramName != null ? paramName.hashCode() : 0); result = 31 * result + (dataType != null ? dataType.hashCode() : 0); @@ -332,42 +336,43 @@ public int hashCode() { result = 31 * result + (defaultValue != null ? defaultValue.hashCode() : 0); result = 31 * result + (example != null ? example.hashCode() : 0); result = 31 * result + (jsonSchema != null ? jsonSchema.hashCode() : 0); - result = 31 * result + (isString ? 13:31); - result = 31 * result + (isNumeric ? 13:31); - result = 31 * result + (isInteger ? 13:31); - result = 31 * result + (isLong ? 13:31); - result = 31 * result + (isFloat ? 13:31); - result = 31 * result + (isNumber ? 13:31); - result = 31 * result + (isDouble ? 13:31); - result = 31 * result + (isByteArray ? 13:31); - result = 31 * result + (isBinary ? 13:31); - result = 31 * result + (isBoolean ? 13:31); - result = 31 * result + (isDate ? 13:31); - result = 31 * result + (isDateTime ? 13:31); - result = 31 * result + (isUuid ? 13:31); - result = 31 * result + (isEmail ? 13:31); - result = 31 * result + (isListContainer ? 13:31); - result = 31 * result + (isMapContainer ? 13:31); - result = 31 * result + (isFile ? 13:31); + result = 31 * result + (isString ? 13 : 31); + result = 31 * result + (isNumeric ? 13 : 31); + result = 31 * result + (isInteger ? 13 : 31); + result = 31 * result + (isLong ? 13 : 31); + result = 31 * result + (isFloat ? 13 : 31); + result = 31 * result + (isNumber ? 13 : 31); + result = 31 * result + (isDouble ? 13 : 31); + result = 31 * result + (isByteArray ? 13 : 31); + result = 31 * result + (isBinary ? 13 : 31); + result = 31 * result + (isBoolean ? 13 : 31); + result = 31 * result + (isDate ? 13 : 31); + result = 31 * result + (isDateTime ? 13 : 31); + result = 31 * result + (isUuid ? 13 : 31); + result = 31 * result + (isEmail ? 13 : 31); + result = 31 * result + (isFreeFormObject ? 13 : 31); + result = 31 * result + (isListContainer ? 13 : 31); + result = 31 * result + (isMapContainer ? 13 : 31); + result = 31 * result + (isFile ? 13 : 31); result = 31 * result + (isEnum ? 1 : 0); result = 31 * result + (_enum != null ? _enum.hashCode() : 0); result = 31 * result + (allowableValues != null ? allowableValues.hashCode() : 0); result = 31 * result + (items != null ? items.hashCode() : 0); result = 31 * result + (mostInnerItems != null ? mostInnerItems.hashCode() : 0); result = 31 * result + (vendorExtensions != null ? vendorExtensions.hashCode() : 0); - result = 31 * result + (hasValidation ? 13:31); - result = 31 * result + (isNullable ? 13:31); - result = 31 * result + (required ? 13:31); + result = 31 * result + (hasValidation ? 13 : 31); + result = 31 * result + (isNullable ? 13 : 31); + result = 31 * result + (required ? 13 : 31); result = 31 * result + (maximum != null ? maximum.hashCode() : 0); - result = 31 * result + (exclusiveMaximum ? 13:31); + result = 31 * result + (exclusiveMaximum ? 13 : 31); result = 31 * result + (minimum != null ? minimum.hashCode() : 0); - result = 31 * result + (exclusiveMinimum ? 13:31); + result = 31 * result + (exclusiveMinimum ? 13 : 31); result = 31 * result + (maxLength != null ? maxLength.hashCode() : 0); result = 31 * result + (minLength != null ? minLength.hashCode() : 0); result = 31 * result + (pattern != null ? pattern.hashCode() : 0); result = 31 * result + (maxItems != null ? maxItems.hashCode() : 0); result = 31 * result + (minItems != null ? minItems.hashCode() : 0); - result = 31 * result + (uniqueItems ? 13:31); + result = 31 * result + (uniqueItems ? 13 : 31); result = 31 * result + (multipleOf != null ? multipleOf.hashCode() : 0); return result; } @@ -414,6 +419,7 @@ public java.lang.String toString() { ", isDateTime=" + isDateTime + ", isUuid=" + isUuid + ", isEmail=" + isEmail + + ", isFreeFormObject=" + isFreeFormObject + ", isListContainer=" + isListContainer + ", isMapContainer=" + isMapContainer + ", isFile=" + isFile + diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenProperty.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenProperty.java index 3fa796d45f28..7f6688c134ed 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenProperty.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenProperty.java @@ -25,10 +25,12 @@ public class CodegenProperty implements Cloneable { public String baseName, complexType, getter, setter, description, dataType, - datatypeWithEnum, dataFormat, name, min, max, defaultValue, defaultValueWithParam, - baseType, containerType, title; + datatypeWithEnum, dataFormat, name, min, max, defaultValue, defaultValueWithParam, + baseType, containerType, title; - /** The 'description' string without escape charcters needed by some programming languages/targets */ + /** + * The 'description' string without escape charcters needed by some programming languages/targets + */ public String unescapedDescription; /** @@ -56,7 +58,8 @@ public class CodegenProperty implements Cloneable { public boolean hasMore, required, secondaryParam; public boolean hasMoreNonReadOnly; // for model constructor, true if next property is not readonly public boolean isPrimitiveType, isModel, isContainer, isNotContainer; - public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBinary, isFile, isBoolean, isDate, isDateTime, isUuid, isEmail; + public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBinary, isFile, + isBoolean, isDate, isDateTime, isUuid, isEmail, isFreeFormObject; public boolean isListContainer, isMapContainer; public boolean isEnum; public boolean isReadOnly; @@ -84,7 +87,7 @@ public class CodegenProperty implements Cloneable { public String xmlNamespace; public boolean isXmlWrapped = false; - public String getBaseName() { + public String getBaseName() { return baseName; } @@ -125,9 +128,9 @@ public void setDescription(String description) { } /** + * @return dataType * @deprecated since version 3.0.0, use {@link #getDataType()} instead.
* May be removed with the next major release (4.0) - * @return dataType */ @Deprecated public String getDatatype() { @@ -411,8 +414,7 @@ public void setXmlNamespace(String xmlNamespace) { } @Override - public int hashCode() - { + public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((_enum == null) ? 0 : _enum.hashCode()); @@ -429,19 +431,19 @@ public int hashCode() result = prime * result + ((description == null) ? 0 : description.hashCode()); result = prime * result + ((title == null) ? 0 : title.hashCode()); result = prime * result + ((example == null) ? 0 : example.hashCode()); - result = prime * result + (exclusiveMaximum ? 13:31); - result = prime * result + (exclusiveMinimum ? 13:31); + result = prime * result + (exclusiveMaximum ? 13 : 31); + result = prime * result + (exclusiveMinimum ? 13 : 31); result = prime * result + ((getter == null) ? 0 : getter.hashCode()); - result = prime * result + (hasMore ? 13:31); - result = prime * result + ((hasMoreNonReadOnly ? 13:31)); - result = prime * result + ((isContainer ? 13:31)); + result = prime * result + (hasMore ? 13 : 31); + result = prime * result + ((hasMoreNonReadOnly ? 13 : 31)); + result = prime * result + ((isContainer ? 13 : 31)); result = prime * result + (isEnum ? 1231 : 1237); - result = prime * result + ((isNotContainer ? 13:31)); - result = prime * result + ((isPrimitiveType ? 13:31)); - result = prime * result + ((isModel ? 13:31)); - result = prime * result + ((isReadOnly ? 13:31)); - result = prime * result + ((isWriteOnly ? 13:31)); - result = prime * result + ((isNullable ? 13:31)); + result = prime * result + ((isNotContainer ? 13 : 31)); + result = prime * result + ((isPrimitiveType ? 13 : 31)); + result = prime * result + ((isModel ? 13 : 31)); + result = prime * result + ((isReadOnly ? 13 : 31)); + result = prime * result + ((isWriteOnly ? 13 : 31)); + result = prime * result + ((isNullable ? 13 : 31)); result = prime * result + ((items == null) ? 0 : items.hashCode()); result = prime * result + ((mostInnerItems == null) ? 0 : mostInnerItems.hashCode()); result = prime * result + ((jsonSchema == null) ? 0 : jsonSchema.hashCode()); @@ -453,29 +455,30 @@ public int hashCode() result = prime * result + ((minimum == null) ? 0 : minimum.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((pattern == null) ? 0 : pattern.hashCode()); - result = prime * result + ((required ? 13:31)); - result = prime * result + ((secondaryParam ? 13:31)); + result = prime * result + ((required ? 13 : 31)); + result = prime * result + ((secondaryParam ? 13 : 31)); result = prime * result + ((setter == null) ? 0 : setter.hashCode()); result = prime * result + ((unescapedDescription == null) ? 0 : unescapedDescription.hashCode()); result = prime * result + ((vendorExtensions == null) ? 0 : vendorExtensions.hashCode()); - result = prime * result + ((hasValidation ? 13:31)); - result = prime * result + ((isString ? 13:31)); - result = prime * result + ((isNumeric ? 13:31)); - result = prime * result + ((isInteger ? 13:31)); - result = prime * result + ((isLong ?13:31)); - result = prime * result + ((isNumber ? 13:31)); - result = prime * result + ((isFloat ? 13:31)); - result = prime * result + ((isDouble ? 13:31)); - result = prime * result + ((isByteArray ? 13:31)); - result = prime * result + ((isBinary ? 13:31)); - result = prime * result + ((isFile ? 13:31)); - result = prime * result + ((isBoolean ? 13:31)); - result = prime * result + ((isDate ? 13:31)); - result = prime * result + ((isDateTime ? 13:31)); - result = prime * result + ((isUuid ? 13:31)); - result = prime * result + ((isEmail ? 13:31)); - result = prime * result + ((isMapContainer ? 13:31)); - result = prime * result + ((isListContainer ? 13:31)); + result = prime * result + ((hasValidation ? 13 : 31)); + result = prime * result + ((isString ? 13 : 31)); + result = prime * result + ((isNumeric ? 13 : 31)); + result = prime * result + ((isInteger ? 13 : 31)); + result = prime * result + ((isLong ? 13 : 31)); + result = prime * result + ((isNumber ? 13 : 31)); + result = prime * result + ((isFloat ? 13 : 31)); + result = prime * result + ((isDouble ? 13 : 31)); + result = prime * result + ((isByteArray ? 13 : 31)); + result = prime * result + ((isBinary ? 13 : 31)); + result = prime * result + ((isFile ? 13 : 31)); + result = prime * result + ((isBoolean ? 13 : 31)); + result = prime * result + ((isDate ? 13 : 31)); + result = prime * result + ((isDateTime ? 13 : 31)); + result = prime * result + ((isUuid ? 13 : 31)); + result = prime * result + ((isEmail ? 13 : 31)); + result = prime * result + ((isFreeFormObject ? 13 : 31)); + result = prime * result + ((isMapContainer ? 13 : 31)); + result = prime * result + ((isListContainer ? 13 : 31)); result = prime * result + Objects.hashCode(isInherited); result = prime * result + Objects.hashCode(discriminatorValue); result = prime * result + Objects.hashCode(nameInCamelCase); @@ -483,11 +486,11 @@ public int hashCode() result = prime * result + Objects.hashCode(enumName); result = prime * result + ((maxItems == null) ? 0 : maxItems.hashCode()); result = prime * result + ((minItems == null) ? 0 : minItems.hashCode()); - result = prime * result + ((isXmlAttribute ? 13:31)); + result = prime * result + ((isXmlAttribute ? 13 : 31)); result = prime * result + ((xmlPrefix == null) ? 0 : xmlPrefix.hashCode()); result = prime * result + ((xmlName == null) ? 0 : xmlName.hashCode()); result = prime * result + ((xmlNamespace == null) ? 0 : xmlNamespace.hashCode()); - result = prime * result + ((isXmlWrapped ? 13:31)); + result = prime * result + ((isXmlWrapped ? 13 : 31)); return result; } @@ -657,6 +660,9 @@ public boolean equals(Object obj) { if (this.isEmail != other.isEmail) { return false; } + if (this.isFreeFormObject != other.isFreeFormObject) { + return false; + } if (this.isBinary != other.isBinary) { return false; } @@ -724,7 +730,7 @@ public CodegenProperty clone() { if (this.mostInnerItems != null) { cp.mostInnerItems = this.mostInnerItems; } - if(this.vendorExtensions != null){ + if (this.vendorExtensions != null) { cp.vendorExtensions = new HashMap(this.vendorExtensions); } return cp; @@ -785,11 +791,12 @@ public java.lang.String toString() { ", isDateTime=" + isDateTime + ", isUuid=" + isUuid + ", isEmail=" + isEmail + + ", isFreeFormObject=" + isFreeFormObject + ", isListContainer=" + isListContainer + ", isMapContainer=" + isMapContainer + ", isEnum=" + isEnum + ", isReadOnly=" + isReadOnly + - ", isWriteOnly=" + isWriteOnly+ + ", isWriteOnly=" + isWriteOnly + ", isNullable=" + isNullable + ", _enum=" + _enum + ", allowableValues=" + allowableValues + diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java index 808a52da87dc..e4241ee00eb9 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java @@ -27,7 +27,7 @@ public class CodegenResponse { public String dataType, baseType, containerType; public boolean hasHeaders; public boolean isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBoolean, isDate, - isDateTime, isUuid, isEmail, isModel; + isDateTime, isUuid, isEmail, isModel, isFreeFormObject; public boolean isDefault; public boolean simpleType; public boolean primitiveType; @@ -68,6 +68,7 @@ public String toString() { ", isDateTime=" + isDateTime + ", isUuid=" + isUuid + ", isEmail=" + isEmail + + ", isFreeFormObject=" + isFreeFormObject + ", isModel=" + isModel + ", isDefault=" + isDefault + ", simpleType=" + simpleType + @@ -102,6 +103,7 @@ public boolean equals(Object o) { isDateTime == that.isDateTime && isUuid == that.isUuid && isEmail == that.isEmail && + isFreeFormObject == that.isFreeFormObject && isModel == that.isModel && isDefault == that.isDefault && simpleType == that.simpleType && @@ -124,7 +126,9 @@ public boolean equals(Object o) { @Override public int hashCode() { - - return Objects.hash(headers, code, message, hasMore, examples, dataType, baseType, containerType, hasHeaders, isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBoolean, isDate, isDateTime, isUuid, isEmail, isModel, isDefault, simpleType, primitiveType, isMapContainer, isListContainer, isBinary, isFile, schema, jsonSchema, vendorExtensions); + return Objects.hash(headers, code, message, hasMore, examples, dataType, baseType, containerType, hasHeaders, + isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBoolean, isDate, + isDateTime, isUuid, isEmail, isFreeFormObject, isModel, isDefault, simpleType, primitiveType, isMapContainer, + isListContainer, isBinary, isFile, schema, jsonSchema, vendorExtensions); } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 1869fbd413c0..d671855ecc1e 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -1152,6 +1152,8 @@ public void setParameterExampleValue(CodegenParameter codegenParameter) { codegenParameter.example = "38400000-8cf0-11bd-b23e-10b96e4ef00d"; } else if (Boolean.TRUE.equals(codegenParameter.isString)) { codegenParameter.example = codegenParameter.paramName + "_example"; + } else if (Boolean.TRUE.equals(codegenParameter.isFreeFormObject)) { + codegenParameter.example = "Object"; } } @@ -1375,6 +1377,8 @@ private static String getPrimitiveType(Schema schema) { return "UUID"; } else if (ModelUtils.isStringSchema(schema)) { return "string"; + } else if (ModelUtils.isFreeFormObject(schema)) { + return "object"; } else if (schema.getProperties() != null && !schema.getProperties().isEmpty()) { // having property implies it's a model return "object"; } else if (StringUtils.isNotEmpty(schema.getType())) { @@ -1685,7 +1689,8 @@ public CodegenModel fromModel(String name, Schema schema, Map al return m; } - private CodegenDiscriminator createDiscriminator(String schemaName, Schema schema, Map allDefinitions) { + private CodegenDiscriminator createDiscriminator(String schemaName, Schema + schema, Map allDefinitions) { if (schema.getDiscriminator() == null) { return null; } @@ -1717,7 +1722,8 @@ protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Sc addParentContainer(codegenModel, codegenModel.name, schema); } - protected void addProperties(Map properties, List required, Schema schema, Map allSchemas) { + protected void addProperties(Map properties, List required, Schema + schema, Map allSchemas) { if (schema instanceof ComposedSchema) { ComposedSchema composedSchema = (ComposedSchema) schema; if (composedSchema.getAllOf() == null) { @@ -2010,6 +2016,9 @@ public CodegenProperty fromProperty(String name, Schema p) { // handle inner property CodegenProperty cp = fromProperty("inner", ModelUtils.getAdditionalProperties(p)); updatePropertyForMap(property, cp); + } else if (ModelUtils.isFreeFormObject(p)) { + property.isFreeFormObject = true; + property.baseType = getSchemaType(p); } else { // model // TODO revise the logic below //if (StringUtils.isNotBlank(p.get$ref())) { @@ -2212,7 +2221,8 @@ protected ApiResponse findMethodResponse(ApiResponses responses) { * @param schemas a map of OAS models * @return Codegen Operation object */ - public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map schemas) { + public CodegenOperation fromOperation(String path, String httpMethod, Operation + operation, Map schemas) { return fromOperation(path, httpMethod, operation, schemas, null); } @@ -2617,6 +2627,8 @@ public CodegenResponse fromResponse(OpenAPI openAPI, String responseCode, ApiRes r.isDate = true; } else if (Boolean.TRUE.equals(cp.isDateTime)) { r.isDateTime = true; + } else if (Boolean.TRUE.equals(cp.isFreeFormObject)) { + r.isFreeFormObject = true; } else { LOGGER.debug("Property type is not primitive: " + cp.dataType); } @@ -2652,7 +2664,8 @@ public CodegenResponse fromResponse(OpenAPI openAPI, String responseCode, ApiRes * @param openAPI a OAS object representing the spec * @return Codegen Response object */ - public CodegenCallback fromCallback(String name, Callback callback, Map schemas, OpenAPI openAPI) { + public CodegenCallback fromCallback(String name, Callback callback, Map schemas, OpenAPI + openAPI) { CodegenCallback c = new CodegenCallback(); c.name = name; @@ -3222,7 +3235,8 @@ private static List addHasMore(List objs) { * @param operations map of Codegen operations */ @SuppressWarnings("static-method") - public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map> operations) { + public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation + co, Map> operations) { List opList = operations.get(tag); if (opList == null) { opList = new ArrayList(); @@ -3329,7 +3343,8 @@ protected void addImport(CodegenModel m, String type) { * @param properties model properties (schemas) * @return model properties with direct reference to schemas */ - private Map unaliasPropertySchema(Map allSchemas, Map properties) { + private Map unaliasPropertySchema + (Map allSchemas, Map properties) { if (properties != null) { for (String key : properties.keySet()) { properties.put(key, ModelUtils.unaliasSchema(allSchemas, properties.get(key))); @@ -3370,7 +3385,8 @@ private void addVars(CodegenModel m, Map properties, List vars, Map properties, Set mandatory) { + private void addVars(CodegenModel + m, List vars, Map properties, Set mandatory) { // convert set to list so that we can access the next entry in the loop List> propertyList = new ArrayList>(properties.entrySet()); final int totalCount = propertyList.size(); @@ -3883,6 +3899,8 @@ public void setParameterBooleanFlagWithCodegenProperty(CodegenParameter paramete } else if (Boolean.TRUE.equals(property.isDateTime)) { parameter.isDateTime = true; parameter.isPrimitiveType = true; + } else if (Boolean.TRUE.equals(property.isFreeFormObject)) { + parameter.isFreeFormObject = true; } else { LOGGER.debug("Property type is not primitive: " + property.dataType); } @@ -3956,7 +3974,8 @@ public void updateCodegenPropertyEnum(CodegenProperty var) { } } - private void updateEnumVarsWithExtensions(List> enumVars, Map vendorExtensions) { + private void updateEnumVarsWithExtensions + (List> enumVars, Map vendorExtensions) { if (vendorExtensions != null && vendorExtensions.containsKey("x-enum-varnames")) { List alias = (List) vendorExtensions.get("x-enum-varnames"); int size = Math.min(enumVars.size(), alias.size()); @@ -4267,7 +4286,8 @@ public String getHelp() { return null; } - public List fromRequestBodyToFormParameters(RequestBody body, Map schemas, Set imports) { + public List fromRequestBodyToFormParameters(RequestBody + body, Map schemas, Set imports) { List parameters = new ArrayList(); LOGGER.debug("debugging fromRequestBodyToFormParameters= " + body); Schema schema = ModelUtils.getSchemaFromRequestBody(body); @@ -4423,7 +4443,8 @@ public CodegenParameter fromFormProperty(String name, Schema propertySchema, Set return codegenParameter; } - public CodegenParameter fromRequestBody(RequestBody body, Map schemas, Set imports, String bodyParameterName) { + public CodegenParameter fromRequestBody(RequestBody + body, Map schemas, Set imports, String bodyParameterName) { if (body == null) { LOGGER.error("body in fromRequestBody cannot be null!"); } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java index 4bd891240636..bbea5774cdf1 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java @@ -302,9 +302,13 @@ public static boolean isObjectSchema(Schema schema) { if (schema instanceof ObjectSchema) { return true; } + + // must not be a map if (SchemaTypeUtil.OBJECT_TYPE.equals(schema.getType()) && !(schema instanceof MapSchema)) { return true; } + + // must have at least one property if (schema.getType() == null && schema.getProperties() != null && !schema.getProperties().isEmpty()) { return true; } @@ -750,7 +754,8 @@ private static Schema getSchemaFromContent(Content content) { */ public static Schema unaliasSchema(Map allSchemas, Schema schema) { if (allSchemas == null || allSchemas.isEmpty()) { - LOGGER.warn("allSchemas cann't be null/empty in unaliasSchema. Returned 'schema'"); + // skip the warning as the spec can have no model defined + //LOGGER.warn("allSchemas cannot be null/empty in unaliasSchema. Returned 'schema'"); return schema; } @@ -762,6 +767,8 @@ public static Schema unaliasSchema(Map allSchemas, Schema schema } else if (ref.getEnum() != null && !ref.getEnum().isEmpty()) { // top-level enum class return schema; + } else if (isFreeFormObject(ref)) { + return schema; } else if (isArraySchema(ref) || isComposedSchema(ref)) { // array def should be created as models return schema; } else if (isMapSchema(ref)) { diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinClientCodegenModelTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinClientCodegenModelTest.java index 312a2fa32e3e..4c6894c17d48 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinClientCodegenModelTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinClientCodegenModelTest.java @@ -238,7 +238,7 @@ public void complexPropertyTest() { Assert.assertEquals(property1.name, "child"); Assert.assertEquals(property1.baseType, "Child"); Assert.assertFalse(property1.required); - Assert.assertTrue(property1.isNotContainer); + Assert.assertFalse(property1.isContainer); } @DataProvider(name = "modelNames") From 8af534cf166f103396e36ef2aed86111fb0655f8 Mon Sep 17 00:00:00 2001 From: William Cheng Date: Sat, 10 Nov 2018 12:32:34 +0800 Subject: [PATCH 3/4] add object mapping for elixir client --- .../org/openapitools/codegen/languages/ElixirClientCodegen.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElixirClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElixirClientCodegen.java index 230100673c7c..aa5bccbab4ae 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElixirClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElixirClientCodegen.java @@ -169,7 +169,7 @@ public ElixirClientCodegen() { typeMapping.put("map", "Map"); typeMapping.put("array", "List"); typeMapping.put("list", "List"); - // typeMapping.put("object", "Map"); + typeMapping.put("object", "Map"); typeMapping.put("binary", "String"); typeMapping.put("ByteArray", "String"); typeMapping.put("UUID", "String"); From eebaa03196fb64530be4663f781d16872d66aabe Mon Sep 17 00:00:00 2001 From: William Cheng Date: Thu, 22 Nov 2018 17:25:09 +0800 Subject: [PATCH 4/4] minor fix to free form object check --- .../java/org/openapitools/codegen/utils/ModelUtils.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java index bbea5774cdf1..6f495304fcc2 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/ModelUtils.java @@ -545,17 +545,19 @@ public static boolean isFreeFormObject(Schema schema) { if ("object".equals(schema.getType())) { // no properties if ((schema.getProperties() == null || schema.getProperties().isEmpty())) { - if (schema.getAdditionalProperties() == null) { return true; } else { // additionalProperties set to true - if (schema.getAdditionalProperties() instanceof Boolean && (Boolean) schema.getAdditionalProperties()) { + if (schema.getAdditionalProperties() instanceof Boolean + && (Boolean) schema.getAdditionalProperties()) { return true; } // additionalProperties is set to {} - if (schema.getAdditionalProperties() instanceof Schema && schema.getAdditionalProperties() != null) { + if (schema.getAdditionalProperties() instanceof Schema && schema.getAdditionalProperties() != null + && schema.getAdditionalProperties() instanceof ObjectSchema + && ((Schema) schema.getAdditionalProperties()).getProperties().isEmpty()) { return true; } }