diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java index 118de425c93..6b0dd68e9fb 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java @@ -17,6 +17,7 @@ public class CodegenModel { // References to parent and interface CodegenModels. Only set when code generator supports inheritance. public CodegenModel parentModel; public List interfaceModels; + public List children; public String name, classname, title, description, classVarName, modelJson, dataType; public String classFilename; // store the class file name, mainly used for import diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java index 5ccc9b24945..c5554f7a66f 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java @@ -180,6 +180,18 @@ public Map postProcessAllModels(Map objs) { } } } + // Let parent know about all its children + for (String name : allModels.keySet()) { + CodegenModel cm = allModels.get(name); + CodegenModel parent = allModels.get(cm.parent); + while (parent != null) { + if (parent.children == null) { + parent.children = new ArrayList(); + } + parent.children.add(cm); + parent = allModels.get(parent.parent); + } + } } return objs; } diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractJavaCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractJavaCodegen.java index 5327a4e84cc..6e90afaf61a 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractJavaCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractJavaCodegen.java @@ -253,6 +253,8 @@ public void processOpts() { importMapping.put("ApiModelProperty", "io.swagger.annotations.ApiModelProperty"); importMapping.put("ApiModel", "io.swagger.annotations.ApiModel"); importMapping.put("JsonProperty", "com.fasterxml.jackson.annotation.JsonProperty"); + importMapping.put("JsonSubTypes", "com.fasterxml.jackson.annotation.JsonSubTypes"); + importMapping.put("JsonTypeInfo", "com.fasterxml.jackson.annotation.JsonTypeInfo"); importMapping.put("JsonCreator", "com.fasterxml.jackson.annotation.JsonCreator"); importMapping.put("JsonValue", "com.fasterxml.jackson.annotation.JsonValue"); importMapping.put("SerializedName", "com.google.gson.annotations.SerializedName"); @@ -628,6 +630,10 @@ public CodegenModel fromModel(String name, Model model, Map allDe if(codegenModel.description != null) { codegenModel.imports.add("ApiModel"); } + if (codegenModel.discriminator != null && additionalProperties.containsKey("jackson")) { + codegenModel.imports.add("JsonSubTypes"); + codegenModel.imports.add("JsonTypeInfo"); + } if (allDefinitions != null && codegenModel.parentSchema != null && codegenModel.hasEnums) { final Model parentModel = allDefinitions.get(codegenModel.parentSchema); final CodegenModel parentCodegenModel = super.fromModel(codegenModel.parent, parentModel); diff --git a/modules/swagger-codegen/src/main/resources/Java/pojo.mustache b/modules/swagger-codegen/src/main/resources/Java/pojo.mustache index 408c6dbe645..c522bdba860 100644 --- a/modules/swagger-codegen/src/main/resources/Java/pojo.mustache +++ b/modules/swagger-codegen/src/main/resources/Java/pojo.mustache @@ -2,7 +2,7 @@ * {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}} */{{#description}} @ApiModel(description = "{{{description}}}"){{/description}} -{{>generatedAnnotation}} +{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}} public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#parcelableModel}}implements Parcelable {{#serializableModel}}, Serializable {{/serializableModel}}{{/parcelableModel}}{{^parcelableModel}}{{#serializableModel}}implements Serializable {{/serializableModel}}{{/parcelableModel}}{ {{#vars}} {{#isEnum}} diff --git a/modules/swagger-codegen/src/main/resources/Java/typeInfoAnnotation.mustache b/modules/swagger-codegen/src/main/resources/Java/typeInfoAnnotation.mustache new file mode 100644 index 00000000000..6ef9431ff60 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Java/typeInfoAnnotation.mustache @@ -0,0 +1,5 @@ +{{#jackson}} +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{discriminator}}" ) +@JsonSubTypes({ + {{#children}}@JsonSubTypes.Type(value = {{name}}.class, name = "{{name}}"),{{/children}} +}){{/jackson}} \ No newline at end of file diff --git a/samples/client/petstore/java/feign/src/main/java/io/swagger/client/model/Animal.java b/samples/client/petstore/java/feign/src/main/java/io/swagger/client/model/Animal.java index 485734d526c..8fc61b6891a 100644 --- a/samples/client/petstore/java/feign/src/main/java/io/swagger/client/model/Animal.java +++ b/samples/client/petstore/java/feign/src/main/java/io/swagger/client/model/Animal.java @@ -16,13 +16,18 @@ import java.util.Objects; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; /** * Animal */ - +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className" ) +@JsonSubTypes({ + @JsonSubTypes.Type(value = Dog.class, name = "Dog"),@JsonSubTypes.Type(value = Cat.class, name = "Cat"), +}) public class Animal { @JsonProperty("className") private String className = null; diff --git a/samples/client/petstore/java/jersey1/src/main/java/io/swagger/client/model/Animal.java b/samples/client/petstore/java/jersey1/src/main/java/io/swagger/client/model/Animal.java index 485734d526c..8fc61b6891a 100644 --- a/samples/client/petstore/java/jersey1/src/main/java/io/swagger/client/model/Animal.java +++ b/samples/client/petstore/java/jersey1/src/main/java/io/swagger/client/model/Animal.java @@ -16,13 +16,18 @@ import java.util.Objects; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; /** * Animal */ - +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className" ) +@JsonSubTypes({ + @JsonSubTypes.Type(value = Dog.class, name = "Dog"),@JsonSubTypes.Type(value = Cat.class, name = "Cat"), +}) public class Animal { @JsonProperty("className") private String className = null; diff --git a/samples/client/petstore/java/jersey2-java8/src/main/java/io/swagger/client/RFC3339DateFormat.java b/samples/client/petstore/java/jersey2-java8/src/main/java/io/swagger/client/RFC3339DateFormat.java new file mode 100644 index 00000000000..e8df24310aa --- /dev/null +++ b/samples/client/petstore/java/jersey2-java8/src/main/java/io/swagger/client/RFC3339DateFormat.java @@ -0,0 +1,32 @@ +/* + * Swagger Petstore + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ + * + * OpenAPI spec version: 1.0.0 + * Contact: apiteam@swagger.io + * + * NOTE: This class is auto generated by the swagger code generator program. + * https://github.com/swagger-api/swagger-codegen.git + * Do not edit the class manually. + */ + +package io.swagger.client; + +import com.fasterxml.jackson.databind.util.ISO8601DateFormat; +import com.fasterxml.jackson.databind.util.ISO8601Utils; + +import java.text.FieldPosition; +import java.util.Date; + + +public class RFC3339DateFormat extends ISO8601DateFormat { + + // Same as ISO8601DateFormat but serializing milliseconds. + @Override + public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) { + String value = ISO8601Utils.format(date, true); + toAppendTo.append(value); + return toAppendTo; + } + +} \ No newline at end of file diff --git a/samples/client/petstore/java/jersey2-java8/src/main/java/io/swagger/client/model/Animal.java b/samples/client/petstore/java/jersey2-java8/src/main/java/io/swagger/client/model/Animal.java index 485734d526c..8fc61b6891a 100644 --- a/samples/client/petstore/java/jersey2-java8/src/main/java/io/swagger/client/model/Animal.java +++ b/samples/client/petstore/java/jersey2-java8/src/main/java/io/swagger/client/model/Animal.java @@ -16,13 +16,18 @@ import java.util.Objects; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; /** * Animal */ - +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className" ) +@JsonSubTypes({ + @JsonSubTypes.Type(value = Dog.class, name = "Dog"),@JsonSubTypes.Type(value = Cat.class, name = "Cat"), +}) public class Animal { @JsonProperty("className") private String className = null; diff --git a/samples/client/petstore/java/jersey2/src/main/java/io/swagger/client/model/Animal.java b/samples/client/petstore/java/jersey2/src/main/java/io/swagger/client/model/Animal.java index 485734d526c..8fc61b6891a 100644 --- a/samples/client/petstore/java/jersey2/src/main/java/io/swagger/client/model/Animal.java +++ b/samples/client/petstore/java/jersey2/src/main/java/io/swagger/client/model/Animal.java @@ -16,13 +16,18 @@ import java.util.Objects; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; /** * Animal */ - +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "className" ) +@JsonSubTypes({ + @JsonSubTypes.Type(value = Dog.class, name = "Dog"),@JsonSubTypes.Type(value = Cat.class, name = "Cat"), +}) public class Animal { @JsonProperty("className") private String className = null;