Add support for multiple inheritance (#1664)

* add all parent names

* clean up supportsInheritance

* fix npe

* fix allVars, fix test cases

* add more tests, remove comments

* update docker m2 cache dir, add more tests, fix mandatory

* update samples

* regenerate js spec files

* add logic to detect self reference

* add isSelfReference flag to codegen property

* add ruby tests for cat model

* remove debugging info

* fix JS allvars not have x-js-doctype

* update samples

* update js samples
This commit is contained in:
William Cheng 2018-12-15 00:24:36 +08:00 committed by GitHub
parent 587bd56655
commit 8c599ebf12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
214 changed files with 835 additions and 454 deletions

View File

@ -171,6 +171,8 @@ public interface CodegenConfig {
void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations);
Map<String, Object> updateAllModels(Map<String, Object> objs);
Map<String, Object> postProcessAllModels(Map<String, Object> objs);
Map<String, Object> postProcessModels(Map<String, Object> objs);

View File

@ -22,11 +22,13 @@ import io.swagger.v3.oas.models.ExternalDocumentation;
import java.util.*;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.apache.commons.lang3.builder.ToStringBuilder;
@JsonIgnoreProperties({"parentModel", "interfaceModels"})
public class CodegenModel {
public String parent, parentSchema;
public List<String> interfaces;
public List<String> allParents;
// References to parent and interface CodegenModels. Only set when code generator supports inheritance.
public CodegenModel parentModel;
@ -46,18 +48,18 @@ public class CodegenModel {
public String arrayModelType;
public boolean isAlias; // Is this effectively an alias of another simple type
public boolean isString, isInteger;
public List<CodegenProperty> vars = new ArrayList<CodegenProperty>();
public List<CodegenProperty> vars = new ArrayList<CodegenProperty>(); // all properties (without parent's properties)
public List<CodegenProperty> allVars = new ArrayList<CodegenProperty>(); // all properties (with parent's properties)
public List<CodegenProperty> requiredVars = new ArrayList<CodegenProperty>(); // a list of required properties
public List<CodegenProperty> optionalVars = new ArrayList<CodegenProperty>(); // a list of optional properties
public List<CodegenProperty> readOnlyVars = new ArrayList<CodegenProperty>(); // a list of read-only properties
public List<CodegenProperty> readWriteVars = new ArrayList<CodegenProperty>(); // a list of properties for read, write
public List<CodegenProperty> allVars = new ArrayList<CodegenProperty>();
public List<CodegenProperty> parentVars = new ArrayList<CodegenProperty>();
public Map<String, Object> allowableValues;
// Sorted sets of required parameters.
public Set<String> mandatory = new TreeSet<String>();
public Set<String> allMandatory;
public Set<String> mandatory = new TreeSet<String>(); // without parent's required properties
public Set<String> allMandatory = new TreeSet<String>(); // with parent's required properties
public Set<String> imports = new TreeSet<String>();
public boolean hasVars, emptyVars, hasMoreModels, hasEnums, isEnum, hasRequired, hasOptional, isArrayModel, hasChildren, isMapModel;
@ -69,16 +71,59 @@ public class CodegenModel {
//The type of the value from additional properties. Used in map like objects.
public String additionalPropertiesType;
{
// By default these are the same collections. Where the code generator supports inheritance, composed models
// store the complete closure of owned and inherited properties in allVars and allMandatory.
allVars = vars;
allMandatory = mandatory;
}
@Override
public String toString() {
return String.format(Locale.ROOT, "%s(%s)", name, classname);
return new ToStringBuilder(this)
.append("parent", parent)
.append("parentSchema", parentSchema)
.append("interfaces", interfaces)
.append("parentModel", parentModel)
.append("interfaceModels", interfaceModels)
.append("children", children)
.append("name", name)
.append("classname", classname)
.append("title", title)
.append("description", description)
.append("classVarName", classVarName)
.append("modelJson", modelJson)
.append("dataType", dataType)
.append("xmlPrefix", xmlPrefix)
.append("xmlNamespace", xmlNamespace)
.append("xmlName", xmlName)
.append("classFilename", classFilename)
.append("unescapedDescription", unescapedDescription)
.append("discriminator", discriminator)
.append("defaultValue", defaultValue)
.append("arrayModelType", arrayModelType)
.append("isAlias", isAlias)
.append("isString", isString)
.append("isInteger", isInteger)
.append("vars", vars)
.append("requiredVars", requiredVars)
.append("optionalVars", optionalVars)
.append("readOnlyVars", readOnlyVars)
.append("readWriteVars", readWriteVars)
.append("allVars", allVars)
.append("parentVars", parentVars)
.append("allowableValues", allowableValues)
.append("mandatory", mandatory)
.append("allMandatory", allMandatory)
.append("imports", imports)
.append("hasVars", hasVars)
.append("emptyVars", emptyVars)
.append("hasMoreModels", hasMoreModels)
.append("hasEnums", hasEnums)
.append("isEnum", isEnum)
.append("hasRequired", hasRequired)
.append("hasOptional", hasOptional)
.append("isArrayModel", isArrayModel)
.append("hasChildren", hasChildren)
.append("isMapModel", isMapModel)
.append("hasOnlyReadOnly", hasOnlyReadOnly)
.append("externalDocumentation", externalDocumentation)
.append("vendorExtensions", vendorExtensions)
.append("additionalPropertiesType", additionalPropertiesType)
.toString();
}
@Override
@ -94,6 +139,8 @@ public class CodegenModel {
return false;
if (interfaces != null ? !interfaces.equals(that.interfaces) : that.interfaces != null)
return false;
if (allParents != null ? !allParents.equals(that.allParents) : that.allParents != null)
return false;
if (parentModel != null ? !parentModel.equals(that.parentModel) : that.parentModel != null)
return false;
if (interfaceModels != null ? !interfaceModels.equals(that.interfaceModels) : that.interfaceModels != null)
@ -169,6 +216,7 @@ public class CodegenModel {
int result = parent != null ? parent.hashCode() : 0;
result = 31 * result + (parentSchema != null ? parentSchema.hashCode() : 0);
result = 31 * result + (interfaces != null ? interfaces.hashCode() : 0);
result = 31 * result + (allParents != null ? allParents.hashCode() : 0);
result = 31 * result + (parentModel != null ? parentModel.hashCode() : 0);
result = 31 * result + (interfaceModels != null ? interfaceModels.hashCode() : 0);
result = 31 * result + (name != null ? name.hashCode() : 0);
@ -226,10 +274,18 @@ public class CodegenModel {
return interfaces;
}
public List<String> getAllParents() {
return allParents;
}
public void setInterfaces(List<String> interfaces) {
this.interfaces = interfaces;
}
public void setAllParents(List<String> allParents) {
this.allParents = allParents;
}
public CodegenModel getParentModel() {
return parentModel;
}

View File

@ -61,6 +61,7 @@ public class CodegenProperty implements Cloneable {
public boolean isReadOnly;
public boolean isWriteOnly;
public boolean isNullable;
public boolean isSelfReference;
public List<String> _enum;
public Map<String, Object> allowableValues;
public CodegenProperty items;
@ -439,6 +440,7 @@ public class CodegenProperty implements Cloneable {
result = prime * result + ((isReadOnly ? 13 : 31));
result = prime * result + ((isWriteOnly ? 13 : 31));
result = prime * result + ((isNullable ? 13 : 31));
result = prime * result + ((isSelfReference ? 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());
@ -597,6 +599,9 @@ public class CodegenProperty implements Cloneable {
if (this.isNullable != other.isNullable) {
return false;
}
if (this.isSelfReference != other.isSelfReference ) {
return false;
}
if (this._enum != other._enum && (this._enum == null || !this._enum.equals(other._enum))) {
return false;
}
@ -790,6 +795,7 @@ public class CodegenProperty implements Cloneable {
", isReadOnly=" + isReadOnly +
", isWriteOnly=" + isWriteOnly +
", isNullable=" + isNullable +
", isSelfReference=" + isSelfReference +
", _enum=" + _enum +
", allowableValues=" + allowableValues +
", items=" + items +

View File

@ -115,6 +115,7 @@ public class DefaultCodegen implements CodegenConfig {
protected List<CliOption> cliOptions = new ArrayList<CliOption>();
protected boolean skipOverwrite;
protected boolean removeOperationIdPrefix;
protected boolean supportsMultipleInheritance;
protected boolean supportsInheritance;
protected boolean supportsMixins;
protected Map<String, String> supportedLibraries = new LinkedHashMap<String, String>();
@ -212,53 +213,79 @@ public class DefaultCodegen implements CodegenConfig {
// override with any special post-processing for all models
@SuppressWarnings({"static-method", "unchecked"})
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
if (supportsInheritance) {
// Index all CodegenModels by model name.
Map<String, CodegenModel> allModels = new HashMap<String, CodegenModel>();
for (Entry<String, Object> entry : objs.entrySet()) {
String modelName = toModelName(entry.getKey());
Map<String, Object> inner = (Map<String, Object>) entry.getValue();
List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models");
for (Map<String, Object> mo : models) {
CodegenModel cm = (CodegenModel) mo.get("model");
allModels.put(modelName, cm);
}
return objs;
}
/**
* Loop through all models to update different flags (e.g. isSelfReference), children models, etc
*
* @param objs Map of models
* @return maps of models with various updates
*/
public Map<String, Object> updateAllModels(Map<String, Object> objs) {
// Index all CodegenModels by model name.
Map<String, CodegenModel> allModels = new HashMap<String, CodegenModel>();
for (Entry<String, Object> entry : objs.entrySet()) {
String modelName = toModelName(entry.getKey());
Map<String, Object> inner = (Map<String, Object>) entry.getValue();
List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models");
for (Map<String, Object> mo : models) {
CodegenModel cm = (CodegenModel) mo.get("model");
allModels.put(modelName, cm);
}
// Fix up all parent and interface CodegenModel references.
for (CodegenModel cm : allModels.values()) {
if (cm.getParent() != null) {
cm.setParentModel(allModels.get(cm.getParent()));
}
if (cm.getInterfaces() != null && !cm.getInterfaces().isEmpty()) {
cm.setInterfaceModels(new ArrayList<CodegenModel>(cm.getInterfaces().size()));
for (String intf : cm.getInterfaces()) {
CodegenModel intfModel = allModels.get(intf);
if (intfModel != null) {
cm.getInterfaceModels().add(intfModel);
}
}
}
}
// Fix up all parent and interface CodegenModel references.
for (CodegenModel cm : allModels.values()) {
if (cm.getParent() != null) {
cm.setParentModel(allModels.get(cm.getParent()));
}
// Let parent know about all its children
for (String name : allModels.keySet()) {
CodegenModel cm = allModels.get(name);
CodegenModel parent = allModels.get(cm.getParent());
// if a discriminator exists on the parent, don't add this child to the inheritance hierarchy
// TODO Determine what to do if the parent discriminator name == the grandparent discriminator name
while (parent != null) {
if (parent.getChildren() == null) {
parent.setChildren(new ArrayList<CodegenModel>());
}
parent.getChildren().add(cm);
parent.hasChildren = true;
if (parent.getDiscriminator() == null) {
parent = allModels.get(parent.getParent());
} else {
parent = null;
if (cm.getInterfaces() != null && !cm.getInterfaces().isEmpty()) {
cm.setInterfaceModels(new ArrayList<CodegenModel>(cm.getInterfaces().size()));
for (String intf : cm.getInterfaces()) {
CodegenModel intfModel = allModels.get(intf);
if (intfModel != null) {
cm.getInterfaceModels().add(intfModel);
}
}
}
}
// Let parent know about all its children
for (String name : allModels.keySet()) {
CodegenModel cm = allModels.get(name);
CodegenModel parent = allModels.get(cm.getParent());
// if a discriminator exists on the parent, don't add this child to the inheritance hierarchy
// TODO Determine what to do if the parent discriminator name == the grandparent discriminator name
while (parent != null) {
if (parent.getChildren() == null) {
parent.setChildren(new ArrayList<CodegenModel>());
}
parent.getChildren().add(cm);
parent.hasChildren = true;
if (parent.getDiscriminator() == null) {
parent = allModels.get(parent.getParent());
} else {
parent = null;
}
}
}
// loop through properties of each model to detect self-reference
for (Map.Entry<String, Object> entry : objs.entrySet()) {
Map<String, Object> inner = (Map<String, Object>) entry.getValue();
List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models");
for (Map<String, Object> mo : models) {
CodegenModel cm = (CodegenModel) mo.get("model");
for (CodegenProperty cp : cm.allVars) {
// detect self import
if (cp.dataType.equals(cm.classname) ||
(cp.isContainer && cp.items.dataType.equals(cm.classname))) {
cm.imports.remove(cm.classname); // remove self import
cp.isSelfReference = true;
}
}
}
}
return objs;
}
@ -1618,6 +1645,7 @@ public class DefaultCodegen implements CodegenConfig {
// parent model
final String parentName = ModelUtils.getParentName(composed, allDefinitions);
final List<String> allParents = ModelUtils.getAllParentsName(composed, allDefinitions);
final Schema parent = StringUtils.isBlank(parentName) || allDefinitions == null ? null : allDefinitions.get(parentName);
final boolean hasParent = StringUtils.isNotBlank(parentName);
@ -1666,19 +1694,16 @@ public class DefaultCodegen implements CodegenConfig {
m.interfaces.add(modelName);
addImport(m, modelName);
if (allDefinitions != null && refSchema != null) {
if (hasParent || supportsInheritance) {
if (supportsInheritance || parentName.equals(modelName)) {
// inheritance
addProperties(allProperties, allRequired, refSchema, allDefinitions);
} else {
// composition
//LOGGER.debug("Parent {} not set to model name {}", parentName, modelName);
addProperties(properties, required, refSchema, allDefinitions);
}
} else if (!supportsMixins && !supportsInheritance) {
if (allParents.contains(modelName) && supportsMultipleInheritance) {
// multiple inheritance
addProperties(allProperties, allRequired, refSchema, allDefinitions);
} else if (parentName != null && parentName.equals(modelName) && supportsInheritance) {
// single inheritance
addProperties(allProperties, allRequired, refSchema, allDefinitions);
} else {
// composition
addProperties(properties, required, refSchema, allDefinitions);
}
}
if (composed.getAnyOf() != null) {
@ -1696,13 +1721,16 @@ public class DefaultCodegen implements CodegenConfig {
if (parent != null) {
m.parentSchema = parentName;
m.parent = toModelName(parentName);
addImport(m, m.parent);
if (allDefinitions != null && !allDefinitions.isEmpty()) {
if (hasParent || supportsInheritance) {
addProperties(allProperties, allRequired, parent, allDefinitions);
} else {
addProperties(properties, required, parent, allDefinitions);
if (supportsMultipleInheritance) {
m.allParents = new ArrayList<String>();
for (String pname : allParents) {
String pModelName = toModelName(pname);
m.allParents.add(pModelName);
addImport(m, pModelName);
}
} else { // single inheritance
addImport(m, m.parent);
}
}
@ -1713,15 +1741,14 @@ public class DefaultCodegen implements CodegenConfig {
// component is the child schema
addProperties(properties, required, component, allDefinitions);
if (hasParent || supportsInheritance) {
addProperties(allProperties, allRequired, component, allDefinitions);
}
// includes child's properties (all, required) in allProperties, allRequired
addProperties(allProperties, allRequired, component, allDefinitions);
}
break; // at most one schema not using $ref
break; // at most one child only
}
}
addVars(m, unaliasPropertySchema(allDefinitions, properties), required, allProperties, allRequired);
addVars(m, unaliasPropertySchema(allDefinitions, properties), required, unaliasPropertySchema(allDefinitions, allProperties), allRequired);
// end of code block for composed schema
} else {
@ -1745,7 +1772,8 @@ public class DefaultCodegen implements CodegenConfig {
m.isString = Boolean.TRUE;
}
addVars(m, unaliasPropertySchema(allDefinitions, schema.getProperties()), schema.getRequired());
// passing null to allProperties and allRequired as there's no parent
addVars(m, unaliasPropertySchema(allDefinitions, schema.getProperties()), schema.getRequired(), null, null);
}
// remove duplicated properties
@ -1797,9 +1825,19 @@ public class DefaultCodegen implements CodegenConfig {
addParentContainer(codegenModel, codegenModel.name, schema);
}
/**
* Add schema's properties to "properties" and "required" list
*
* @param properties all properties
* @param required required property only
* @param schema schema in which the properties will be added to the lists
* @param allSchemas all schemas
*/
protected void addProperties(Map<String, Schema> properties, List<String> required, Schema
schema, Map<String, Schema> allSchemas) {
if (schema instanceof ComposedSchema) {
throw new RuntimeException("Please report the issue: Cannot process Composed Schema in addProperties: " + schema);
/*
ComposedSchema composedSchema = (ComposedSchema) schema;
if (composedSchema.getAllOf() == null) {
return;
@ -1809,8 +1847,11 @@ public class DefaultCodegen implements CodegenConfig {
addProperties(properties, required, component, allSchemas);
}
return;
*/
}
Schema unaliasSchema = ModelUtils.unaliasSchema(globalSchemas, schema);
if (StringUtils.isNotBlank(schema.get$ref())) {
Schema interfaceSchema = allSchemas.get(ModelUtils.getSimpleRef(schema.get$ref()));
addProperties(properties, required, interfaceSchema, allSchemas);
@ -3425,49 +3466,69 @@ public class DefaultCodegen implements CodegenConfig {
return properties;
}
private void addVars(CodegenModel model, Map<String, Schema> properties, List<String> required) {
addVars(model, properties, required, null, null);
}
private void addVars(CodegenModel m, Map<String, Schema> properties, List<String> required,
Map<String, Schema> allProperties, List<String> allRequired) {
m.hasRequired = false;
if (properties != null && !properties.isEmpty()) {
m.hasVars = true;
m.hasEnums = false;
m.hasEnums = false; // TODO need to fix as its false in both cases
Set<String> mandatory = required == null ? Collections.<String>emptySet()
: new TreeSet<String>(required);
// update "vars" without parent's properties (all, required)
addVars(m, m.vars, properties, mandatory);
m.allMandatory = m.mandatory = mandatory;
} else {
m.emptyVars = true;
m.hasVars = false;
m.hasEnums = false;
m.hasEnums = false; // TODO need to fix as its false in both cases
}
if (allProperties != null) {
Set<String> allMandatory = allRequired == null ? Collections.<String>emptySet()
: new TreeSet<String>(allRequired);
// update "vars" with parent's properties (all, required)
addVars(m, m.allVars, allProperties, allMandatory);
m.allMandatory = allMandatory;
} else { // without parent, allVars and vars are the same
m.allVars = m.vars;
m.allMandatory = m.mandatory;
}
// loop through list to update property name with toVarName
Set<String> renamedMandatory = new TreeSet<String>();
Iterator<String> mandatoryIterator = m.mandatory.iterator();
while (mandatoryIterator.hasNext()) {
renamedMandatory.add(toVarName(mandatoryIterator.next()));
}
m.mandatory = renamedMandatory;
Set<String> renamedAllMandatory = new TreeSet<String>();
Iterator<String> allMandatoryIterator = m.allMandatory.iterator();
while (allMandatoryIterator.hasNext()) {
renamedAllMandatory.add(toVarName(allMandatoryIterator.next()));
}
m.allMandatory = renamedAllMandatory;
}
private void addVars(CodegenModel
m, List<CodegenProperty> vars, Map<String, Schema> properties, Set<String> mandatory) {
// convert set to list so that we can access the next entry in the loop
List<Map.Entry<String, Schema>> propertyList = new ArrayList<Map.Entry<String, Schema>>(properties.entrySet());
final int totalCount = propertyList.size();
for (int i = 0; i < totalCount; i++) {
Map.Entry<String, Schema> entry = propertyList.get(i);
/**
* Add variables (properties) to codegen model (list of properties, various flags, etc)
*
* @param m Codegen model
* @param vars list of codegen properties (e.g. vars, allVars) to be updated with the new properties
* @param properties a map of properties (schema)
* @param mandatory a set of required properties' name
*/
private void addVars(CodegenModel m, List<CodegenProperty> vars, Map<String, Schema> properties, Set<String> mandatory) {
for (Map.Entry<String, Schema> entry : properties.entrySet()) {
final String key = entry.getKey();
final Schema prop = entry.getValue();
if (prop == null) {
LOGGER.warn("null property for " + key);
LOGGER.warn("Please report the issue. There shouldn't be null property for " + key);
} else {
final CodegenProperty cp = fromProperty(key, prop);
cp.required = mandatory.contains(key);
@ -3484,14 +3545,7 @@ public class DefaultCodegen implements CodegenConfig {
m.hasOnlyReadOnly = false;
}
if (i + 1 != totalCount) {
cp.hasMore = true;
// check the next entry to see if it's read only
if (!Boolean.TRUE.equals(propertyList.get(i + 1).getValue().getReadOnly())) {
cp.hasMoreNonReadOnly = true; // next entry is not ready only
}
}
// TODO revise the logic to include map
if (cp.isContainer) {
addImport(m, typeMapping.get("array"));
}
@ -3515,7 +3569,7 @@ public class DefaultCodegen implements CodegenConfig {
if (Boolean.TRUE.equals(cp.isReadOnly)) {
m.readOnlyVars.add(cp);
} else { // else add to readWriteVars (list of properties)
// FIXME: readWriteVars can contain duplicated properties. Debug/breakpoint here while running C# generator (Dog and Cat models)
// duplicated properties will be removed by removeAllDuplicatedProperty later
m.readWriteVars.add(cp);
}
}

View File

@ -458,6 +458,9 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
}
}
// loop through all models to update children models, isSelfReference, isCircularReference, etc
allProcessedModels = config.updateAllModels(allProcessedModels);
// post process all processed models
allProcessedModels = config.postProcessAllModels(allProcessedModels);

View File

@ -54,6 +54,9 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
supportsInheritance = true;
// to support multiple inheritance e.g. export interface ModelC extends ModelA, ModelB
//supportsMultipleInheritance = true;
// NOTE: TypeScript uses camel cased reserved words, while models are title cased. We don't want lowercase comparisons.
reservedWords.addAll(Arrays.asList(
// local variable names used in API methods (endpoints)

View File

@ -1046,6 +1046,16 @@ public class JavascriptClientCodegen extends DefaultCodegen implements CodegenCo
}
}
for (CodegenProperty var : cm.allVars) {
// Add JSDoc @type value for this property.
String jsDocType = getJSDocType(cm, var);
var.vendorExtensions.put("x-jsdoc-type", jsDocType);
if (Boolean.TRUE.equals(var.required)) {
required.add(var);
}
}
if (supportsInheritance || supportsMixins) {
for (CodegenProperty var : cm.allVars) {
if (Boolean.TRUE.equals(var.required)) {

View File

@ -762,5 +762,4 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig
}
}
}
}

View File

@ -68,6 +68,8 @@ public class RubyClientCodegen extends AbstractRubyCodegen {
public RubyClientCodegen() {
super();
supportsInheritance = true;
// clear import mapping (from default generator) as ruby does not use it
// at the moment
importMapping.clear();
@ -112,6 +114,7 @@ public class RubyClientCodegen extends AbstractRubyCodegen {
itr.remove();
}
}
cliOptions.add(new CliOption(GEM_NAME, "gem name (convention: underscore_case).").
defaultValue("openapi_client"));
cliOptions.add(new CliOption(MODULE_NAME, "top module name (convention: CamelCase, usually corresponding" +

View File

@ -877,6 +877,35 @@ public class ModelUtils {
return null;
}
public static List<String> getAllParentsName(ComposedSchema composedSchema, Map<String, Schema> allSchemas) {
List<Schema> interfaces = getInterfaces(composedSchema);
List<String> names = new ArrayList<String>();
if (interfaces != null && !interfaces.isEmpty()) {
for (Schema schema : interfaces) {
// get the actual schema
if (StringUtils.isNotEmpty(schema.get$ref())) {
String parentName = getSimpleRef(schema.get$ref());
Schema s = allSchemas.get(parentName);
if (s == null) {
LOGGER.error("Failed to obtain schema from {}", parentName);
names.add("UNKNOWN_PARENT_NAME");
} else if (s.getDiscriminator() != null && StringUtils.isNotEmpty(s.getDiscriminator().getPropertyName())) {
// discriminator.propertyName is used
names.add(parentName);
} else {
LOGGER.debug("Not a parent since discriminator.propertyName is not set {}", s.get$ref());
// not a parent since discriminator.propertyName is not set
}
} else {
// not a ref, doing nothing
}
}
}
return names;
}
public static boolean isNullable(Schema schema) {
if (schema == null) {
return false;

View File

@ -1,4 +1,4 @@
export interface {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{ {{>modelGenericAdditionalProperties}}
export interface {{classname}}{{#allParents}}{{#-first}} extends {{/-first}}{{{.}}}{{^-last}}, {{/-last}}{{/allParents}} { {{>modelGenericAdditionalProperties}}
{{#vars}}
{{#description}}
/**
@ -7,4 +7,4 @@ export interface {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{ {{>m
{{/description}}
{{#isReadOnly}}readonly {{/isReadOnly}}{{{name}}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}};
{{/vars}}
}{{>modelGenericEnums}}
}{{>modelGenericEnums}}

View File

@ -208,23 +208,80 @@ public class RubyClientCodegenTest {
final Schema schema = openAPI.getComponents().getSchemas().get("Pet");
CodegenModel nullablePet = codegen.fromModel("Pet", schema, openAPI.getComponents().getSchemas());
Assert.assertNotNull(nullablePet);
Assert.assertEquals(nullablePet.getVars().size(), 6);
CodegenProperty cp0 = nullablePet.getVars().get(0);
Assert.assertFalse(cp0.isNullable);
Assert.assertEquals(cp0.name, "id");
CodegenProperty cp1 = nullablePet.getVars().get(1);
Assert.assertFalse(cp1.isNullable);
Assert.assertEquals(cp1.name, "category");
CodegenProperty cp2 = nullablePet.getVars().get(2);
Assert.assertFalse(cp2.isNullable);
Assert.assertEquals(cp2.name, "name");
CodegenProperty cp3 = nullablePet.getVars().get(3);
Assert.assertFalse(cp3.isNullable);
Assert.assertEquals(cp3.name, "photo_urls");
CodegenProperty cp4 = nullablePet.getVars().get(4);
Assert.assertFalse(cp4.isNullable);
Assert.assertEquals(cp4.name, "tags");
CodegenProperty cp5 = nullablePet.getVars().get(5);
Assert.assertFalse(cp5.isNullable);
Assert.assertEquals(cp5.name, "status");
// test allVars
Assert.assertEquals(nullablePet.getAllVars().size(), 6);
cp0 = nullablePet.getVars().get(0);
Assert.assertFalse(cp0.isNullable);
Assert.assertEquals(cp0.name, "id");
cp1 = nullablePet.getVars().get(1);
Assert.assertFalse(cp1.isNullable);
Assert.assertEquals(cp1.name, "category");
cp2 = nullablePet.getVars().get(2);
Assert.assertFalse(cp2.isNullable);
Assert.assertEquals(cp2.name, "name");
cp3 = nullablePet.getVars().get(3);
Assert.assertFalse(cp3.isNullable);
Assert.assertEquals(cp3.name, "photo_urls");
cp4 = nullablePet.getVars().get(4);
Assert.assertFalse(cp4.isNullable);
Assert.assertEquals(cp4.name, "tags");
cp5 = nullablePet.getVars().get(5);
Assert.assertFalse(cp5.isNullable);
Assert.assertEquals(cp5.name, "status");
// test requiredVars
Assert.assertEquals(nullablePet.getRequiredVars().size(), 2);
cp0 = nullablePet.getRequiredVars().get(0);
Assert.assertFalse(cp0.isNullable);
Assert.assertEquals(cp0.name, "name");
cp1 = nullablePet.getRequiredVars().get(1);
Assert.assertFalse(cp1.isNullable);
Assert.assertEquals(cp1.name, "photo_urls");
// test mandatory
Set<String> mandatory = new TreeSet<String>();
mandatory.add("name");
mandatory.add("photo_urls");
Assert.assertEquals(nullablePet.getMandatory(), mandatory);
// test allMandatory
Set<String> allMandatory = new TreeSet<String>();
allMandatory.add("name");
allMandatory.add("photo_urls");
Assert.assertEquals(nullablePet.getAllMandatory(), allMandatory);
}
@Test(description = "test nullable for parameters (OAS3)")
@ -349,8 +406,8 @@ public class RubyClientCodegenTest {
}
@Test(description = "test allOf with discriminator and duplicated properties(OAS3)")
public void allOfMappingDuplicatedPropertiesTest() {
@Test(description = "test allOf with discriminator and duplicated properties(OAS3) for Child model")
public void allOfMappingDuplicatedPropertiesTestForChild() {
final OpenAPI openAPI = new OpenAPIParser().readLocation("src/test/resources/3_0/allOfMappingDuplicatedProperties.yaml", null, new ParseOptions()).getOpenAPI();
final RubyClientCodegen codegen = new RubyClientCodegen();
codegen.setModuleName("OnlinePetstore");
@ -358,25 +415,108 @@ public class RubyClientCodegenTest {
final Schema schema = openAPI.getComponents().getSchemas().get("Child");
CodegenModel child = codegen.fromModel("Child", schema, openAPI.getComponents().getSchemas());
Assert.assertNotNull(child);
Assert.assertEquals(child.getVars().size(), 6);
CodegenProperty cp0 = child.getVars().get(0);
// to test allVars (without parent's properties)
Assert.assertEquals(child.getAllVars().size(), 7);
CodegenProperty cp0 = child.getAllVars().get(0);
Assert.assertEquals(cp0.name, "_type");
CodegenProperty cp1 = child.getAllVars().get(1);
Assert.assertEquals(cp1.name, "last_name");
CodegenProperty cp2 = child.getAllVars().get(2);
Assert.assertEquals(cp2.name, "first_name");
CodegenProperty cp3 = child.getAllVars().get(3);
Assert.assertEquals(cp3.name, "duplicated_optional");
CodegenProperty cp4 = child.getAllVars().get(4);
Assert.assertEquals(cp4.name, "duplicated_required");
CodegenProperty cp5 = child.getAllVars().get(5);
Assert.assertEquals(cp5.name, "person_required");
CodegenProperty cp6 = child.getAllVars().get(6);
Assert.assertEquals(cp6.name, "age");
// to test vars (without parent's properties)
Assert.assertEquals(child.getVars().size(), 2);
cp0 = child.getVars().get(0);
Assert.assertEquals(cp0.name, "age");
CodegenProperty cp1 = child.getVars().get(1);
cp1 = child.getVars().get(1);
Assert.assertEquals(cp1.name, "first_name");
CodegenProperty cp2 = child.getVars().get(2);
Assert.assertEquals(cp2.name, "_type");
// to test requiredVars
Assert.assertEquals(child.getRequiredVars().size(), 2);
CodegenProperty cp3 = child.getVars().get(3);
Assert.assertEquals(cp3.name, "last_name");
cp0 = child.getRequiredVars().get(0);
Assert.assertEquals(cp0.name, "duplicated_required");
CodegenProperty cp4 = child.getVars().get(4);
Assert.assertEquals(cp4.name, "duplicated_optional");
cp1 = child.getRequiredVars().get(1);
Assert.assertEquals(cp1.name, "person_required");
CodegenProperty cp5 = child.getVars().get(5);
Assert.assertEquals(cp5.name, "duplicated_required");
}
@Test(description = "test allOf with discriminator and duplicated properties(OAS3) for Adult model")
public void allOfMappingDuplicatedPropertiesTestForAdult() {
final OpenAPI openAPI = new OpenAPIParser().readLocation("src/test/resources/3_0/allOfMappingDuplicatedProperties.yaml", null, new ParseOptions()).getOpenAPI();
final RubyClientCodegen codegen = new RubyClientCodegen();
codegen.setModuleName("OnlinePetstore");
final Schema schema = openAPI.getComponents().getSchemas().get("Adult");
CodegenModel adult = codegen.fromModel("Adult", schema, openAPI.getComponents().getSchemas());
Assert.assertNotNull(adult);
// to test allVars (without parent's properties)
Assert.assertEquals(adult.getAllVars().size(), 8);
CodegenProperty cp0 = adult.getAllVars().get(0);
Assert.assertEquals(cp0.name, "_type");
CodegenProperty cp1 = adult.getAllVars().get(1);
Assert.assertEquals(cp1.name, "last_name");
CodegenProperty cp2 = adult.getAllVars().get(2);
Assert.assertEquals(cp2.name, "first_name");
CodegenProperty cp3 = adult.getAllVars().get(3);
Assert.assertEquals(cp3.name, "duplicated_optional");
CodegenProperty cp4 = adult.getAllVars().get(4);
Assert.assertEquals(cp4.name, "duplicated_required");
CodegenProperty cp5 = adult.getAllVars().get(5);
Assert.assertEquals(cp5.name, "person_required");
CodegenProperty cp6 = adult.getAllVars().get(6);
Assert.assertEquals(cp6.name, "children");
CodegenProperty cp7 = adult.getAllVars().get(7);
Assert.assertEquals(cp7.name, "adult_required");
// to test vars (without parent's properties)
Assert.assertEquals(adult.getVars().size(), 4);
cp0 = adult.getVars().get(0);
Assert.assertEquals(cp0.name, "duplicated_optional");
cp1 = adult.getVars().get(1);
Assert.assertEquals(cp1.name, "duplicated_required");
cp2 = adult.getVars().get(2);
Assert.assertEquals(cp2.name, "children");
// to test requiredVars
Assert.assertEquals(adult.getRequiredVars().size(), 2);
cp0 = adult.getRequiredVars().get(0);
Assert.assertEquals(cp0.name, "duplicated_required");
cp1 = adult.getRequiredVars().get(1);
Assert.assertEquals(cp1.name, "person_required");
}
@Test(description = "test example string imported from x-example parameterr (OAS2)")
@ -410,9 +550,9 @@ public class RubyClientCodegenTest {
/**
* We want to make sure that all Regex patterns:
* - Start with / so Ruby know this is a regex pattern
* - Have a second / that may be added to end if only 1 exists at start
* - If there are 2 / in pattern then don't add any more
* - Start with / so Ruby know this is a regex pattern
* - Have a second / that may be added to end if only 1 exists at start
* - If there are 2 / in pattern then don't add any more
*/
@Test(description = "test regex patterns")
public void exampleRegexParameterValidationOAS3Test() {

View File

@ -29,6 +29,7 @@ components:
Person:
required:
- duplicated_required
- person_required
type: object
discriminator:
propertyName: $_type
@ -46,6 +47,9 @@ components:
type: string
duplicated_required:
type: string
person_required:
type: string
format: date-time
Adult:
description: A representation of an adult
allOf:
@ -53,6 +57,7 @@ components:
- type: object
required:
- duplicated_required
- child_required
properties:
duplicated_optional:
type: integer
@ -62,6 +67,8 @@ components:
type: array
items:
$ref: "#/components/schemas/Child"
adult_required:
type: boolean
Child:
description: A representation of a child
allOf:

View File

@ -0,0 +1,94 @@
openapi: 3.0.1
info:
version: 1.0.0
title: Example
license:
name: MIT
servers:
- url: http://api.example.xyz/v1
paths:
/person/display/{personId}:
get:
parameters:
- name: personId
in: path
required: true
description: The id of the person to retrieve
schema:
type: string
operationId: list
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/Person"
components:
schemas:
Person:
required:
- duplicated_required
- person_required
type: object
discriminator:
propertyName: $_type
mapping:
a: '#/components/schemas/Adult'
c: '#/components/schemas/Child'
properties:
$_type:
type: string
lastName:
type: string
firstName:
type: string
duplicated_optional:
type: string
duplicated_required:
type: string
person_required:
type: string
format: date-time
Human:
required:
- body
type: object
discriminator:
propertyName: $_type
properties:
$_type:
type: string
body:
type: string
Adult:
description: A representation of an adult
allOf:
- $ref: '#/components/schemas/Person'
- $ref: '#/components/schemas/Human'
- type: object
required:
- duplicated_required
- child_required
properties:
duplicated_optional:
type: integer
duplicated_required:
type: integer
children:
type: array
items:
$ref: "#/components/schemas/Child"
adult_required:
type: boolean
Child:
description: A representation of a child
allOf:
- type: object
properties:
age:
type: integer
format: int32
firstName:
type: string
- $ref: '#/components/schemas/Person'

View File

@ -13,6 +13,6 @@ docker run --rm -it \
-e MAVEN_CONFIG=/var/maven/.m2 \
-u "$(id -u):$(id -g)" \
-v "${PWD}:/gen" \
-v "${maven_cache_repo}:/var/maven/.m2/repository" \
-v "$HOME/.m2":/root/.m2 \
--entrypoint /gen/docker-entrypoint.sh \
maven:3-jdk-8 "$@"

View File

@ -3,9 +3,9 @@
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**Declawed** | **bool** | | [optional]
**ClassName** | **string** | |
**Color** | **string** | | [optional] [default to red]
**Declawed** | **bool** | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@ -3,9 +3,9 @@
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**Breed** | **string** | | [optional]
**ClassName** | **string** | |
**Color** | **string** | | [optional] [default to red]
**Breed** | **string** | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@ -10,7 +10,7 @@
package petstore
type Cat struct {
Declawed bool `json:"declawed,omitempty"`
ClassName string `json:"className"`
Color string `json:"color,omitempty"`
Declawed bool `json:"declawed,omitempty"`
}

View File

@ -10,7 +10,7 @@
package petstore
type Dog struct {
Breed string `json:"breed,omitempty"`
ClassName string `json:"className"`
Color string `json:"color,omitempty"`
Breed string `json:"breed,omitempty"`
}

View File

@ -457,26 +457,26 @@ mkCapitalization =
-- ** Cat
-- | Cat
data Cat = Cat
{ catDeclawed :: !(Maybe Bool) -- ^ "declawed"
, catClassName :: !(Text) -- ^ /Required/ "className"
{ catClassName :: !(Text) -- ^ /Required/ "className"
, catColor :: !(Maybe Text) -- ^ "color"
, catDeclawed :: !(Maybe Bool) -- ^ "declawed"
} deriving (P.Show, P.Eq, P.Typeable)
-- | FromJSON Cat
instance A.FromJSON Cat where
parseJSON = A.withObject "Cat" $ \o ->
Cat
<$> (o .:? "declawed")
<*> (o .: "className")
<$> (o .: "className")
<*> (o .:? "color")
<*> (o .:? "declawed")
-- | ToJSON Cat
instance A.ToJSON Cat where
toJSON Cat {..} =
_omitNulls
[ "declawed" .= catDeclawed
, "className" .= catClassName
[ "className" .= catClassName
, "color" .= catColor
, "declawed" .= catDeclawed
]
@ -486,9 +486,9 @@ mkCat
-> Cat
mkCat catClassName =
Cat
{ catDeclawed = Nothing
, catClassName
{ catClassName
, catColor = Nothing
, catDeclawed = Nothing
}
-- ** Category
@ -584,26 +584,26 @@ mkClient =
-- ** Dog
-- | Dog
data Dog = Dog
{ dogBreed :: !(Maybe Text) -- ^ "breed"
, dogClassName :: !(Text) -- ^ /Required/ "className"
{ dogClassName :: !(Text) -- ^ /Required/ "className"
, dogColor :: !(Maybe Text) -- ^ "color"
, dogBreed :: !(Maybe Text) -- ^ "breed"
} deriving (P.Show, P.Eq, P.Typeable)
-- | FromJSON Dog
instance A.FromJSON Dog where
parseJSON = A.withObject "Dog" $ \o ->
Dog
<$> (o .:? "breed")
<*> (o .: "className")
<$> (o .: "className")
<*> (o .:? "color")
<*> (o .:? "breed")
-- | ToJSON Dog
instance A.ToJSON Dog where
toJSON Dog {..} =
_omitNulls
[ "breed" .= dogBreed
, "className" .= dogClassName
[ "className" .= dogClassName
, "color" .= dogColor
, "breed" .= dogBreed
]
@ -613,9 +613,9 @@ mkDog
-> Dog
mkDog dogClassName =
Dog
{ dogBreed = Nothing
, dogClassName
{ dogClassName
, dogColor = Nothing
, dogBreed = Nothing
}
-- ** EnumArrays

View File

@ -156,11 +156,6 @@ capitalizationAttNameL f Capitalization{..} = (\capitalizationAttName -> Capital
-- * Cat
-- | 'catDeclawed' Lens
catDeclawedL :: Lens_' Cat (Maybe Bool)
catDeclawedL f Cat{..} = (\catDeclawed -> Cat { catDeclawed, ..} ) <$> f catDeclawed
{-# INLINE catDeclawedL #-}
-- | 'catClassName' Lens
catClassNameL :: Lens_' Cat (Text)
catClassNameL f Cat{..} = (\catClassName -> Cat { catClassName, ..} ) <$> f catClassName
@ -171,6 +166,11 @@ catColorL :: Lens_' Cat (Maybe Text)
catColorL f Cat{..} = (\catColor -> Cat { catColor, ..} ) <$> f catColor
{-# INLINE catColorL #-}
-- | 'catDeclawed' Lens
catDeclawedL :: Lens_' Cat (Maybe Bool)
catDeclawedL f Cat{..} = (\catDeclawed -> Cat { catDeclawed, ..} ) <$> f catDeclawed
{-# INLINE catDeclawedL #-}
-- * Category
@ -207,11 +207,6 @@ clientClientL f Client{..} = (\clientClient -> Client { clientClient, ..} ) <$>
-- * Dog
-- | 'dogBreed' Lens
dogBreedL :: Lens_' Dog (Maybe Text)
dogBreedL f Dog{..} = (\dogBreed -> Dog { dogBreed, ..} ) <$> f dogBreed
{-# INLINE dogBreedL #-}
-- | 'dogClassName' Lens
dogClassNameL :: Lens_' Dog (Text)
dogClassNameL f Dog{..} = (\dogClassName -> Dog { dogClassName, ..} ) <$> f dogClassName
@ -222,6 +217,11 @@ dogColorL :: Lens_' Dog (Maybe Text)
dogColorL f Dog{..} = (\dogColor -> Dog { dogColor, ..} ) <$> f dogColor
{-# INLINE dogColorL #-}
-- | 'dogBreed' Lens
dogBreedL :: Lens_' Dog (Maybe Text)
dogBreedL f Dog{..} = (\dogBreed -> Dog { dogBreed, ..} ) <$> f dogBreed
{-# INLINE dogBreedL #-}
-- * EnumArrays

View File

@ -138,9 +138,9 @@ instance Arbitrary Capitalization where
instance Arbitrary Cat where
arbitrary =
Cat
<$> arbitrary -- catDeclawed :: Maybe Bool
<*> arbitrary -- catClassName :: Text
<$> arbitrary -- catClassName :: Text
<*> arbitrary -- catColor :: Maybe Text
<*> arbitrary -- catDeclawed :: Maybe Bool
instance Arbitrary Category where
arbitrary =
@ -161,9 +161,9 @@ instance Arbitrary Client where
instance Arbitrary Dog where
arbitrary =
Dog
<$> arbitrary -- dogBreed :: Maybe Text
<*> arbitrary -- dogClassName :: Text
<$> arbitrary -- dogClassName :: Text
<*> arbitrary -- dogColor :: Maybe Text
<*> arbitrary -- dogBreed :: Maybe Text
instance Arbitrary EnumArrays where
arbitrary =

View File

@ -1 +1 @@
3.3.4-SNAPSHOT
4.0.0-SNAPSHOT

View File

@ -13,10 +13,6 @@ Name | Type | Description | Notes
## Enum: {String: String}
* `UPPER` (value: `"UPPER"`)
* `lower` (value: `"lower"`)

View File

@ -25,7 +25,7 @@ class Cat {
* @alias module:model/Cat
* @extends module:model/Animal
* @implements module:model/Animal
* @param className {}
* @param className {String}
*/
constructor(className) {
Animal.initialize(this, className);

View File

@ -25,7 +25,7 @@ class Dog {
* @alias module:model/Dog
* @extends module:model/Animal
* @implements module:model/Animal
* @param className {}
* @param className {String}
*/
constructor(className) {
Animal.initialize(this, className);

View File

@ -1 +1 @@
3.3.4-SNAPSHOT
4.0.0-SNAPSHOT

View File

@ -13,10 +13,6 @@ Name | Type | Description | Notes
## Enum: {String: String}
* `UPPER` (value: `"UPPER"`)
* `lower` (value: `"lower"`)

View File

@ -25,7 +25,7 @@ class Cat {
* @alias module:model/Cat
* @extends module:model/Animal
* @implements module:model/Animal
* @param className {}
* @param className {String}
*/
constructor(className) {
Animal.initialize(this, className);

View File

@ -25,7 +25,7 @@ class Dog {
* @alias module:model/Dog
* @extends module:model/Animal
* @implements module:model/Animal
* @param className {}
* @param className {String}
*/
constructor(className) {
Animal.initialize(this, className);

View File

@ -1 +1 @@
3.3.4-SNAPSHOT
4.0.0-SNAPSHOT

View File

@ -13,10 +13,6 @@ Name | Type | Description | Notes
## Enum: {String: String}
* `UPPER` (value: `"UPPER"`)
* `lower` (value: `"lower"`)

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*
@ -44,7 +44,7 @@
* @class
* @extends module:model/Animal
* @implements module:model/Animal
* @param className {}
* @param className {String}
*/
var exports = function(className) {
var _this = this;

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*
@ -44,7 +44,7 @@
* @class
* @extends module:model/Animal
* @implements module:model/Animal
* @param className {}
* @param className {String}
*/
var exports = function(className) {
var _this = this;

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -1 +1 @@
3.3.4-SNAPSHOT
4.0.0-SNAPSHOT

View File

@ -13,10 +13,6 @@ Name | Type | Description | Notes
## Enum: {String: String}
* `UPPER` (value: `"UPPER"`)
* `lower` (value: `"lower"`)

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*
@ -44,7 +44,7 @@
* @class
* @extends module:model/Animal
* @implements module:model/Animal
* @param className {}
* @param className {String}
*/
var exports = function(className) {
var _this = this;

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*
@ -44,7 +44,7 @@
* @class
* @extends module:model/Animal
* @implements module:model/Animal
* @param className {}
* @param className {String}
*/
var exports = function(className) {
var _this = this;

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

View File

@ -7,7 +7,7 @@
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
*
* OpenAPI Generator version: 3.3.4-SNAPSHOT
* OpenAPI Generator version: 4.0.0-SNAPSHOT
*
* Do not edit the class manually.
*

Some files were not shown because too many files have changed in this diff Show More