[java][client] oneOf support for jackson clients (#5120)

This commit is contained in:
Slavek Kabrda
2020-01-27 14:23:20 +01:00
committed by Jim Schubert
parent 04af5e0445
commit a42ff37a42
69 changed files with 521 additions and 22 deletions

View File

@@ -10,6 +10,8 @@ import java.util.Set;
public class CodegenDiscriminator {
private String propertyName;
private String propertyBaseName;
private String propertyGetter;
private String propertyType;
private Map<String, String> mapping;
private Set<MappedModel> mappedModels = new LinkedHashSet<>();
@@ -21,6 +23,14 @@ public class CodegenDiscriminator {
this.propertyName = propertyName;
}
public String getPropertyGetter() {
return propertyGetter;
}
public void setPropertyGetter(String propertyGetter) {
this.propertyGetter = propertyGetter;
}
public String getPropertyBaseName() {
return propertyBaseName;
}
@@ -29,6 +39,14 @@ public class CodegenDiscriminator {
this.propertyBaseName = propertyBaseName;
}
public String getPropertyType() {
return propertyType;
}
public void setPropertyType(String propertyType) {
this.propertyType = propertyType;
}
public Map<String, String> getMapping() {
return mapping;
}

View File

@@ -1663,6 +1663,10 @@ public class DefaultCodegen implements CodegenConfig {
*/
@SuppressWarnings("static-method")
public String toOneOfName(List<String> names, ComposedSchema composedSchema) {
Map<String, Object> exts = composedSchema.getExtensions();
if (exts != null && exts.containsKey("x-oneOf-name")) {
return (String) exts.get("x-oneOf-name");
}
return "oneOf<" + String.join(",", names) + ">";
}
@@ -2126,13 +2130,16 @@ public class DefaultCodegen implements CodegenConfig {
return m;
}
private CodegenDiscriminator createDiscriminator(String schemaName, Schema schema) {
protected CodegenDiscriminator createDiscriminator(String schemaName, Schema schema) {
if (schema.getDiscriminator() == null) {
return null;
}
CodegenDiscriminator discriminator = new CodegenDiscriminator();
discriminator.setPropertyName(toVarName(schema.getDiscriminator().getPropertyName()));
discriminator.setPropertyBaseName(schema.getDiscriminator().getPropertyName());
discriminator.setPropertyGetter(toGetter(discriminator.getPropertyName()));
// FIXME: for now, we assume that the discriminator property is String
discriminator.setPropertyType(typeMapping.get("string"));
discriminator.setMapping(schema.getDiscriminator().getMapping());
if (schema.getDiscriminator().getMapping() != null && !schema.getDiscriminator().getMapping().isEmpty()) {
for (Entry<String, String> e : schema.getDiscriminator().getMapping().entrySet()) {

View File

@@ -25,12 +25,19 @@ import org.openapitools.codegen.languages.features.GzipFeatures;
import org.openapitools.codegen.languages.features.PerformBeanValidationFeatures;
import org.openapitools.codegen.meta.features.DocumentationFeature;
import org.openapitools.codegen.templating.mustache.CaseFormatLambda;
import org.openapitools.codegen.utils.ModelUtils;
import org.openapitools.codegen.utils.ProcessUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.responses.ApiResponse;
import java.io.File;
import java.util.*;
@@ -103,6 +110,9 @@ public class JavaClientCodegen extends AbstractJavaCodegen
protected String authFolder;
protected String serializationLibrary = null;
protected boolean useOneOfInterfaces = false;
protected List<CodegenModel> addOneOfInterfaces = new ArrayList<CodegenModel>();
public JavaClientCodegen() {
super();
@@ -488,6 +498,10 @@ public class JavaClientCodegen extends AbstractJavaCodegen
additionalProperties.remove(SERIALIZATION_LIBRARY_GSON);
}
if (additionalProperties.containsKey(SERIALIZATION_LIBRARY_JACKSON)) {
useOneOfInterfaces = true;
}
}
private boolean usesAnyRetrofitLibrary() {
@@ -712,9 +726,10 @@ public class JavaClientCodegen extends AbstractJavaCodegen
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
objs = super.postProcessModels(objs);
List<Object> models = (List<Object>) objs.get("models");
if (additionalProperties.containsKey(SERIALIZATION_LIBRARY_JACKSON) && !JERSEY1.equals(getLibrary())) {
List<Map<String, String>> imports = (List<Map<String, String>>) objs.get("imports");
List<Object> models = (List<Object>) objs.get("models");
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
@@ -741,6 +756,20 @@ public class JavaClientCodegen extends AbstractJavaCodegen
}
}
// add implements for serializable/parcelable to all models
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
cm.getVendorExtensions().putIfAbsent("implements", new ArrayList<String>());
List<String> impl = (List<String>) cm.getVendorExtensions().get("implements");
if (this.parcelableModel) {
impl.add("Parcelable");
}
if (this.serializableModel) {
impl.add("Serializable");
}
}
return objs;
}
@@ -816,6 +845,250 @@ public class JavaClientCodegen extends AbstractJavaCodegen
}
}
public void addOneOfNameExtension(Schema s, String name) {
ComposedSchema cs = (ComposedSchema) s;
if (cs.getOneOf() != null && cs.getOneOf().size() > 0) {
cs.addExtension("x-oneOf-name", name);
}
}
public void addOneOfInterfaceModel(ComposedSchema cs, String type) {
CodegenModel cm = new CodegenModel();
for (Schema o : cs.getOneOf()) {
// TODO: inline objects
cm.oneOf.add(toModelName(ModelUtils.getSimpleRef(o.get$ref())));
}
cm.name = type;
cm.classname = type;
cm.vendorExtensions.put("isOneOfInterface", true);
cm.discriminator = createDiscriminator("", (Schema) cs);
cm.interfaceModels = new ArrayList<CodegenModel>();
addOneOfInterfaces.add(cm);
}
@Override
public void preprocessOpenAPI(OpenAPI openAPI) {
// we process the openapi schema here to find oneOf schemas here and create interface models for them
super.preprocessOpenAPI(openAPI);
Map<String, Schema> schemas = new HashMap<String, Schema>(openAPI.getComponents().getSchemas());
if (schemas == null) {
schemas = new HashMap<String, Schema>();
}
Map<String, PathItem> pathItems = openAPI.getPaths();
// we need to add all request and response bodies to processed schemas
if (pathItems != null) {
for (Map.Entry<String, PathItem> e : pathItems.entrySet()) {
for (Map.Entry<PathItem.HttpMethod, Operation> op : e.getValue().readOperationsMap().entrySet()) {
String opId = getOrGenerateOperationId(op.getValue(), e.getKey(), op.getKey().toString());
// process request body
RequestBody b = ModelUtils.getReferencedRequestBody(openAPI, op.getValue().getRequestBody());
Schema requestSchema = null;
if (b != null) {
requestSchema = ModelUtils.getSchemaFromRequestBody(b);
}
if (requestSchema != null) {
schemas.put(opId, requestSchema);
}
// process all response bodies
for (Map.Entry<String, ApiResponse> ar : op.getValue().getResponses().entrySet()) {
ApiResponse a = ModelUtils.getReferencedApiResponse(openAPI, ar.getValue());
Schema responseSchema = ModelUtils.getSchemaFromResponse(a);
if (responseSchema != null) {
schemas.put(opId + ar.getKey(), responseSchema);
}
}
}
}
}
for (Map.Entry<String, Schema> e : schemas.entrySet()) {
String n = toModelName(e.getKey());
Schema s = e.getValue();
String nOneOf = toModelName(n + "OneOf");
if (ModelUtils.isComposedSchema(s)) {
addOneOfNameExtension(s, n);
} else if (ModelUtils.isArraySchema(s)) {
Schema items = ((ArraySchema) s).getItems();
if (ModelUtils.isComposedSchema(items)) {
addOneOfNameExtension(items, nOneOf);
addOneOfInterfaceModel((ComposedSchema) items, nOneOf);
}
} else if (ModelUtils.isMapSchema(s)) {
Schema addProps = ModelUtils.getAdditionalProperties(s);
if (addProps != null && ModelUtils.isComposedSchema(addProps)) {
addOneOfNameExtension(addProps, nOneOf);
addOneOfInterfaceModel((ComposedSchema) addProps, nOneOf);
}
}
}
}
private class OneOfImplementorAdditionalData {
private String implementorName;
private List<String> additionalInterfaces = new ArrayList<String>();
private List<CodegenProperty> additionalProps = new ArrayList<CodegenProperty>();
private List<Map<String, String>> additionalImports = new ArrayList<Map<String, String>>();
public OneOfImplementorAdditionalData(String implementorName) {
this.implementorName = implementorName;
}
public String getImplementorName() {
return implementorName;
}
public void addFromInterfaceModel(CodegenModel cm, List<Map<String, String>> modelsImports) {
// Add cm as implemented interface
additionalInterfaces.add(cm.classname);
// Add all vars defined on cm
// a "oneOf" model (cm) by default inherits all properties from its "interfaceModels",
// but we only want to add properties defined on cm itself
List<CodegenProperty> toAdd = new ArrayList<CodegenProperty>(cm.vars);
// note that we can't just toAdd.removeAll(m.vars) for every interfaceModel,
// as they might have different value of `hasMore` and thus are not equal
List<String> omitAdding = new ArrayList<String>();
for (CodegenModel m : cm.interfaceModels) {
for (CodegenProperty v : m.vars) {
omitAdding.add(v.baseName);
}
}
for (CodegenProperty v : toAdd) {
if (!omitAdding.contains(v.baseName)) {
additionalProps.add(v.clone());
}
}
// Add all imports of cm
for (Map<String, String> importMap : modelsImports) {
// we're ok with shallow clone here, because imports are strings only
additionalImports.add(new HashMap<String, String>(importMap));
}
}
public void addToImplementor(CodegenModel implcm, List<Map<String, String>> implImports) {
implcm.getVendorExtensions().putIfAbsent("implements", new ArrayList<String>());
// Add implemented interfaces
for (String intf : additionalInterfaces) {
List<String> impl = (List<String>) implcm.getVendorExtensions().get("implements");
impl.add(intf);
// Add imports for interfaces
implcm.imports.add(intf);
Map<String, String> importsItem = new HashMap<String, String>();
importsItem.put("import", toModelImport(intf));
implImports.add(importsItem);
}
// Add oneOf-containing models properties - we need to properly set the hasMore values to make renderind correct
if (implcm.vars.size() > 0 && additionalProps.size() > 0) {
implcm.vars.get(implcm.vars.size() - 1).hasMore = true;
}
for (int i = 0; i < additionalProps.size(); i++) {
CodegenProperty var = additionalProps.get(i);
if (i == additionalProps.size() - 1) {
var.hasMore = false;
} else {
var.hasMore = true;
}
implcm.vars.add(var);
}
// Add imports
for (Map<String, String> oneImport : additionalImports) {
// exclude imports from this package - these are imports that only the oneOf interface needs
if (!implImports.contains(oneImport) && !oneImport.getOrDefault("import", "").startsWith(modelPackage())) {
implImports.add(oneImport);
}
}
}
}
@Override
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
objs = super.postProcessAllModels(objs);
if (this.useOneOfInterfaces) {
// First, add newly created oneOf interfaces
for (CodegenModel cm : addOneOfInterfaces) {
Map<String, Object> modelValue = new HashMap<String, Object>() {{
putAll(additionalProperties());
put("model", cm);
}};
List<Object> modelsValue = Arrays.asList(modelValue);
List<Map<String, String>> importsValue = new ArrayList<Map<String, String>>();
for (String i : Arrays.asList("JsonSubTypes", "JsonTypeInfo")) {
Map<String, String> oneImport = new HashMap<String, String>() {{
put("import", importMapping.get(i));
}};
importsValue.add(oneImport);
}
Map<String, Object> objsValue = new HashMap<String, Object>() {{
put("models", modelsValue);
put("package", modelPackage());
put("imports", importsValue);
put("classname", cm.classname);
putAll(additionalProperties);
}};
objs.put(cm.name, objsValue);
}
// - Add all "oneOf" models as interfaces to be implemented by the models that
// are the choices in "oneOf"; also mark the models containing "oneOf" as interfaces
// - Add all properties of "oneOf" to the implementing classes (NOTE that this
// would be problematic if the class was in multiple such "oneOf" models, in which
// case it would get all their properties, but it's probably better than not doing this)
// - Add all imports of "oneOf" model to all the implementing classes (this might not
// be optimal, as it can contain more than necessary, but it's good enough)
Map<String, OneOfImplementorAdditionalData> additionalDataMap = new HashMap<String, OneOfImplementorAdditionalData>();
for (Map.Entry modelsEntry : objs.entrySet()) {
Map<String, Object> modelsAttrs = (Map<String, Object>) modelsEntry.getValue();
List<Object> models = (List<Object>) modelsAttrs.get("models");
List<Map<String, String>> modelsImports = (List<Map<String, String>>) modelsAttrs.getOrDefault("imports", new ArrayList<Map<String, String>>());
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
if (cm.oneOf.size() > 0) {
cm.vendorExtensions.put("isOneOfInterface", true);
// if this is oneOf interface, make sure we include the necessary jackson imports for it
for (String s : Arrays.asList("JsonTypeInfo", "JsonSubTypes")) {
Map<String, String> i = new HashMap<String, String>() {{
put("import", importMapping.get(s));
}};
if (!modelsImports.contains(i)) {
modelsImports.add(i);
}
}
for (String one : cm.oneOf) {
if (!additionalDataMap.containsKey(one)) {
additionalDataMap.put(one, new OneOfImplementorAdditionalData(one));
}
additionalDataMap.get(one).addFromInterfaceModel(cm, modelsImports);
}
}
}
}
for (Map.Entry modelsEntry : objs.entrySet()) {
Map<String, Object> modelsAttrs = (Map<String, Object>) modelsEntry.getValue();
List<Object> models = (List<Object>) modelsAttrs.get("models");
List<Map<String, String>> imports = (List<Map<String, String>>) modelsAttrs.get("imports");
for (Object _implmo : models) {
Map<String, Object> implmo = (Map<String, Object>) _implmo;
CodegenModel implcm = (CodegenModel) implmo.get("model");
if (additionalDataMap.containsKey(implcm.name)) {
additionalDataMap.get(implcm.name).addToImplementor(implcm, imports);
}
}
}
}
return objs;
}
public void forceSerializationLibrary(String serializationLibrary) {
if((this.serializationLibrary != null) && !this.serializationLibrary.equalsIgnoreCase(serializationLibrary)) {
LOGGER.warn("The configured serializationLibrary '" + this.serializationLibrary + "', is not supported by the library: '" + getLibrary() + "', switching back to: " + serializationLibrary);

View File

@@ -42,6 +42,6 @@ import org.hibernate.validator.constraints.*;
{{#models}}
{{#model}}
{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{>pojo}}{{/isEnum}}
{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{#vendorExtensions.isOneOfInterface}}{{>oneof_interface}}{{/vendorExtensions.isOneOfInterface}}{{^vendorExtensions.isOneOfInterface}}{{>pojo}}{{/vendorExtensions.isOneOfInterface}}{{/isEnum}}
{{/model}}
{{/models}}

View File

@@ -21,6 +21,7 @@ import java.util.Map;
public class {{classname}}Test {
{{#models}}
{{#model}}
{{^vendorExtensions.isOneOfInterface}}
{{^isEnum}}
private final {{classname}} model = new {{classname}}();
@@ -43,6 +44,7 @@ public class {{classname}}Test {
}
{{/allVars}}
{{/vendorExtensions.isOneOfInterface}}
{{/model}}
{{/models}}
}

View File

@@ -0,0 +1,6 @@
{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{>typeInfoAnnotation}}{{>xmlAnnotation}}
public interface {{classname}} {{#vendorExtensions.implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.implements}} {
{{#discriminator}}
public {{propertyType}} {{propertyGetter}}();
{{/discriminator}}
}

View File

@@ -10,7 +10,7 @@
})
{{/jackson}}
{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}}
public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#parcelableModel}}implements Parcelable {{#serializableModel}}, Serializable {{/serializableModel}}{{/parcelableModel}}{{^parcelableModel}}{{#serializableModel}}implements Serializable {{/serializableModel}}{{/parcelableModel}}{
public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#vendorExtensions.implements}}{{#-first}}implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{#-last}} {{/-last}}{{/vendorExtensions.implements}}{
{{#serializableModel}}
private static final long serialVersionUID = 1L;

View File

@@ -1,7 +1,8 @@
# {{classname}}
# {{#vendorExtensions.isOneOfInterface}}Interface {{/vendorExtensions.isOneOfInterface}}{{classname}}
{{#description}}{{&description}}
{{/description}}
{{^vendorExtensions.isOneOfInterface}}
## Properties
Name | Type | Description | Notes
@@ -17,3 +18,19 @@ Name | Value
---- | -----{{#allowableValues}}{{#enumVars}}
{{name}} | {{value}}{{/enumVars}}{{/allowableValues}}
{{/isEnum}}{{/vars}}
{{#vendorExtensions.implements.0}}
## Implemented Interfaces
{{#vendorExtensions.implements}}
* {{{.}}}
{{/vendorExtensions.implements}}
{{/vendorExtensions.implements.0}}
{{/vendorExtensions.isOneOfInterface}}
{{#vendorExtensions.isOneOfInterface}}
## Implementing Classes
{{#oneOf}}
* {{{.}}}
{{/oneOf}}
{{/vendorExtensions.isOneOfInterface}}

View File

@@ -1,6 +1,6 @@
{{#jackson}}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{{discriminator.propertyBaseName}}}", visible = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "{{{discriminator.propertyBaseName}}}", visible = true)
@JsonSubTypes({
{{#discriminator.mappedModels}}
@JsonSubTypes.Type(value = {{modelName}}.class, name = "{{^vendorExtensions.x-discriminator-value}}{{mappingName}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}"),

View File

@@ -34,7 +34,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
})
@javax.annotation.concurrent.Immutable
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className", visible = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "className", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),

View File

@@ -33,7 +33,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
Animal.JSON_PROPERTY_COLOR
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className", visible = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "className", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),

View File

@@ -33,7 +33,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
Animal.JSON_PROPERTY_COLOR
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className", visible = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "className", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),

View File

@@ -33,7 +33,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
Animal.JSON_PROPERTY_COLOR
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className", visible = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "className", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),

View File

@@ -32,7 +32,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
Animal.JSON_PROPERTY_COLOR
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className", visible = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "className", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),

View File

@@ -33,7 +33,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
Animal.JSON_PROPERTY_COLOR
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className", visible = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "className", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),

View File

@@ -33,7 +33,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
Animal.JSON_PROPERTY_COLOR
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className", visible = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "className", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),

View File

@@ -33,7 +33,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
Animal.JSON_PROPERTY_COLOR
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className", visible = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "className", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),

View File

@@ -9,4 +9,8 @@ Name | Type | Description | Notes
**name** | **String** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -9,4 +9,8 @@ Name | Type | Description | Notes
**name** | **String** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -9,4 +9,8 @@ Name | Type | Description | Notes
**name** | **String** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -19,4 +19,8 @@ Name | Type | Description | Notes
**anytype3** | [**Object**](.md) | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -9,4 +9,8 @@ Name | Type | Description | Notes
**name** | **String** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -9,4 +9,8 @@ Name | Type | Description | Notes
**name** | **String** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -9,4 +9,8 @@ Name | Type | Description | Notes
**name** | **String** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -9,4 +9,8 @@ Name | Type | Description | Notes
**name** | **String** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -10,4 +10,8 @@ Name | Type | Description | Notes
**color** | **String** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -9,4 +9,8 @@ Name | Type | Description | Notes
**arrayArrayNumber** | [**List&lt;List&lt;BigDecimal&gt;&gt;**](List.md) | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -9,4 +9,8 @@ Name | Type | Description | Notes
**arrayNumber** | [**List&lt;BigDecimal&gt;**](BigDecimal.md) | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -11,4 +11,8 @@ Name | Type | Description | Notes
**arrayArrayOfModel** | [**List&lt;List&lt;ReadOnlyFirst&gt;&gt;**](List.md) | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -20,4 +20,8 @@ LEOPARDS | &quot;leopards&quot;
JAGUARS | &quot;jaguars&quot;
## Implemented Interfaces
* Parcelable

View File

@@ -20,4 +20,8 @@ LEOPARDS | &quot;leopards&quot;
JAGUARS | &quot;jaguars&quot;
## Implemented Interfaces
* Parcelable

View File

@@ -14,4 +14,8 @@ Name | Type | Description | Notes
**ATT_NAME** | **String** | Name of the pet | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -9,4 +9,8 @@ Name | Type | Description | Notes
**declawed** | **Boolean** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -9,4 +9,8 @@ Name | Type | Description | Notes
**declawed** | **Boolean** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -10,4 +10,8 @@ Name | Type | Description | Notes
**name** | **String** | |
## Implemented Interfaces
* Parcelable

View File

@@ -10,4 +10,8 @@ Name | Type | Description | Notes
**propertyClass** | **String** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -9,4 +9,8 @@ Name | Type | Description | Notes
**client** | **String** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -9,4 +9,8 @@ Name | Type | Description | Notes
**breed** | **String** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -9,4 +9,8 @@ Name | Type | Description | Notes
**breed** | **String** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -28,4 +28,8 @@ FISH | &quot;fish&quot;
CRAB | &quot;crab&quot;
## Implemented Interfaces
* Parcelable

View File

@@ -51,4 +51,8 @@ NUMBER_1_DOT_1 | 1.1
NUMBER_MINUS_1_DOT_2 | -1.2
## Implemented Interfaces
* Parcelable

View File

@@ -10,4 +10,8 @@ Name | Type | Description | Notes
**files** | [**List&lt;java.io.File&gt;**](java.io.File.md) | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -22,4 +22,8 @@ Name | Type | Description | Notes
**bigDecimal** | [**BigDecimal**](BigDecimal.md) | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -10,4 +10,8 @@ Name | Type | Description | Notes
**foo** | **String** | | [optional] [readonly]
## Implemented Interfaces
* Parcelable

View File

@@ -21,4 +21,8 @@ UPPER | &quot;UPPER&quot;
LOWER | &quot;lower&quot;
## Implemented Interfaces
* Parcelable

View File

@@ -11,4 +11,8 @@ Name | Type | Description | Notes
**map** | [**Map&lt;String, Animal&gt;**](Animal.md) | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -11,4 +11,8 @@ Name | Type | Description | Notes
**propertyClass** | **String** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -11,4 +11,8 @@ Name | Type | Description | Notes
**message** | **String** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -10,4 +10,8 @@ Name | Type | Description | Notes
**_return** | **Integer** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -13,4 +13,8 @@ Name | Type | Description | Notes
**_123number** | **Integer** | | [optional] [readonly]
## Implemented Interfaces
* Parcelable

View File

@@ -9,4 +9,8 @@ Name | Type | Description | Notes
**justNumber** | [**BigDecimal**](BigDecimal.md) | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -24,4 +24,8 @@ APPROVED | &quot;approved&quot;
DELIVERED | &quot;delivered&quot;
## Implemented Interfaces
* Parcelable

View File

@@ -11,4 +11,8 @@ Name | Type | Description | Notes
**myBoolean** | **Boolean** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -24,4 +24,8 @@ PENDING | &quot;pending&quot;
SOLD | &quot;sold&quot;
## Implemented Interfaces
* Parcelable

View File

@@ -10,4 +10,8 @@ Name | Type | Description | Notes
**baz** | **String** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -9,4 +9,8 @@ Name | Type | Description | Notes
**$specialPropertyName** | **Long** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -10,4 +10,8 @@ Name | Type | Description | Notes
**name** | **String** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -13,4 +13,8 @@ Name | Type | Description | Notes
**arrayItem** | **List&lt;Integer&gt;** | |
## Implemented Interfaces
* Parcelable

View File

@@ -14,4 +14,8 @@ Name | Type | Description | Notes
**arrayItem** | **List&lt;Integer&gt;** | |
## Implemented Interfaces
* Parcelable

View File

@@ -16,4 +16,8 @@ Name | Type | Description | Notes
**userStatus** | **Integer** | User Status | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -37,4 +37,8 @@ Name | Type | Description | Notes
**prefixNsWrappedArray** | **List&lt;Integer&gt;** | | [optional]
## Implemented Interfaces
* Parcelable

View File

@@ -33,7 +33,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
Animal.JSON_PROPERTY_COLOR
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className", visible = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "className", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),

View File

@@ -35,7 +35,7 @@ import javax.xml.bind.annotation.*;
Animal.JSON_PROPERTY_COLOR
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className", visible = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "className", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),

View File

@@ -33,7 +33,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
Animal.JSON_PROPERTY_COLOR
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className", visible = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "className", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),

View File

@@ -35,7 +35,7 @@ import javax.validation.Valid;
Animal.JSON_PROPERTY_COLOR
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className", visible = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "className", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),

View File

@@ -35,7 +35,7 @@ import javax.validation.Valid;
Animal.JSON_PROPERTY_COLOR
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className", visible = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "className", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),

View File

@@ -35,7 +35,7 @@ import javax.validation.Valid;
Animal.JSON_PROPERTY_COLOR
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className", visible = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "className", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),

View File

@@ -33,7 +33,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
Animal.JSON_PROPERTY_COLOR
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className", visible = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "className", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),

View File

@@ -33,7 +33,7 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
Animal.JSON_PROPERTY_COLOR
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className", visible = true)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "className", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "Dog"),
@JsonSubTypes.Type(value = Cat.class, name = "Cat"),