forked from loafle/openapi-generator-original
Merge pull request #1051 from who/develop_2.0
[Java] Fixing subClassed types so that they can use enums
This commit is contained in:
commit
a610fb5ac3
@ -34,4 +34,108 @@ public class CodegenProperty {
|
|||||||
public boolean isEnum;
|
public boolean isEnum;
|
||||||
public List<String> _enum;
|
public List<String> _enum;
|
||||||
public Map<String, Object> allowableValues;
|
public Map<String, Object> allowableValues;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final CodegenProperty other = (CodegenProperty) obj;
|
||||||
|
if ((this.baseName == null) ? (other.baseName != null) : !this.baseName.equals(other.baseName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((this.complexType == null) ? (other.complexType != null) : !this.complexType.equals(other.complexType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((this.getter == null) ? (other.getter != null) : !this.getter.equals(other.getter)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((this.setter == null) ? (other.setter != null) : !this.setter.equals(other.setter)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((this.datatype == null) ? (other.datatype != null) : !this.datatype.equals(other.datatype)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((this.datatypeWithEnum == null) ? (other.datatypeWithEnum != null) : !this.datatypeWithEnum.equals(other.datatypeWithEnum)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((this.min == null) ? (other.min != null) : !this.min.equals(other.min)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((this.max == null) ? (other.max != null) : !this.max.equals(other.max)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((this.defaultValue == null) ? (other.defaultValue != null) : !this.defaultValue.equals(other.defaultValue)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((this.baseType == null) ? (other.baseType != null) : !this.baseType.equals(other.baseType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((this.containerType == null) ? (other.containerType != null) : !this.containerType.equals(other.containerType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.maxLength != other.maxLength && (this.maxLength == null || !this.maxLength.equals(other.maxLength))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.minLength != other.minLength && (this.minLength == null || !this.minLength.equals(other.minLength))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((this.pattern == null) ? (other.pattern != null) : !this.pattern.equals(other.pattern)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((this.example == null) ? (other.example != null) : !this.example.equals(other.example)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((this.jsonSchema == null) ? (other.jsonSchema != null) : !this.jsonSchema.equals(other.jsonSchema)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.minimum != other.minimum && (this.minimum == null || !this.minimum.equals(other.minimum))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.maximum != other.maximum && (this.maximum == null || !this.maximum.equals(other.maximum))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.exclusiveMinimum != other.exclusiveMinimum && (this.exclusiveMinimum == null || !this.exclusiveMinimum.equals(other.exclusiveMinimum))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.exclusiveMaximum != other.exclusiveMaximum && (this.exclusiveMaximum == null || !this.exclusiveMaximum.equals(other.exclusiveMaximum))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.required != other.required && (this.required == null || !this.required.equals(other.required))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.secondaryParam != other.secondaryParam && (this.secondaryParam == null || !this.secondaryParam.equals(other.secondaryParam))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.isPrimitiveType != other.isPrimitiveType && (this.isPrimitiveType == null || !this.isPrimitiveType.equals(other.isPrimitiveType))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.isContainer != other.isContainer && (this.isContainer == null || !this.isContainer.equals(other.isContainer))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.isNotContainer != other.isNotContainer && (this.isNotContainer == null || !this.isNotContainer.equals(other.isNotContainer))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.isEnum != other.isEnum) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this._enum != other._enum && (this._enum == null || !this._enum.equals(other._enum))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.allowableValues != other.allowableValues && (this.allowableValues == null || !this.allowableValues.equals(other.allowableValues))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,30 @@
|
|||||||
package io.swagger.codegen.languages;
|
package io.swagger.codegen.languages;
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
import io.swagger.codegen.CliOption;
|
import io.swagger.codegen.CliOption;
|
||||||
import io.swagger.codegen.CodegenConfig;
|
import io.swagger.codegen.CodegenConfig;
|
||||||
|
import io.swagger.codegen.CodegenModel;
|
||||||
|
import io.swagger.codegen.CodegenProperty;
|
||||||
import io.swagger.codegen.CodegenType;
|
import io.swagger.codegen.CodegenType;
|
||||||
import io.swagger.codegen.DefaultCodegen;
|
import io.swagger.codegen.DefaultCodegen;
|
||||||
import io.swagger.codegen.SupportingFile;
|
import io.swagger.codegen.SupportingFile;
|
||||||
|
import io.swagger.models.ComposedModel;
|
||||||
|
import io.swagger.models.Model;
|
||||||
|
import io.swagger.models.ModelImpl;
|
||||||
|
import io.swagger.models.RefModel;
|
||||||
import io.swagger.models.properties.ArrayProperty;
|
import io.swagger.models.properties.ArrayProperty;
|
||||||
import io.swagger.models.properties.MapProperty;
|
import io.swagger.models.properties.MapProperty;
|
||||||
import io.swagger.models.properties.Property;
|
import io.swagger.models.properties.Property;
|
||||||
|
import io.swagger.models.properties.StringProperty;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
@ -255,6 +268,57 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
|
|||||||
return camelize(operationId, true);
|
return camelize(operationId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CodegenModel fromModel(String name, Model model, Map<String, Model> allDefinitions) {
|
||||||
|
CodegenModel codegenModel = super.fromModel(name, model, allDefinitions);
|
||||||
|
|
||||||
|
if (allDefinitions != null && codegenModel != null && codegenModel.parent != null && codegenModel.hasEnums) {
|
||||||
|
final Model parentModel = allDefinitions.get(toModelName(codegenModel.parent));
|
||||||
|
final CodegenModel parentCodegenModel = super.fromModel(codegenModel.parent, parentModel);
|
||||||
|
codegenModel = this.reconcileInlineEnums(codegenModel, parentCodegenModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
return codegenModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CodegenModel reconcileInlineEnums(CodegenModel codegenModel, CodegenModel parentCodegenModel) {
|
||||||
|
// This generator uses inline classes to define enums, which breaks when
|
||||||
|
// dealing with models that have subTypes. To clean this up, we will analyze
|
||||||
|
// the parent and child models, look for enums that match, and remove
|
||||||
|
// them from the child models and leave them in the parent.
|
||||||
|
// Because the child models extend the parents, the enums will be available via the parent.
|
||||||
|
|
||||||
|
// Only bother with reconciliation if the parent model has enums.
|
||||||
|
if (parentCodegenModel.hasEnums) {
|
||||||
|
|
||||||
|
// Get the properties for the parent and child models
|
||||||
|
final List<CodegenProperty> parentModelCodegenProperties = parentCodegenModel.vars;
|
||||||
|
List<CodegenProperty> codegenProperties = codegenModel.vars;
|
||||||
|
|
||||||
|
// Iterate over all of the parent model properties
|
||||||
|
for (CodegenProperty parentModelCodegenPropery : parentModelCodegenProperties) {
|
||||||
|
// Look for enums
|
||||||
|
if (parentModelCodegenPropery.isEnum) {
|
||||||
|
// Now that we have found an enum in the parent class,
|
||||||
|
// and search the child class for the same enum.
|
||||||
|
Iterator<CodegenProperty> iterator = codegenProperties.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
CodegenProperty codegenProperty = iterator.next();
|
||||||
|
if (codegenProperty.isEnum && codegenProperty.equals(parentModelCodegenPropery)) {
|
||||||
|
// We found an enum in the child class that is
|
||||||
|
// a duplicate of the one in the parent, so remove it.
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
codegenModel.vars = codegenProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
return codegenModel;
|
||||||
|
}
|
||||||
|
|
||||||
public void setInvokerPackage(String invokerPackage) {
|
public void setInvokerPackage(String invokerPackage) {
|
||||||
this.invokerPackage = invokerPackage;
|
this.invokerPackage = invokerPackage;
|
||||||
}
|
}
|
||||||
|
@ -31,4 +31,55 @@ class JavaModelEnumTest extends FlatSpec with Matchers {
|
|||||||
enumVar.baseType should be("String")
|
enumVar.baseType should be("String")
|
||||||
enumVar.isEnum should equal(true)
|
enumVar.isEnum should equal(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it should "not override identical parent enums" in {
|
||||||
|
|
||||||
|
val identicalEnumProperty = new StringProperty()
|
||||||
|
identicalEnumProperty.setEnum(List("VALUE1", "VALUE2", "VALUE3").asJava)
|
||||||
|
|
||||||
|
val subEnumProperty = new StringProperty()
|
||||||
|
subEnumProperty.setEnum(List("SUB1", "SUB2", "SUB3").asJava)
|
||||||
|
|
||||||
|
// Add one enum ptoperty to the parent
|
||||||
|
val parentProperties = new java.util.HashMap[String, Property]()
|
||||||
|
parentProperties.put("sharedThing", identicalEnumProperty)
|
||||||
|
|
||||||
|
// Add TWO enums to the subType model; one of which is identical to the one in parent class
|
||||||
|
val subProperties = new java.util.HashMap[String, Property]()
|
||||||
|
subProperties.put("sharedThing", identicalEnumProperty)
|
||||||
|
subProperties.put("unsharedThing", identicalEnumProperty)
|
||||||
|
|
||||||
|
val parentModel = new ModelImpl();
|
||||||
|
parentModel.setProperties(parentProperties);
|
||||||
|
parentModel.name("parentModel");
|
||||||
|
|
||||||
|
val subModel = new ModelImpl();
|
||||||
|
subModel.setProperties(subProperties);
|
||||||
|
subModel.name("subModel");
|
||||||
|
|
||||||
|
val model = new ComposedModel()
|
||||||
|
.parent(new RefModel(parentModel.getName()))
|
||||||
|
.child(subModel)
|
||||||
|
.interfaces(new java.util.ArrayList[RefModel]())
|
||||||
|
|
||||||
|
val codegen = new JavaClientCodegen()
|
||||||
|
val allModels = new java.util.HashMap[String, Model]()
|
||||||
|
allModels.put(codegen.toModelName(parentModel.getName()), parentModel)
|
||||||
|
allModels.put(codegen.toModelName(subModel.getName()), subModel)
|
||||||
|
|
||||||
|
val cm = codegen.fromModel("sample", model, allModels)
|
||||||
|
|
||||||
|
cm.name should be("sample")
|
||||||
|
cm.classname should be("Sample")
|
||||||
|
cm.parent should be("ParentModel")
|
||||||
|
cm.imports.asScala should be(Set("ParentModel"))
|
||||||
|
|
||||||
|
// Assert that only the unshared/uninherited enum remains
|
||||||
|
cm.vars.size should be (1)
|
||||||
|
val enumVar = cm.vars.get(0)
|
||||||
|
enumVar.baseName should be("unsharedThing")
|
||||||
|
enumVar.datatype should be("String")
|
||||||
|
enumVar.datatypeWithEnum should be("UnsharedThingEnum")
|
||||||
|
enumVar.isEnum should equal(true)
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user