From ca3097b67bce559fc728bb2680f64d0da4fe4274 Mon Sep 17 00:00:00 2001 From: Timo Rohrberg Date: Sat, 15 Feb 2020 18:42:18 +0100 Subject: [PATCH] #602 Generated code does not implement model inheritance correctly Fix handling of composed models and adjustments to model.mustache and typeInfoAnnotation.mustache templates to correctly generate models with inheritance structure. --- .../v3/generators/java/SpringCodegen.java | 61 +++++++++++++++++-- .../handlebars/JavaSpring/model.mustache | 12 ++-- .../JavaSpring/typeInfoAnnotation.mustache | 15 +++-- 3 files changed, 73 insertions(+), 15 deletions(-) diff --git a/src/main/java/io/swagger/codegen/v3/generators/java/SpringCodegen.java b/src/main/java/io/swagger/codegen/v3/generators/java/SpringCodegen.java index b8e3fff9ae..579c05bee4 100644 --- a/src/main/java/io/swagger/codegen/v3/generators/java/SpringCodegen.java +++ b/src/main/java/io/swagger/codegen/v3/generators/java/SpringCodegen.java @@ -15,6 +15,7 @@ import io.swagger.codegen.v3.SupportingFile; import io.swagger.codegen.v3.generators.features.BeanValidationFeatures; import io.swagger.codegen.v3.generators.features.OptionalFeatures; +import io.swagger.codegen.v3.generators.util.OpenAPIUtil; import io.swagger.codegen.v3.utils.URLPathUtil; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; @@ -27,11 +28,7 @@ import java.io.IOException; import java.io.Writer; import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.regex.Matcher; import java.util.stream.Collectors; @@ -792,6 +789,60 @@ public void postProcessModelProperty(CodegenModel model, CodegenProperty propert } } + @Override + public Map postProcessAllModels(Map objs) { + Map allProcessedModels = super.postProcessAllModels(objs); + + List allModels = new ArrayList(); + for (String name: allProcessedModels.keySet()) { + Map models = (Map)allProcessedModels.get(name); + try { + allModels.add(((List) models.get("models")).get(0)); + } catch (Exception e){ + e.printStackTrace(); + } + } + + additionalProperties.put("parent", modelInheritanceSupport(allModels)); + + return allProcessedModels; + } + + protected List> modelInheritanceSupport(List allModels) { + Map> byParent = new LinkedHashMap<>(); + for (Object model : allModels) { + Map entry = (Map) model; + CodegenModel parent = ((CodegenModel)entry.get("model")).parentModel; + if(null!= parent) { + byParent.computeIfAbsent(parent, k -> new LinkedList<>()).add((CodegenModel)entry.get("model")); + } + } + + List> parentsList = new ArrayList<>(); + for (Map.Entry> parentModelEntry : byParent.entrySet()) { + CodegenModel parentModel = parentModelEntry.getKey(); + List> childrenList = new ArrayList<>(); + Map parent = new HashMap<>(); + parent.put("classname", parentModel.classname); + List childrenModels = byParent.get(parentModel); + for (CodegenModel model : childrenModels) { + Map child = new HashMap<>(); + child.put("name", model.name); + child.put("classname", model.classname); + childrenList.add(child); + } + parent.put("children", childrenList); + parent.put("discriminator", parentModel.discriminator); + if(parentModel.discriminator != null && parentModel.discriminator.getMapping() != null) + { + parentModel.discriminator.getMapping().replaceAll((key, value) -> OpenAPIUtil.getSimpleRef(value)); + } + parentsList.add(parent); + } + + return parentsList; + } + @Override public Map postProcessModelsEnum(Map objs) { objs = super.postProcessModelsEnum(objs); diff --git a/src/main/resources/handlebars/JavaSpring/model.mustache b/src/main/resources/handlebars/JavaSpring/model.mustache index 4c471ff2b7..c61051f0b5 100644 --- a/src/main/resources/handlebars/JavaSpring/model.mustache +++ b/src/main/resources/handlebars/JavaSpring/model.mustache @@ -1,6 +1,6 @@ package {{package}}; -{{^x-is-composed-model}} +{{^isComposedModel}} import java.util.Objects; {{#imports}}import {{import}}; {{/imports}} @@ -21,20 +21,20 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; {{#withXml}} import javax.xml.bind.annotation.*; {{/withXml}} -{{/x-is-composed-model}} +{{/isComposedModel}} {{#models}} {{#model}} -{{#vendorExtensions.x-is-composed-model}} +{{#isComposedModel}} {{>interface}} -{{/vendorExtensions.x-is-composed-model}} -{{^vendorExtensions.x-is-composed-model}} +{{/isComposedModel}} +{{^isComposedModel}} {{#isEnum}} {{>enumOuterClass}} {{/isEnum}} {{^isEnum}} {{>pojo}} {{/isEnum}} -{{/vendorExtensions.x-is-composed-model}} +{{/isComposedModel}} {{/model}} {{/models}} diff --git a/src/main/resources/handlebars/JavaSpring/typeInfoAnnotation.mustache b/src/main/resources/handlebars/JavaSpring/typeInfoAnnotation.mustache index f2a2e1c88f..f3ed515976 100644 --- a/src/main/resources/handlebars/JavaSpring/typeInfoAnnotation.mustache +++ b/src/main/resources/handlebars/JavaSpring/typeInfoAnnotation.mustache @@ -1,7 +1,14 @@ {{#jackson}} @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{discriminator.propertyName}}", visible = true ) @JsonSubTypes({ - {{#children}} - @JsonSubTypes.Type(value = {{classname}}.class, name = "{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}"), - {{/children}} -}){{/jackson}} + {{#if discriminator.mapping}} + {{#each discriminator.mapping}} + @JsonSubTypes.Type(value = {{this}}.class, name = "{{@key}}"), + {{/each}} + {{else}} + {{#children}} + @JsonSubTypes.Type(value = {{classname}}.class, name = "{{name}}"), + {{/children}} + {{/if}} +}) +{{/jackson}} \ No newline at end of file