forked from loafle/openapi-generator-original
[Java][Jersey2] various improvements (#6518)
* [java][jersey2] Add support for discriminator, fix nullable typo and nullable deserialization (#6495) * Mustache template should use invokerPackage tag to generate import * fix typo, fix script issue, add log statement for troubleshooting * Add java jersey2 samples with OpenAPI doc that has HTTP signature security scheme * Add sample for Java jersey2 and HTTP signature scheme * Add unit test for oneOf schema deserialization * Add unit test for oneOf schema deserialization * Add log statements * Add profile for jersey2 * Temporarily disable unit test * Temporarily disable unit test * support for discriminator in jersey2 * fix typo in pom.xml * disable unit test because jersey2 deserialization is broken * disable unit test because jersey2 deserialization is broken * fix duplicate jersey2 samples * fix duplicate jersey2 samples * Add code comments * fix duplicate artifact id * fix duplicate jersey2 samples * run samples scripts * resolve merge conflicts * Add unit tests * fix unit tests * continue implementation of discriminator lookup * throw deserialization exception when value is null and schema does not allow null value * continue implementation of compose schema * continue implementation of compose schema * continue implementation of compose schema * Add more unit tests * Add unit tests for anyOf * Add unit tests Co-authored-by: Vikrant Balyan (vvb) <vvb@cisco.com> * update samples * add tests to oas3 java jersey2 petstore * comment out jersey2 ensure uptodate * Jersey2 supports additional properties with composed schema (#6523) * Mustache template should use invokerPackage tag to generate import * fix typo, fix script issue, add log statement for troubleshooting * Add java jersey2 samples with OpenAPI doc that has HTTP signature security scheme * Add sample for Java jersey2 and HTTP signature scheme * Add unit test for oneOf schema deserialization * Add unit test for oneOf schema deserialization * Add log statements * Add profile for jersey2 * Temporarily disable unit test * Temporarily disable unit test * support for discriminator in jersey2 * fix typo in pom.xml * disable unit test because jersey2 deserialization is broken * disable unit test because jersey2 deserialization is broken * fix duplicate jersey2 samples * fix duplicate jersey2 samples * Add code comments * fix duplicate artifact id * fix duplicate jersey2 samples * run samples scripts * resolve merge conflicts * Add unit tests * fix unit tests * continue implementation of discriminator lookup * throw deserialization exception when value is null and schema does not allow null value * continue implementation of compose schema * continue implementation of compose schema * continue implementation of compose schema * Add more unit tests * Add unit tests for anyOf * Add unit tests * Set supportsAdditionalPropertiesWithComposedSchema to true for Java jersey2 * Support additional properties as nested field * Support additional properties as nested field * add code comments * add customer deserializer * Fix 'method too big' error with generated code * resolve merge conflicts Co-authored-by: Vikrant Balyan (vvb) <vvb@cisco.com> * [Jersey2] Fix code generation of 'registerDiscriminator' method for large models (#6535) * Mustache template should use invokerPackage tag to generate import * fix typo, fix script issue, add log statement for troubleshooting * Add java jersey2 samples with OpenAPI doc that has HTTP signature security scheme * Add sample for Java jersey2 and HTTP signature scheme * Add unit test for oneOf schema deserialization * Add unit test for oneOf schema deserialization * Add log statements * Add profile for jersey2 * Temporarily disable unit test * Temporarily disable unit test * support for discriminator in jersey2 * fix typo in pom.xml * disable unit test because jersey2 deserialization is broken * disable unit test because jersey2 deserialization is broken * fix duplicate jersey2 samples * fix duplicate jersey2 samples * Add code comments * fix duplicate artifact id * fix duplicate jersey2 samples * run samples scripts * resolve merge conflicts * Add unit tests * fix unit tests * continue implementation of discriminator lookup * throw deserialization exception when value is null and schema does not allow null value * continue implementation of compose schema * continue implementation of compose schema * continue implementation of compose schema * Add more unit tests * Add unit tests for anyOf * Add unit tests * Fix 'method too big' error with generated code * resolve merge conflicts Co-authored-by: Vikrant Balyan (vvb) <vvb@cisco.com> * update samples * comment out tests * support additional properties in serialize and deserialize * add discriminator lookup * remove oneof/anyof logic in apilcient * add serializer to mammal.java * add serialize to oneOf model * add serializer to anyof model * comment out test cases that are subject to further discussion * add back files * update configs, samples Co-authored-by: Sebastien Rosset <serosset@cisco.com> Co-authored-by: Vikrant Balyan (vvb) <vvb@cisco.com>
This commit is contained in:
@@ -1649,10 +1649,24 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
|
||||
|
||||
@Override
|
||||
protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Schema schema) {
|
||||
super.addAdditionPropertiesToCodeGenModel(codegenModel, schema);
|
||||
if (!supportsAdditionalPropertiesWithComposedSchema) {
|
||||
// The additional (undeclared) propertiees are modeled in Java as a HashMap.
|
||||
//
|
||||
// 1. supportsAdditionalPropertiesWithComposedSchema is set to false:
|
||||
// The generated model class extends from the HashMap. That does not work
|
||||
// with composed schemas that also use a discriminator because the model class
|
||||
// is supposed to extend from the generated parent model class.
|
||||
// 2. supportsAdditionalPropertiesWithComposedSchema is set to true:
|
||||
// The HashMap is a field.
|
||||
super.addAdditionPropertiesToCodeGenModel(codegenModel, schema);
|
||||
}
|
||||
|
||||
// See https://github.com/OpenAPITools/openapi-generator/pull/1729#issuecomment-449937728
|
||||
codegenModel.additionalPropertiesType = getSchemaType(getAdditionalProperties(schema));
|
||||
addImport(codegenModel, codegenModel.additionalPropertiesType);
|
||||
Schema s = getAdditionalProperties(schema);
|
||||
// 's' may be null if 'additionalProperties: false' in the OpenAPI schema.
|
||||
if (s != null) {
|
||||
codegenModel.additionalPropertiesType = getSchemaType(s);
|
||||
addImport(codegenModel, codegenModel.additionalPropertiesType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,6 +176,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
// inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values,
|
||||
// and the discriminator mapping schemas in the OAS document.
|
||||
this.setLegacyDiscriminatorBehavior(false);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -371,6 +372,14 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
}
|
||||
supportingFiles.add(new SupportingFile("AbstractOpenApiSchema.mustache", (sourceFolder + File.separator + modelPackage().replace('.', File.separatorChar)).replace('/', File.separatorChar), "AbstractOpenApiSchema.java"));
|
||||
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
|
||||
|
||||
// Composed schemas can have the 'additionalProperties' keyword, as specified in JSON schema.
|
||||
// In principle, this should be enabled by default for all code generators. However due to limitations
|
||||
// in other code generators, support needs to be enabled on a case-by-case basis.
|
||||
// The flag below should be set for all Java libraries, but the templates need to be ported
|
||||
// one by one for each library.
|
||||
supportsAdditionalPropertiesWithComposedSchema = true;
|
||||
|
||||
} else if (NATIVE.equals(getLibrary())) {
|
||||
setJava8Mode(true);
|
||||
additionalProperties.put("java8", "true");
|
||||
@@ -587,38 +596,6 @@ public class JavaClientCodegen extends AbstractJavaCodegen
|
||||
objs = AbstractJavaJAXRSServerCodegen.jaxrsPostProcessOperations(objs);
|
||||
}
|
||||
|
||||
if (JERSEY2.equals(getLibrary())) {
|
||||
// index the model
|
||||
HashMap<String, CodegenModel> modelMaps = new HashMap<String, CodegenModel>();
|
||||
for (Object o : allModels) {
|
||||
HashMap<String, Object> h = (HashMap<String, Object>) o;
|
||||
CodegenModel m = (CodegenModel) h.get("model");
|
||||
modelMaps.put(m.classname, m);
|
||||
}
|
||||
|
||||
// check if return type is oneOf/anyeOf model
|
||||
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
|
||||
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
|
||||
for (CodegenOperation op : operationList) {
|
||||
if (op.returnType != null) {
|
||||
// look up the model to see if it's anyOf/oneOf
|
||||
if (modelMaps.containsKey(op.returnType) && modelMaps.get(op.returnType) != null) {
|
||||
CodegenModel cm = modelMaps.get(op.returnType);
|
||||
|
||||
if (cm.oneOf != null && !cm.oneOf.isEmpty()) {
|
||||
op.vendorExtensions.put("x-java-return-type-one-of", true);
|
||||
}
|
||||
|
||||
if (cm.anyOf != null && !cm.anyOf.isEmpty()) {
|
||||
op.vendorExtensions.put("x-java-return-type-any-of", true);
|
||||
}
|
||||
} else {
|
||||
//LOGGER.error("cannot lookup model " + op.returnType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return objs;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,14 +30,14 @@ public abstract class AbstractOpenApiSchema {
|
||||
this.isNullable = isNullable;
|
||||
}
|
||||
|
||||
/***
|
||||
* Get the list of schemas allowed to be stored in this object
|
||||
/**
|
||||
* Get the list of oneOf/anyOf composed schemas allowed to be stored in this object
|
||||
*
|
||||
* @return an instance of the actual schema/object
|
||||
*/
|
||||
public abstract Map<String, GenericType> getSchemas();
|
||||
|
||||
/***
|
||||
/**
|
||||
* Get the actual instance
|
||||
*
|
||||
* @return an instance of the actual schema/object
|
||||
@@ -45,14 +45,14 @@ public abstract class AbstractOpenApiSchema {
|
||||
@JsonValue
|
||||
public Object getActualInstance() {return instance;}
|
||||
|
||||
/***
|
||||
/**
|
||||
* Set the actual instance
|
||||
*
|
||||
* @param instance the actual instance of the schema/object
|
||||
*/
|
||||
public void setActualInstance(Object instance) {this.instance = instance;}
|
||||
|
||||
/***
|
||||
/**
|
||||
* Get the schema type (e.g. anyOf, oneOf)
|
||||
*
|
||||
* @return the schema type
|
||||
@@ -101,7 +101,7 @@ public abstract class AbstractOpenApiSchema {
|
||||
return Objects.hash(instance, isNullable, schemaType);
|
||||
}
|
||||
|
||||
/***
|
||||
/**
|
||||
* Is nullalble
|
||||
*
|
||||
* @return true if it's nullable
|
||||
@@ -113,4 +113,7 @@ public abstract class AbstractOpenApiSchema {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
{{>libraries/jersey2/additional_properties}}
|
||||
|
||||
}
|
||||
|
||||
@@ -68,7 +68,6 @@ import {{invokerPackage}}.auth.ApiKeyAuth;
|
||||
{{#hasOAuthMethods}}
|
||||
import {{invokerPackage}}.auth.OAuth;
|
||||
{{/hasOAuthMethods}}
|
||||
import {{invokerPackage}}.model.AbstractOpenApiSchema;
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
public class ApiClient {
|
||||
@@ -894,67 +893,6 @@ public class ApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
public AbstractOpenApiSchema deserializeSchemas(Response response, AbstractOpenApiSchema schema) throws ApiException{
|
||||
|
||||
Object result = null;
|
||||
int matchCounter = 0;
|
||||
ArrayList<String> matchSchemas = new ArrayList<>();
|
||||
|
||||
if (schema.isNullable()) {
|
||||
response.bufferEntity();
|
||||
if ("{}".equals(String.valueOf(response.readEntity(String.class))) ||
|
||||
"".equals(String.valueOf(response.readEntity(String.class)))) {
|
||||
// schema is nullable and the response body is {} or empty string
|
||||
return schema;
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, GenericType> entry : schema.getSchemas().entrySet()) {
|
||||
String schemaName = entry.getKey();
|
||||
GenericType schemaType = entry.getValue();
|
||||
|
||||
if (schemaType instanceof GenericType) { // model
|
||||
try {
|
||||
Object deserializedObject = deserialize(response, schemaType);
|
||||
if (deserializedObject != null) {
|
||||
result = deserializedObject;
|
||||
matchCounter++;
|
||||
|
||||
if ("anyOf".equals(schema.getSchemaType())) {
|
||||
break;
|
||||
} else if ("oneOf".equals(schema.getSchemaType())) {
|
||||
matchSchemas.add(schemaName);
|
||||
} else {
|
||||
throw new ApiException("Unknowe type found while expecting anyOf/oneOf:" + schema.getSchemaType());
|
||||
}
|
||||
} else {
|
||||
// failed to deserialize the response in the schema provided, proceed to the next one if any
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// failed to deserialize, do nothing and try next one (schema)
|
||||
// Logging the error may be useful to troubleshoot why a payload fails to match
|
||||
// the schema.
|
||||
log.log(Level.FINE, "Input data does not match schema '" + schemaName + "'", ex);
|
||||
}
|
||||
} else {// unknown type
|
||||
throw new ApiException(schemaType.getClass() + " is not a GenericType and cannot be handled properly in deserialization.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (matchCounter > 1 && "oneOf".equals(schema.getSchemaType())) {// more than 1 match for oneOf
|
||||
throw new ApiException("Response body is invalid as it matches more than one schema (" + StringUtil.join(matchSchemas, ", ") + ") defined in the oneOf model: " + schema.getClass().getName());
|
||||
} else if (matchCounter == 0) { // fail to match any in oneOf/anyOf schemas
|
||||
throw new ApiException("Response body is invalid as it does not match any schemas (" + StringUtil.join(schema.getSchemas().keySet(), ", ") + ") defined in the oneOf/anyOf model: " + schema.getClass().getName());
|
||||
} else { // only one matched
|
||||
schema.setActualInstance(result);
|
||||
return schema;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Deserialize response body to Java object according to the Content-Type.
|
||||
* @param <T> Type
|
||||
@@ -1062,7 +1000,6 @@ public class ApiClient {
|
||||
* @param contentType The request's Content-Type header
|
||||
* @param authNames The authentications to apply
|
||||
* @param returnType The return type into which to deserialize the response
|
||||
* @param schema An instance of the response that uses oneOf/anyOf
|
||||
* @return The response body in type of string
|
||||
* @throws ApiException API exception
|
||||
*/
|
||||
@@ -1078,8 +1015,7 @@ public class ApiClient {
|
||||
String accept,
|
||||
String contentType,
|
||||
String[] authNames,
|
||||
GenericType<T> returnType,
|
||||
AbstractOpenApiSchema schema)
|
||||
GenericType<T> returnType)
|
||||
throws ApiException {
|
||||
|
||||
// Not using `.target(targetURL).path(path)` below,
|
||||
@@ -1178,12 +1114,10 @@ public class ApiClient {
|
||||
if (response.getStatusInfo() == Status.NO_CONTENT) {
|
||||
return new ApiResponse<T>(statusCode, responseHeaders);
|
||||
} else if (response.getStatusInfo().getFamily() == Status.Family.SUCCESSFUL) {
|
||||
if (returnType == null) return new ApiResponse<T>(statusCode, responseHeaders);
|
||||
else if (schema == null) {
|
||||
if (returnType == null) {
|
||||
return new ApiResponse<T>(statusCode, responseHeaders);
|
||||
} else {
|
||||
return new ApiResponse<T>(statusCode, responseHeaders, deserialize(response, returnType));
|
||||
} else { // oneOf/anyOf
|
||||
return new ApiResponse<T>(
|
||||
statusCode, responseHeaders, (T) deserializeSchemas(response, schema));
|
||||
}
|
||||
} else {
|
||||
String message = "error";
|
||||
@@ -1229,8 +1163,8 @@ public class ApiClient {
|
||||
* @deprecated Add qualified name of the operation as a first parameter.
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> ApiResponse<T> invokeAPI(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, String> cookieParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, GenericType<T> returnType, AbstractOpenApiSchema schema) throws ApiException {
|
||||
return invokeAPI(null, path, method, queryParams, body, headerParams, cookieParams, formParams, accept, contentType, authNames, returnType, schema);
|
||||
public <T> ApiResponse<T> invokeAPI(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, String> cookieParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, GenericType<T> returnType) throws ApiException {
|
||||
return invokeAPI(null, path, method, queryParams, body, headerParams, cookieParams, formParams, accept, contentType, authNames, returnType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,9 +15,16 @@ import com.fasterxml.jackson.datatype.joda.JodaModule;
|
||||
{{#threetenbp}}
|
||||
import com.fasterxml.jackson.datatype.threetenbp.ThreeTenModule;
|
||||
{{/threetenbp}}
|
||||
{{#models.0}}
|
||||
import {{modelPackage}}.*;
|
||||
{{/models.0}}
|
||||
|
||||
import java.text.DateFormat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.ws.rs.core.GenericType;
|
||||
import javax.ws.rs.ext.ContextResolver;
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
@@ -69,4 +76,197 @@ public class JSON implements ContextResolver<ObjectMapper> {
|
||||
* @return object mapper
|
||||
*/
|
||||
public ObjectMapper getMapper() { return mapper; }
|
||||
|
||||
/**
|
||||
* Returns the target model class that should be used to deserialize the input data.
|
||||
* The discriminator mappings are used to determine the target model class.
|
||||
*
|
||||
* @param node The input data.
|
||||
* @param modelClass The class that contains the discriminator mappings.
|
||||
*/
|
||||
public static Class getClassForElement(JsonNode node, Class modelClass) {
|
||||
ClassDiscriminatorMapping cdm = modelDiscriminators.get(modelClass);
|
||||
if (cdm != null) {
|
||||
return cdm.getClassForElement(node, new HashSet<Class>());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class to register the discriminator mappings.
|
||||
*/
|
||||
private static class ClassDiscriminatorMapping {
|
||||
// The model class name.
|
||||
Class modelClass;
|
||||
// The name of the discriminator property.
|
||||
String discriminatorName;
|
||||
// The discriminator mappings for a model class.
|
||||
Map<String, Class> discriminatorMappings;
|
||||
|
||||
// Constructs a new class discriminator.
|
||||
ClassDiscriminatorMapping(Class cls, String propertyName, Map<String, Class> mappings) {
|
||||
modelClass = cls;
|
||||
discriminatorName = propertyName;
|
||||
discriminatorMappings = new HashMap<String, Class>();
|
||||
if (mappings != null) {
|
||||
discriminatorMappings.putAll(mappings);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the name of the discriminator property for this model class.
|
||||
String getDiscriminatorPropertyName() {
|
||||
return discriminatorName;
|
||||
}
|
||||
|
||||
// Return the discriminator value or null if the discriminator is not
|
||||
// present in the payload.
|
||||
String getDiscriminatorValue(JsonNode node) {
|
||||
// Determine the value of the discriminator property in the input data.
|
||||
if (discriminatorName != null) {
|
||||
// Get the value of the discriminator property, if present in the input payload.
|
||||
node = node.get(discriminatorName);
|
||||
if (node != null && node.isValueNode()) {
|
||||
String discrValue = node.asText();
|
||||
if (discrValue != null) {
|
||||
return discrValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the target model class that should be used to deserialize the input data.
|
||||
* This function can be invoked for anyOf/oneOf composed models with discriminator mappings.
|
||||
* The discriminator mappings are used to determine the target model class.
|
||||
*
|
||||
* @param node The input data.
|
||||
* @param visitedClasses The set of classes that have already been visited.
|
||||
*/
|
||||
Class getClassForElement(JsonNode node, Set<Class> visitedClasses) {
|
||||
if (visitedClasses.contains(modelClass)) {
|
||||
// Class has already been visited.
|
||||
return null;
|
||||
}
|
||||
// Determine the value of the discriminator property in the input data.
|
||||
String discrValue = getDiscriminatorValue(node);
|
||||
if (discrValue == null) {
|
||||
return null;
|
||||
}
|
||||
Class cls = discriminatorMappings.get(discrValue);
|
||||
// It may not be sufficient to return this cls directly because that target class
|
||||
// may itself be a composed schema, possibly with its own discriminator.
|
||||
visitedClasses.add(modelClass);
|
||||
for (Class childClass : discriminatorMappings.values()) {
|
||||
ClassDiscriminatorMapping childCdm = modelDiscriminators.get(childClass);
|
||||
if (childCdm == null) {
|
||||
continue;
|
||||
}
|
||||
if (!discriminatorName.equals(childCdm.discriminatorName)) {
|
||||
discrValue = getDiscriminatorValue(node);
|
||||
if (discrValue == null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (childCdm != null) {
|
||||
// Recursively traverse the discriminator mappings.
|
||||
Class childDiscr = childCdm.getClassForElement(node, visitedClasses);
|
||||
if (childDiscr != null) {
|
||||
return childDiscr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cls;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if inst is an instance of modelClass in the OpenAPI model hierarchy.
|
||||
*
|
||||
* The Java class hierarchy is not implemented the same way as the OpenAPI model hierarchy,
|
||||
* so it's not possible to use the instanceof keyword.
|
||||
*
|
||||
* @param modelClass A OpenAPI model class.
|
||||
* @param inst The instance object.
|
||||
*/
|
||||
public static boolean isInstanceOf(Class modelClass, Object inst, Set<Class> visitedClasses) {
|
||||
if (modelClass.isInstance(inst)) {
|
||||
// This handles the 'allOf' use case with single parent inheritance.
|
||||
return true;
|
||||
}
|
||||
if (visitedClasses.contains(modelClass)) {
|
||||
// This is to prevent infinite recursion when the composed schemas have
|
||||
// a circular dependency.
|
||||
return false;
|
||||
}
|
||||
visitedClasses.add(modelClass);
|
||||
|
||||
// Traverse the oneOf/anyOf composed schemas.
|
||||
Map<String, GenericType> descendants = modelDescendants.get(modelClass);
|
||||
if (descendants != null) {
|
||||
for (GenericType childType : descendants.values()) {
|
||||
if (isInstanceOf(childType.getRawType(), inst, visitedClasses)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* A map of discriminators for all model classes.
|
||||
*/
|
||||
private static Map<Class, ClassDiscriminatorMapping> modelDiscriminators = new HashMap<Class, ClassDiscriminatorMapping>();
|
||||
|
||||
/**
|
||||
* A map of oneOf/anyOf descendants for each model class.
|
||||
*/
|
||||
private static Map<Class, Map<String, GenericType>> modelDescendants = new HashMap<Class, Map<String, GenericType>>();
|
||||
|
||||
/**
|
||||
* Register a model class discriminator.
|
||||
*
|
||||
* @param modelClass the model class
|
||||
* @param discriminatorPropertyName the name of the discriminator property
|
||||
* @param mappings a map with the discriminator mappings.
|
||||
*/
|
||||
public static void registerDiscriminator(Class modelClass, String discriminatorPropertyName, Map<String, Class> mappings) {
|
||||
ClassDiscriminatorMapping m = new ClassDiscriminatorMapping(modelClass, discriminatorPropertyName, mappings);
|
||||
modelDiscriminators.put(modelClass, m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the oneOf/anyOf descendants of the modelClass.
|
||||
*
|
||||
* @param modelClass the model class
|
||||
* @param descendants a map of oneOf/anyOf descendants.
|
||||
*/
|
||||
public static void registerDescendants(Class modelClass, Map<String, GenericType> descendants) {
|
||||
modelDescendants.put(modelClass, descendants);
|
||||
}
|
||||
|
||||
private static JSON json;
|
||||
|
||||
static
|
||||
{
|
||||
json = new JSON();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default JSON instance.
|
||||
*
|
||||
* @return the default JSON instance
|
||||
*/
|
||||
public static JSON getDefault() {
|
||||
return json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default JSON instance.
|
||||
*
|
||||
* @param json JSON instance to be used
|
||||
*/
|
||||
public static void setDefault(JSON json) {
|
||||
JSON.json = json;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
{{#additionalPropertiesType}}
|
||||
/**
|
||||
* A container for additional, undeclared properties.
|
||||
* This is a holder for any undeclared properties as specified with
|
||||
* the 'additionalProperties' keyword in the OAS document.
|
||||
*/
|
||||
private Map<String, {{{.}}}> additionalProperties;
|
||||
|
||||
/**
|
||||
* Set the additional (undeclared) property with the specified name and value.
|
||||
* If the property does not already exist, create it otherwise replace it.
|
||||
*/
|
||||
@JsonAnySetter
|
||||
public {{classname}} putAdditionalProperty(String key, {{{.}}} value) {
|
||||
if (this.additionalProperties == null) {
|
||||
this.additionalProperties = new HashMap<String, {{{.}}}>();
|
||||
}
|
||||
this.additionalProperties.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the additional (undeclared) property.
|
||||
*/
|
||||
@JsonAnyGetter
|
||||
public Map<String, {{{.}}}> getAdditionalProperties() {
|
||||
return additionalProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the additional (undeclared) property with the specified name.
|
||||
*/
|
||||
public {{{.}}} getAdditionalProperty(String key) {
|
||||
if (this.additionalProperties == null) {
|
||||
return null;
|
||||
}
|
||||
return this.additionalProperties.get(key);
|
||||
}
|
||||
{{/additionalPropertiesType}}
|
||||
@@ -4,21 +4,44 @@ import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
import org.openapitools.client.JSON;
|
||||
|
||||
{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{>xmlAnnotation}}
|
||||
@JsonDeserialize(using={{classname}}.{{classname}}Deserializer.class)
|
||||
@JsonSerialize(using = {{classname}}.{{classname}}Serializer.class)
|
||||
public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-implements}}, {{{.}}}{{/vendorExtensions.x-implements}} {
|
||||
private static final Logger log = Logger.getLogger({{classname}}.class.getName());
|
||||
|
||||
public static class {{classname}}Serializer extends StdSerializer<{{classname}}> {
|
||||
public {{classname}}Serializer(Class<{{classname}}> t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
public {{classname}}Serializer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize({{classname}} value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
|
||||
jgen.writeObject(value.getActualInstance());
|
||||
}
|
||||
}
|
||||
|
||||
public static class {{classname}}Deserializer extends StdDeserializer<{{classname}}> {
|
||||
public {{classname}}Deserializer() {
|
||||
this({{classname}}.class);
|
||||
@@ -33,6 +56,18 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
|
||||
JsonNode tree = jp.readValueAsTree();
|
||||
|
||||
Object deserialized = null;
|
||||
{{#discriminator}}
|
||||
Class cls = JSON.getClassForElement(tree, {{classname}}.class);
|
||||
if (cls != null) {
|
||||
// When the OAS schema includes a discriminator, use the discriminator value to
|
||||
// discriminate the anyOf schemas.
|
||||
// Get the discriminator mapping value to get the class.
|
||||
deserialized = tree.traverse(jp.getCodec()).readValueAs(cls);
|
||||
{{classname}} ret = new {{classname}}();
|
||||
ret.setActualInstance(deserialized);
|
||||
return ret;
|
||||
}
|
||||
{{/discriminator}}
|
||||
{{#anyOf}}
|
||||
// deserialzie {{{.}}}
|
||||
try {
|
||||
@@ -48,6 +83,41 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
|
||||
{{/anyOf}}
|
||||
throw new IOException(String.format("Failed deserialization for {{classname}}: no match found"));
|
||||
}
|
||||
|
||||
{{#additionalPropertiesType}}
|
||||
/**
|
||||
* Method called to deal with a property that did not map to a known Bean property.
|
||||
* Method can deal with the problem as it sees fit (ignore, throw exception); but if it does return,
|
||||
* it has to skip the matching Json content parser has.
|
||||
*
|
||||
* @param p - Parser that points to value of the unknown property
|
||||
* @param ctxt - Context for deserialization; allows access to the parser, error reporting functionality
|
||||
* @param instanceOrClass - Instance that is being populated by this deserializer, or if not known, Class that would be instantiated. If null, will assume type is what getValueClass() returns.
|
||||
* @param propName - Name of the property that cannot be mapped
|
||||
*/
|
||||
@Override
|
||||
protected void handleUnknownProperty(JsonParser p,
|
||||
DeserializationContext ctxt,
|
||||
Object instanceOrClass,
|
||||
String propName) throws IOException {
|
||||
System.out.println("Deserializing unknown property " + propName);
|
||||
{{{.}}} deserialized = p.readValueAs({{{.}}}.class);
|
||||
additionalProperties.put(propName, deserialized);
|
||||
}
|
||||
{{/additionalPropertiesType}}
|
||||
|
||||
/**
|
||||
* Handle deserialization of the 'null' value.
|
||||
*/
|
||||
@Override
|
||||
public {{classname}} getNullValue(DeserializationContext ctxt) throws JsonMappingException {
|
||||
{{#isNullable}}
|
||||
return null;
|
||||
{{/isNullable}}
|
||||
{{^isNullable}}
|
||||
throw new JsonMappingException("{{classname}} cannot be null");
|
||||
{{/isNullable}}
|
||||
}
|
||||
}
|
||||
|
||||
// store a list of schema names defined in anyOf
|
||||
@@ -56,7 +126,18 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
|
||||
public {{classname}}() {
|
||||
super("anyOf", {{#isNullable}}Boolean.TRUE{{/isNullable}}{{^isNullable}}Boolean.FALSE{{/isNullable}});
|
||||
}
|
||||
{{> libraries/jersey2/additional_properties }}
|
||||
{{#additionalPropertiesType}}
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return super.equals(o) && Objects.equals(this.additionalProperties, o.additionalProperties)
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(instance, isNullable, schemaType, additionalProperties);
|
||||
}
|
||||
{{/additionalPropertiesType}}
|
||||
{{#anyOf}}
|
||||
public {{classname}}({{{.}}} o) {
|
||||
super("anyOf", {{#isNullable}}Boolean.TRUE{{/isNullable}}{{^isNullable}}Boolean.FALSE{{/isNullable}});
|
||||
@@ -69,6 +150,16 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
|
||||
schemas.put("{{{.}}}", new GenericType<{{{.}}}>() {
|
||||
});
|
||||
{{/anyOf}}
|
||||
JSON.registerDescendants({{classname}}.class, Collections.unmodifiableMap(schemas));
|
||||
{{#discriminator}}
|
||||
// Initialize and register the discriminator mappings.
|
||||
Map<String, Class> mappings = new HashMap<String, Class>();
|
||||
{{#mappedModels}}
|
||||
mappings.put("{{mappingName}}", {{modelName}}.class);
|
||||
{{/mappedModels}}
|
||||
mappings.put("{{name}}", {{classname}}.class);
|
||||
JSON.registerDiscriminator({{classname}}.class, "{{propertyBaseName}}", mappings);
|
||||
{{/discriminator}}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,15 +169,15 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
|
||||
|
||||
@Override
|
||||
public void setActualInstance(Object instance) {
|
||||
{{#isNulalble}}
|
||||
{{#isNullable}}
|
||||
if (instance == null) {
|
||||
super.setActualInstance(instance);
|
||||
return;
|
||||
}
|
||||
|
||||
{{/isNulalble}}
|
||||
{{/isNullable}}
|
||||
{{#anyOf}}
|
||||
if (instance instanceof {{{.}}}) {
|
||||
if (JSON.isInstanceOf({{{.}}}.class, instance, new HashSet<Class>())) {
|
||||
super.setActualInstance(instance);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ public class {{classname}} {
|
||||
{{/returnType}}
|
||||
return apiClient.invokeAPI("{{classname}}.{{operationId}}", localVarPath, "{{httpMethod}}", localVarQueryParams, localVarPostBody,
|
||||
localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAccept, localVarContentType,
|
||||
localVarAuthNames, {{#returnType}}localVarReturnType{{/returnType}}{{^returnType}}null{{/returnType}}, {{#vendorExtensions.x-java-return-type-one-of}}new {{{returnType}}}(){{/vendorExtensions.x-java-return-type-one-of}}{{^vendorExtensions.x-java-return-type-one-of}}{{#vendorExtensions.x-java-return-type-any-of}}new {{{returnType}}}(){{/vendorExtensions.x-java-return-type-any-of}}{{^vendorExtensions.x-java-return-type-any-of}}null{{/vendorExtensions.x-java-return-type-any-of}}{{/vendorExtensions.x-java-return-type-one-of}});
|
||||
localVarAuthNames, {{#returnType}}localVarReturnType{{/returnType}}{{^returnType}}null{{/returnType}});
|
||||
}
|
||||
{{#vendorExtensions.x-group-parameters}}
|
||||
|
||||
|
||||
@@ -6,9 +6,10 @@ import {{invokerPackage}}.*;
|
||||
import {{invokerPackage}}.auth.*;
|
||||
{{#imports}}import {{import}};
|
||||
{{/imports}}
|
||||
import org.junit.Test;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
{{^fullJavaUtil}}
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -6,9 +6,21 @@ package {{package}};
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
{{/useReflectionEqualsHashCode}}
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
{{#additionalPropertiesType}}
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
{{/additionalPropertiesType}}
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
{{^supportJava6}}
|
||||
import java.util.Objects;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
{{/supportJava6}}
|
||||
{{#supportJava6}}
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
@@ -39,9 +51,16 @@ import javax.validation.Valid;
|
||||
{{#performBeanValidation}}
|
||||
import org.hibernate.validator.constraints.*;
|
||||
{{/performBeanValidation}}
|
||||
import {{invokerPackage}}.JSON;
|
||||
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
{{#oneOf}}
|
||||
{{#-first}}
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
{{/-first}}
|
||||
{{/oneOf}}
|
||||
|
||||
{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{#oneOf}}{{#-first}}{{>oneof_model}}{{/-first}}{{/oneOf}}{{^oneOf}}{{#anyOf}}{{#-first}}{{>anyof_model}}{{/-first}}{{/anyOf}}{{^anyOf}}{{>pojo}}{{/anyOf}}{{/oneOf}}{{/isEnum}}
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
|
||||
@@ -4,21 +4,44 @@ import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
import org.openapitools.client.JSON;
|
||||
|
||||
{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{>xmlAnnotation}}
|
||||
@JsonDeserialize(using={{classname}}.{{classname}}Deserializer.class)
|
||||
@JsonDeserialize(using = {{classname}}.{{classname}}Deserializer.class)
|
||||
@JsonSerialize(using = {{classname}}.{{classname}}Serializer.class)
|
||||
public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-implements}}, {{{.}}}{{/vendorExtensions.x-implements}} {
|
||||
private static final Logger log = Logger.getLogger({{classname}}.class.getName());
|
||||
|
||||
public static class {{classname}}Serializer extends StdSerializer<{{classname}}> {
|
||||
public {{classname}}Serializer(Class<{{classname}}> t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
public {{classname}}Serializer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize({{classname}} value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
|
||||
jgen.writeObject(value.getActualInstance());
|
||||
}
|
||||
}
|
||||
|
||||
public static class {{classname}}Deserializer extends StdDeserializer<{{classname}}> {
|
||||
public {{classname}}Deserializer() {
|
||||
this({{classname}}.class);
|
||||
@@ -31,13 +54,33 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
|
||||
@Override
|
||||
public {{classname}} deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
|
||||
JsonNode tree = jp.readValueAsTree();
|
||||
|
||||
int match = 0;
|
||||
Object deserialized = null;
|
||||
{{#useOneOfDiscriminatorLookup}}
|
||||
{{#discriminator}}
|
||||
{{classname}} new{{classname}} = new {{classname}}();
|
||||
Map<String,Object> result2 = tree.traverse(jp.getCodec()).readValueAs(new TypeReference<Map<String, Object>>() {});
|
||||
String discriminatorValue = (String)result2.get("{{{propertyBaseName}}}");
|
||||
switch (discriminatorValue) {
|
||||
{{#mappedModels}}
|
||||
case "{{{mappingName}}}":
|
||||
deserialized = tree.traverse(jp.getCodec()).readValueAs({{{modelName}}}.class);
|
||||
new{{classname}}.setActualInstance(deserialized);
|
||||
return new{{classname}};
|
||||
{{/mappedModels}}
|
||||
default:
|
||||
log.log(Level.WARNING, String.format("Failed to lookup discriminator value `%s` for {{classname}}. Possible values:{{#mappedModels}} {{{mappingName}}}{{/mappedModels}}", discriminatorValue));
|
||||
}
|
||||
|
||||
{{/discriminator}}
|
||||
{{/useOneOfDiscriminatorLookup}}
|
||||
int match = 0;
|
||||
{{#oneOf}}
|
||||
// deserialize {{{.}}}
|
||||
try {
|
||||
deserialized = tree.traverse(jp.getCodec()).readValueAs({{{.}}}.class);
|
||||
// TODO: there is no validation against JSON schema constraints
|
||||
// (min, max, enum, pattern...), this does not perform a strict JSON
|
||||
// validation, which means the 'match' count may be higher than it should be.
|
||||
match++;
|
||||
log.log(Level.FINER, "Input data matches schema '{{{.}}}'");
|
||||
} catch (Exception e) {
|
||||
@@ -53,6 +96,41 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
|
||||
}
|
||||
throw new IOException(String.format("Failed deserialization for {{classname}}: %d classes match result, expected 1", match));
|
||||
}
|
||||
|
||||
{{#additionalPropertiesType}}
|
||||
/**
|
||||
* Method called to deal with a property that did not map to a known Bean property.
|
||||
* Method can deal with the problem as it sees fit (ignore, throw exception); but if it does return,
|
||||
* it has to skip the matching Json content parser has.
|
||||
*
|
||||
* @param p - Parser that points to value of the unknown property
|
||||
* @param ctxt - Context for deserialization; allows access to the parser, error reporting functionality
|
||||
* @param instanceOrClass - Instance that is being populated by this deserializer, or if not known, Class that would be instantiated. If null, will assume type is what getValueClass() returns.
|
||||
* @param propName - Name of the property that cannot be mapped
|
||||
*/
|
||||
@Override
|
||||
protected void handleUnknownProperty(JsonParser p,
|
||||
DeserializationContext ctxt,
|
||||
Object instanceOrClass,
|
||||
String propName) throws IOException {
|
||||
System.out.println("Deserializing unknown property " + propName);
|
||||
{{{.}}} deserialized = p.readValueAs({{{.}}}.class);
|
||||
additionalProperties.put(propName, deserialized);
|
||||
}
|
||||
{{/additionalPropertiesType}}
|
||||
|
||||
/**
|
||||
* Handle deserialization of the 'null' value.
|
||||
*/
|
||||
@Override
|
||||
public {{classname}} getNullValue(DeserializationContext ctxt) throws JsonMappingException {
|
||||
{{#isNullable}}
|
||||
return null;
|
||||
{{/isNullable}}
|
||||
{{^isNullable}}
|
||||
throw new JsonMappingException("{{classname}} cannot be null");
|
||||
{{/isNullable}}
|
||||
}
|
||||
}
|
||||
|
||||
// store a list of schema names defined in oneOf
|
||||
@@ -61,7 +139,18 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
|
||||
public {{classname}}() {
|
||||
super("oneOf", {{#isNullable}}Boolean.TRUE{{/isNullable}}{{^isNullable}}Boolean.FALSE{{/isNullable}});
|
||||
}
|
||||
{{> libraries/jersey2/additional_properties }}
|
||||
{{#additionalPropertiesType}}
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return super.equals(o) && Objects.equals(this.additionalProperties, o.additionalProperties)
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(instance, isNullable, schemaType, additionalProperties);
|
||||
}
|
||||
{{/additionalPropertiesType}}
|
||||
{{#oneOf}}
|
||||
public {{classname}}({{{.}}} o) {
|
||||
super("oneOf", {{#isNullable}}Boolean.TRUE{{/isNullable}}{{^isNullable}}Boolean.FALSE{{/isNullable}});
|
||||
@@ -74,6 +163,16 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
|
||||
schemas.put("{{{.}}}", new GenericType<{{{.}}}>() {
|
||||
});
|
||||
{{/oneOf}}
|
||||
JSON.registerDescendants({{classname}}.class, Collections.unmodifiableMap(schemas));
|
||||
{{#discriminator}}
|
||||
// Initialize and register the discriminator mappings.
|
||||
Map<String, Class> mappings = new HashMap<String, Class>();
|
||||
{{#mappedModels}}
|
||||
mappings.put("{{mappingName}}", {{modelName}}.class);
|
||||
{{/mappedModels}}
|
||||
mappings.put("{{name}}", {{classname}}.class);
|
||||
JSON.registerDiscriminator({{classname}}.class, "{{propertyBaseName}}", mappings);
|
||||
{{/discriminator}}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,17 +180,24 @@ public class {{classname}} extends AbstractOpenApiSchema{{#vendorExtensions.x-im
|
||||
return {{classname}}.schemas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the instance that matches the oneOf child schema, check
|
||||
* the instance parameter is valid against the oneOf child schemas.
|
||||
*
|
||||
* It could be an instance of the 'oneOf' schemas.
|
||||
* The oneOf child schemas may themselves be a composed schema (allOf, anyOf, oneOf).
|
||||
*/
|
||||
@Override
|
||||
public void setActualInstance(Object instance) {
|
||||
{{#isNulalble}}
|
||||
{{#isNullable}}
|
||||
if (instance == null) {
|
||||
super.setActualInstance(instance);
|
||||
return;
|
||||
}
|
||||
|
||||
{{/isNulalble}}
|
||||
{{/isNullable}}
|
||||
{{#oneOf}}
|
||||
if (instance instanceof {{{.}}}) {
|
||||
if (JSON.isInstanceOf({{{.}}}.class, instance, new HashSet<Class>())) {
|
||||
super.setActualInstance(instance);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -99,8 +99,12 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#vendorE
|
||||
|
||||
{{^isReadOnly}}
|
||||
public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) {
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}this.{{name}} = JsonNullable.<{{{datatypeWithEnum}}}>of({{name}});{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}this.{{name}} = {{name}};{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{#vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
this.{{name}} = JsonNullable.<{{{datatypeWithEnum}}}>of({{name}});
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
{{^vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
this.{{name}} = {{name}};
|
||||
{{/vendorExtensions.x-is-jackson-optional-nullable}}
|
||||
return this;
|
||||
}
|
||||
{{#isListContainer}}
|
||||
@@ -226,7 +230,7 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#vendorE
|
||||
{{/isReadOnly}}
|
||||
|
||||
{{/vars}}
|
||||
|
||||
{{>libraries/jersey2/additional_properties}}
|
||||
{{^supportJava6}}
|
||||
@Override
|
||||
public boolean equals(java.lang.Object o) {
|
||||
@@ -242,7 +246,8 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#vendorE
|
||||
}{{#hasVars}}
|
||||
{{classname}} {{classVarName}} = ({{classname}}) o;
|
||||
return {{#vars}}{{#isByteArray}}Arrays{{/isByteArray}}{{^isByteArray}}Objects{{/isByteArray}}.equals(this.{{name}}, {{classVarName}}.{{name}}){{#hasMore}} &&
|
||||
{{/hasMore}}{{/vars}}{{#parent}} &&
|
||||
{{/hasMore}}{{/vars}}{{#additionalPropertiesType}}&&
|
||||
Objects.equals(this.additionalProperties, {{classVarName}}.additionalProperties){{/additionalPropertiesType}}{{#parent}} &&
|
||||
super.equals(o){{/parent}};{{/hasVars}}{{^hasVars}}
|
||||
return {{#parent}}super.equals(o){{/parent}}{{^parent}}true{{/parent}};{{/hasVars}}
|
||||
{{/useReflectionEqualsHashCode}}
|
||||
@@ -254,7 +259,7 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#vendorE
|
||||
return HashCodeBuilder.reflectionHashCode(this);
|
||||
{{/useReflectionEqualsHashCode}}
|
||||
{{^useReflectionEqualsHashCode}}
|
||||
return Objects.hash({{#vars}}{{^isByteArray}}{{name}}{{/isByteArray}}{{#isByteArray}}Arrays.hashCode({{name}}){{/isByteArray}}{{#hasMore}}, {{/hasMore}}{{/vars}}{{#parent}}{{#hasVars}}, {{/hasVars}}super.hashCode(){{/parent}});
|
||||
return Objects.hash({{#vars}}{{^isByteArray}}{{name}}{{/isByteArray}}{{#isByteArray}}Arrays.hashCode({{name}}){{/isByteArray}}{{#hasMore}}, {{/hasMore}}{{/vars}}{{#parent}}{{#hasVars}}, {{/hasVars}}super.hashCode(){{/parent}}{{#additionalPropertiesType}}, additionalProperties{{/additionalPropertiesType}});
|
||||
{{/useReflectionEqualsHashCode}}
|
||||
}
|
||||
|
||||
@@ -292,6 +297,9 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#vendorE
|
||||
{{#vars}}
|
||||
sb.append(" {{name}}: ").append(toIndentedString({{name}})).append("\n");
|
||||
{{/vars}}
|
||||
{{#additionalPropertiesType}}
|
||||
sb.append(" additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n");
|
||||
{{/additionalPropertiesType}}
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
@@ -366,4 +374,15 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#vendorE
|
||||
}
|
||||
};
|
||||
{{/parcelableModel}}
|
||||
{{#discriminator}}
|
||||
static {
|
||||
// Initialize and register the discriminator mappings.
|
||||
Map<String, Class> mappings = new HashMap<String, Class>();
|
||||
{{#mappedModels}}
|
||||
mappings.put("{{mappingName}}", {{modelName}}.class);
|
||||
{{/mappedModels}}
|
||||
mappings.put("{{name}}", {{classname}}.class);
|
||||
JSON.registerDiscriminator({{classname}}.class, "{{propertyBaseName}}", mappings);
|
||||
}
|
||||
{{/discriminator}}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
<argLine>-Xms512m -Xmx1500m</argLine>
|
||||
<parallel>methods</parallel>
|
||||
<threadCount>10</threadCount>
|
||||
<trimStackTrace>false</trimStackTrace>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
|
||||
Reference in New Issue
Block a user