From 6a8769e83c9f866769c5fb73a7fd21d1b577b93a Mon Sep 17 00:00:00 2001 From: Alexej Date: Sat, 21 Mar 2020 23:33:15 +0100 Subject: [PATCH 01/25] Fix OpenAPITools#5381 added x-is-one-of-interface extension for oneOf interface in mustache template --- .../codegen/languages/SpringCodegen.java | 125 +++++++++++++++++- .../main/resources/JavaSpring/model.mustache | 2 +- .../JavaSpring/oneof_interface.mustache | 6 + 3 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java index 8450fbd5f4de..6c02e6553c23 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java @@ -21,6 +21,10 @@ import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.PathItem; +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 org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.openapitools.codegen.*; import org.openapitools.codegen.languages.features.BeanValidationFeatures; @@ -29,6 +33,8 @@ import org.openapitools.codegen.meta.features.*; import org.openapitools.codegen.templating.mustache.SplitStringLambda; import org.openapitools.codegen.templating.mustache.TrimWhitespaceLambda; +import org.openapitools.codegen.utils.ModelUtils; +import org.openapitools.codegen.utils.OneOfImplementorAdditionalData; import org.openapitools.codegen.utils.URLPathUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -233,7 +239,7 @@ public void processOpts() { } super.processOpts(); - + useOneOfInterfaces = true; // clear model and api doc template as this codegen // does not support auto-generated markdown doc at the moment //TODO: add doc templates @@ -523,6 +529,58 @@ public void addOperationToGroup(String tag, String resourcePath, Operation opera } } + @Override + public void addOneOfInterfaceModel(ComposedSchema cs, String name) { + CodegenModel codegenModel = new CodegenModel(); + + for (Schema o : cs.getOneOf()) { + codegenModel.oneOf.add(toModelName(ModelUtils.getSimpleRef(o.get$ref()))); + } + codegenModel.name = name; + codegenModel.classname = name; + codegenModel.vendorExtensions.put("isOneOfInterface", true); + codegenModel.discriminator = createDiscriminator("", (Schema) cs); + codegenModel.interfaceModels = new ArrayList(); + + for(Schema schema : cs.getOneOf()){ + String[] split = schema.get$ref().split("/"); + String singleSchemaType = split[split.length-1]; + CodegenProperty codegenProperty = fromProperty(singleSchemaType, schema); + codegenProperty.setBaseName(singleSchemaType.toLowerCase(Locale.getDefault())); + codegenModel.vars.add(codegenProperty); + } + addOneOfInterfaces.add(codegenModel); + } + + @Override + public CodegenParameter fromRequestBody(RequestBody body, Set imports, String bodyParameterName) { + CodegenParameter codegenParameter = super.fromRequestBody(body, imports, bodyParameterName); + Schema schema = ModelUtils.getSchemaFromRequestBody(body); + CodegenProperty codegenProperty = fromProperty("property", schema); + + List oneOfClassNames = new ArrayList<>(); + if (codegenProperty != null && codegenProperty.getComplexType() != null && schema instanceof ComposedSchema) { + // will be set with imports.add(codegenParameter.baseType); in defaultcodegen + imports.clear(); + ComposedSchema composedSchema = (ComposedSchema) schema; + for(Schema oneOfSchema: composedSchema.getOneOf()){ + String[] split = oneOfSchema.get$ref().split("/"); + oneOfClassNames.add(split[split.length - 1]); + } + String codegenModelName = createOneOfClassName(oneOfClassNames); + imports.add(codegenModelName); + codegenParameter.baseName = codegenModelName; + codegenParameter.paramName = toParamName(codegenParameter.baseName); + codegenParameter.baseType = codegenParameter.baseName; + codegenParameter.dataType = getTypeDeclaration(codegenModelName); + codegenParameter.description = codegenProperty.getDescription(); + codegenProperty.setComplexType(codegenModelName); + codegenProperty.setBaseName(codegenModelName); + codegenProperty.setDatatype(codegenModelName); + } + return codegenParameter; + } + @Override public void preprocessOpenAPI(OpenAPI openAPI) { super.preprocessOpenAPI(openAPI); @@ -629,6 +687,57 @@ public void setReturnContainer(final String returnContainer) { return objs; } + @Override + public Map postProcessAllModels(Map objs) { + super.postProcessAllModels(objs); + Map additionalDataMap = new HashMap<>(); + for (Map.Entry modelsEntry : objs.entrySet()) { + Map modelsAttrs = (Map) modelsEntry.getValue(); + List models = (List) modelsAttrs.get("models"); + List> modelsImports = (List>) modelsAttrs + .getOrDefault("imports", new ArrayList>()); + for (Object _mo : models) { + Map mo = (Map) _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 classToImport : Arrays + .asList("JsonTypeInfo", "JsonSubTypes", "JsonProperty", + "ApiModelProperty")) { + Map i = new HashMap() {{ + put("import", importMapping.get(classToImport)); + }}; + if (!modelsImports.contains(i)) { + modelsImports.add(i); + } + } + List oneOfClassNames = new ArrayList<>(); + + for (String one : cm.oneOf) { + if (!additionalDataMap.containsKey(one)) { + additionalDataMap.put(one, new OneOfImplementorAdditionalData(one)); + additionalDataMap.get(one).addFromInterfaceModel(cm, modelsImports); + } + oneOfClassNames.add(one); + } + String codegenModelName = createOneOfClassName(oneOfClassNames); + cm.name = codegenModelName; + cm.classname = codegenModelName; + Object value = modelsEntry.getValue(); + objs.remove(modelsEntry.getKey()); + objs.put(codegenModelName, value); + } + } + } + return objs; + } + + private String createOneOfClassName(List oneOfClassNames) { + oneOfClassNames.sort(String::compareToIgnoreCase); + return "OneOf" + StringUtils.join(oneOfClassNames, ""); + } + private interface DataTypeAssigner { void setReturnType(String returnType); @@ -898,4 +1007,16 @@ public void postProcessParameter(CodegenParameter p) { } } -} + @Override + public void addImportsToOneOfInterface(List> imports) { + for (String i : Arrays.asList("JsonSubTypes", "JsonTypeInfo")) { + Map oneImport = new HashMap() {{ + put("import", importMapping.get(i)); + }}; + if (!imports.contains(oneImport)) { + imports.add(oneImport); + } + } + } + +} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/model.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/model.mustache index fbe3a9f1445d..3eadeffb3ace 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/model.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/model.mustache @@ -35,7 +35,7 @@ import org.springframework.hateoas.RepresentationModel; {{>enumOuterClass}} {{/isEnum}} {{^isEnum}} -{{>pojo}} + {{#vendorExtensions.x-is-one-of-interface}}{{>oneof_interface}}{{/vendorExtensions.x-is-one-of-interface}}{{^vendorExtensions.x-is-one-of-interface}}{{>pojo}}{{/vendorExtensions.x-is-one-of-interface}} {{/isEnum}} {{/model}} {{/models}} diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache new file mode 100644 index 000000000000..02deb483d5fd --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache @@ -0,0 +1,6 @@ +{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{>typeInfoAnnotation}}{{>xmlAnnotation}} +public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} { + {{#discriminator}} + public {{propertyType}} {{propertyGetter}}(); + {{/discriminator}} +} From 049359cded127c14c689f12921f36f544117c771 Mon Sep 17 00:00:00 2001 From: Alexej Date: Sun, 22 Mar 2020 09:06:32 +0100 Subject: [PATCH 02/25] Fix OpenAPITools#5381 fixed name of model from UNKNOWN_BASE_TYPE to right one in api: operationId + OneOf Fix OpenAPITools#5381 parcelableModel is not required --- .../main/java/org/openapitools/codegen/DefaultCodegen.java | 5 ++++- .../org/openapitools/codegen/languages/SpringCodegen.java | 6 ------ .../src/main/resources/JavaSpring/model.mustache | 2 +- .../src/main/resources/JavaSpring/oneof_interface.mustache | 2 +- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 2e5f4f405366..9dfce5afc65e 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -5425,6 +5425,9 @@ public CodegenParameter fromRequestBody(RequestBody body, Set imports, S LOGGER.warn("codegenModel is null. Default to UNKNOWN_BASE_TYPE"); codegenModelName = "UNKNOWN_BASE_TYPE"; codegenModelDescription = "UNKNOWN_DESCRIPTION"; + if (useOneOfInterfaces && templateDir.equals("JavaSpring")){ + codegenModelName = codegenProperty.getComplexType()+"OneOf"; + } } if (StringUtils.isEmpty(bodyParameterName)) { @@ -5439,7 +5442,7 @@ public CodegenParameter fromRequestBody(RequestBody body, Set imports, S codegenParameter.description = codegenModelDescription; imports.add(codegenParameter.baseType); - if (codegenProperty.complexType != null) { + if (codegenProperty.complexType != null && (useOneOfInterfaces && !templateDir.equals("JavaSpring"))) { imports.add(codegenProperty.complexType); } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java index 6c02e6553c23..272b87a3b534 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java @@ -21,10 +21,6 @@ import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.PathItem; -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 org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.openapitools.codegen.*; import org.openapitools.codegen.languages.features.BeanValidationFeatures; @@ -33,8 +29,6 @@ import org.openapitools.codegen.meta.features.*; import org.openapitools.codegen.templating.mustache.SplitStringLambda; import org.openapitools.codegen.templating.mustache.TrimWhitespaceLambda; -import org.openapitools.codegen.utils.ModelUtils; -import org.openapitools.codegen.utils.OneOfImplementorAdditionalData; import org.openapitools.codegen.utils.URLPathUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/model.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/model.mustache index 3eadeffb3ace..d412a1224e04 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/model.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/model.mustache @@ -35,7 +35,7 @@ import org.springframework.hateoas.RepresentationModel; {{>enumOuterClass}} {{/isEnum}} {{^isEnum}} - {{#vendorExtensions.x-is-one-of-interface}}{{>oneof_interface}}{{/vendorExtensions.x-is-one-of-interface}}{{^vendorExtensions.x-is-one-of-interface}}{{>pojo}}{{/vendorExtensions.x-is-one-of-interface}} +{{#vendorExtensions.x-is-one-of-interface}}{{>oneof_interface}}{{/vendorExtensions.x-is-one-of-interface}}{{^vendorExtensions.x-is-one-of-interface}}{{>pojo}}{{/vendorExtensions.x-is-one-of-interface}} {{/isEnum}} {{/model}} {{/models}} diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache index 02deb483d5fd..4500871766c1 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache @@ -3,4 +3,4 @@ public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}exte {{#discriminator}} public {{propertyType}} {{propertyGetter}}(); {{/discriminator}} -} +} \ No newline at end of file From 49f13ebc30340ff78d6e4a8459ead453015c5c22 Mon Sep 17 00:00:00 2001 From: Alexej Date: Sun, 22 Mar 2020 11:18:19 +0100 Subject: [PATCH 03/25] Fix OpenAPITools#5381 removed not needed methods --- .../codegen/languages/SpringCodegen.java | 103 ------------------ 1 file changed, 103 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java index 272b87a3b534..cad6828cd3fd 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java @@ -523,58 +523,6 @@ public void addOperationToGroup(String tag, String resourcePath, Operation opera } } - @Override - public void addOneOfInterfaceModel(ComposedSchema cs, String name) { - CodegenModel codegenModel = new CodegenModel(); - - for (Schema o : cs.getOneOf()) { - codegenModel.oneOf.add(toModelName(ModelUtils.getSimpleRef(o.get$ref()))); - } - codegenModel.name = name; - codegenModel.classname = name; - codegenModel.vendorExtensions.put("isOneOfInterface", true); - codegenModel.discriminator = createDiscriminator("", (Schema) cs); - codegenModel.interfaceModels = new ArrayList(); - - for(Schema schema : cs.getOneOf()){ - String[] split = schema.get$ref().split("/"); - String singleSchemaType = split[split.length-1]; - CodegenProperty codegenProperty = fromProperty(singleSchemaType, schema); - codegenProperty.setBaseName(singleSchemaType.toLowerCase(Locale.getDefault())); - codegenModel.vars.add(codegenProperty); - } - addOneOfInterfaces.add(codegenModel); - } - - @Override - public CodegenParameter fromRequestBody(RequestBody body, Set imports, String bodyParameterName) { - CodegenParameter codegenParameter = super.fromRequestBody(body, imports, bodyParameterName); - Schema schema = ModelUtils.getSchemaFromRequestBody(body); - CodegenProperty codegenProperty = fromProperty("property", schema); - - List oneOfClassNames = new ArrayList<>(); - if (codegenProperty != null && codegenProperty.getComplexType() != null && schema instanceof ComposedSchema) { - // will be set with imports.add(codegenParameter.baseType); in defaultcodegen - imports.clear(); - ComposedSchema composedSchema = (ComposedSchema) schema; - for(Schema oneOfSchema: composedSchema.getOneOf()){ - String[] split = oneOfSchema.get$ref().split("/"); - oneOfClassNames.add(split[split.length - 1]); - } - String codegenModelName = createOneOfClassName(oneOfClassNames); - imports.add(codegenModelName); - codegenParameter.baseName = codegenModelName; - codegenParameter.paramName = toParamName(codegenParameter.baseName); - codegenParameter.baseType = codegenParameter.baseName; - codegenParameter.dataType = getTypeDeclaration(codegenModelName); - codegenParameter.description = codegenProperty.getDescription(); - codegenProperty.setComplexType(codegenModelName); - codegenProperty.setBaseName(codegenModelName); - codegenProperty.setDatatype(codegenModelName); - } - return codegenParameter; - } - @Override public void preprocessOpenAPI(OpenAPI openAPI) { super.preprocessOpenAPI(openAPI); @@ -681,57 +629,6 @@ public void setReturnContainer(final String returnContainer) { return objs; } - @Override - public Map postProcessAllModels(Map objs) { - super.postProcessAllModels(objs); - Map additionalDataMap = new HashMap<>(); - for (Map.Entry modelsEntry : objs.entrySet()) { - Map modelsAttrs = (Map) modelsEntry.getValue(); - List models = (List) modelsAttrs.get("models"); - List> modelsImports = (List>) modelsAttrs - .getOrDefault("imports", new ArrayList>()); - for (Object _mo : models) { - Map mo = (Map) _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 classToImport : Arrays - .asList("JsonTypeInfo", "JsonSubTypes", "JsonProperty", - "ApiModelProperty")) { - Map i = new HashMap() {{ - put("import", importMapping.get(classToImport)); - }}; - if (!modelsImports.contains(i)) { - modelsImports.add(i); - } - } - List oneOfClassNames = new ArrayList<>(); - - for (String one : cm.oneOf) { - if (!additionalDataMap.containsKey(one)) { - additionalDataMap.put(one, new OneOfImplementorAdditionalData(one)); - additionalDataMap.get(one).addFromInterfaceModel(cm, modelsImports); - } - oneOfClassNames.add(one); - } - String codegenModelName = createOneOfClassName(oneOfClassNames); - cm.name = codegenModelName; - cm.classname = codegenModelName; - Object value = modelsEntry.getValue(); - objs.remove(modelsEntry.getKey()); - objs.put(codegenModelName, value); - } - } - } - return objs; - } - - private String createOneOfClassName(List oneOfClassNames) { - oneOfClassNames.sort(String::compareToIgnoreCase); - return "OneOf" + StringUtils.join(oneOfClassNames, ""); - } - private interface DataTypeAssigner { void setReturnType(String returnType); From 1a5a48490c44821e33bd76eca0985502df0b7f57 Mon Sep 17 00:00:00 2001 From: Alexej Date: Sun, 22 Mar 2020 12:03:38 +0100 Subject: [PATCH 04/25] Fix OpenAPITools#5381 catch NPE cases in preprocessOpenAPI updated samples --- .../org/openapitools/codegen/DefaultCodegen.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 9dfce5afc65e..2f0768bb3859 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -710,7 +710,7 @@ public void postProcessParameter(CodegenParameter parameter) { //override with any special handling of the entire OpenAPI spec document @SuppressWarnings("unused") public void preprocessOpenAPI(OpenAPI openAPI) { - if (useOneOfInterfaces) { + if (useOneOfInterfaces && openAPI.getComponents() != null) { // we process the openapi schema here to find oneOf schemas and create interface models for them Map schemas = new HashMap(openAPI.getComponents().getSchemas()); if (schemas == null) { @@ -733,11 +733,13 @@ public void preprocessOpenAPI(OpenAPI openAPI) { schemas.put(opId, requestSchema); } // process all response bodies - for (Map.Entry 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); + if (op.getValue().getResponses() != null){ + for (Map.Entry 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); + } } } } From 48a1a4a71737d187c74d1627d6a40c8b66cc0018 Mon Sep 17 00:00:00 2001 From: Alexej Date: Tue, 24 Mar 2020 22:14:59 +0100 Subject: [PATCH 05/25] Fix OpenAPITools#5381 fixed generation of oneOf Models --- .../src/main/java/org/openapitools/codegen/DefaultCodegen.java | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 2f0768bb3859..e9d57285f03a 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -753,6 +753,7 @@ public void preprocessOpenAPI(OpenAPI openAPI) { String nOneOf = toModelName(n + "OneOf"); if (ModelUtils.isComposedSchema(s)) { addOneOfNameExtension((ComposedSchema) s, n); + addOneOfInterfaceModel((ComposedSchema) s, nOneOf); } else if (ModelUtils.isArraySchema(s)) { Schema items = ((ArraySchema) s).getItems(); if (ModelUtils.isComposedSchema(items)) { From a8113301b983b42d5b26ca073b70fe9291260fbb Mon Sep 17 00:00:00 2001 From: Alexej Date: Tue, 24 Mar 2020 23:18:48 +0100 Subject: [PATCH 06/25] Fix OpenAPITools#5381 addOneOfInterfaceModel only for cases when useOneOfInterfaces is true and for spring --- .../main/java/org/openapitools/codegen/DefaultCodegen.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index e9d57285f03a..68de3d85e27b 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -753,7 +753,9 @@ public void preprocessOpenAPI(OpenAPI openAPI) { String nOneOf = toModelName(n + "OneOf"); if (ModelUtils.isComposedSchema(s)) { addOneOfNameExtension((ComposedSchema) s, n); - addOneOfInterfaceModel((ComposedSchema) s, nOneOf); + if (useOneOfInterfaces && templateDir.equals("JavaSpring")){ + addOneOfInterfaceModel((ComposedSchema) s, nOneOf); + } } else if (ModelUtils.isArraySchema(s)) { Schema items = ((ArraySchema) s).getItems(); if (ModelUtils.isComposedSchema(items)) { From 299cdb38a21422ec71f0925dce2fe974255d2123 Mon Sep 17 00:00:00 2001 From: Alexej Date: Tue, 24 Mar 2020 23:55:30 +0100 Subject: [PATCH 07/25] Fix OpenAPITools#5381 NPE fix --- .../src/main/java/org/openapitools/codegen/DefaultCodegen.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 68de3d85e27b..239915f786cb 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -753,7 +753,7 @@ public void preprocessOpenAPI(OpenAPI openAPI) { String nOneOf = toModelName(n + "OneOf"); if (ModelUtils.isComposedSchema(s)) { addOneOfNameExtension((ComposedSchema) s, n); - if (useOneOfInterfaces && templateDir.equals("JavaSpring")){ + if (useOneOfInterfaces && "JavaSpring".equals(templateDir)){ addOneOfInterfaceModel((ComposedSchema) s, nOneOf); } } else if (ModelUtils.isArraySchema(s)) { From 26a95f637d08a5a0e346a91d339b58047f44aa24 Mon Sep 17 00:00:00 2001 From: Alexej Date: Wed, 25 Mar 2020 11:06:08 +0100 Subject: [PATCH 08/25] Fix OpenAPITools#5381 spring: fixed use of oneOf Models in API --- .../openapitools/codegen/DefaultCodegen.java | 47 +++++++++++++++---- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index f5538a6f9c80..cbe2f03f6b6a 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -83,6 +83,7 @@ public class DefaultCodegen implements CodegenConfig { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class); public static FeatureSet DefaultFeatureSet; + public static final String LIBRARY_ONEOF_IMPL = "JavaSpring"; // A cache of sanitized words. The sanitizeName() method is invoked many times with the same // arguments, this cache is used to optimized performance. @@ -710,7 +711,7 @@ public void postProcessParameter(CodegenParameter parameter) { //override with any special handling of the entire OpenAPI spec document @SuppressWarnings("unused") public void preprocessOpenAPI(OpenAPI openAPI) { - if (useOneOfInterfaces) { + if (useOneOfInterfaces && openAPI.getComponents() != null) { // we process the openapi schema here to find oneOf schemas and create interface models for them Map schemas = new HashMap(openAPI.getComponents().getSchemas()); if (schemas == null) { @@ -733,24 +734,42 @@ public void preprocessOpenAPI(OpenAPI openAPI) { schemas.put(opId, requestSchema); } // process all response bodies - for (Map.Entry 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); + if (op.getValue().getResponses() != null) { + for (Map.Entry 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); + } } } } } } + // also add all properties of all schemas to be checked for oneOf + Map propertySchemas = new HashMap(); + for (Map.Entry e : schemas.entrySet()) { + Schema s = e.getValue(); + Map props = s.getProperties(); + if (props == null) { + props = new HashMap(); + } + for (Map.Entry p : props.entrySet()) { + propertySchemas.put(e.getKey() + "/" + p.getKey(), p.getValue()); + } + } + schemas.putAll(propertySchemas); + // go through all gathered schemas and add them as interfaces to be created for (Map.Entry e : schemas.entrySet()) { String n = toModelName(e.getKey()); Schema s = e.getValue(); String nOneOf = toModelName(n + "OneOf"); if (ModelUtils.isComposedSchema(s)) { - if (e.getKey().contains("/")) { + if (e.getKey().contains("/") || (useOneOfInterfaces && LIBRARY_ONEOF_IMPL.equals(templateDir))) { // if this is property schema, we also need to generate the oneOf interface model addOneOfNameExtension((ComposedSchema) s, nOneOf); addOneOfInterfaceModel((ComposedSchema) s, nOneOf); @@ -5432,6 +5451,9 @@ public CodegenParameter fromRequestBody(RequestBody body, Set imports, S LOGGER.warn("codegenModel is null. Default to UNKNOWN_BASE_TYPE"); codegenModelName = "UNKNOWN_BASE_TYPE"; codegenModelDescription = "UNKNOWN_DESCRIPTION"; + if (useOneOfInterfaces && templateDir.equals(LIBRARY_ONEOF_IMPL)){ + codegenModelName = codegenProperty.getComplexType(); + } } if (StringUtils.isEmpty(bodyParameterName)) { @@ -5446,7 +5468,8 @@ public CodegenParameter fromRequestBody(RequestBody body, Set imports, S codegenParameter.description = codegenModelDescription; imports.add(codegenParameter.baseType); - if (codegenProperty.complexType != null) { + if (codegenProperty.complexType != null && (useOneOfInterfaces && !templateDir.equals( + LIBRARY_ONEOF_IMPL))) { imports.add(codegenProperty.complexType); } } @@ -5733,15 +5756,19 @@ public void addOneOfNameExtension(ComposedSchema s, String name) { } /** - * Add a given ComposedSchema as an interface model to be generated + * Add a given ComposedSchema as an interface model to be generated, assuming it has `oneOf` defined * @param cs ComposedSchema object to create as interface model * @param type name to use for the generated interface model */ public void addOneOfInterfaceModel(ComposedSchema cs, String type) { + if (cs.getOneOf() == null) { + return; + } CodegenModel cm = new CodegenModel(); cm.discriminator = createDiscriminator("", (Schema) cs); - for (Schema o : cs.getOneOf()) { + + for (Schema o : Optional.ofNullable(cs.getOneOf()).orElse(Collections.emptyList())) { if (o.get$ref() == null) { if (cm.discriminator != null && o.get$ref() == null) { // OpenAPI spec states that inline objects should not be considered when discriminator is used From 9af7db65ce8022654ff5a5ee111bd4bdfc6994c2 Mon Sep 17 00:00:00 2001 From: Alexej Date: Mon, 30 Mar 2020 21:22:56 +0200 Subject: [PATCH 09/25] Fix OpenAPITools#5381 implementing oneOf for spring lib overriding methods with different behavior from default --- .../openapitools/codegen/DefaultCodegen.java | 40 +++++++++++-------- .../codegen/languages/SpringCodegen.java | 31 ++++++++++++++ 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index cbe2f03f6b6a..ef771f6bb1eb 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -83,7 +83,6 @@ public class DefaultCodegen implements CodegenConfig { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class); public static FeatureSet DefaultFeatureSet; - public static final String LIBRARY_ONEOF_IMPL = "JavaSpring"; // A cache of sanitized words. The sanitizeName() method is invoked many times with the same // arguments, this cache is used to optimized performance. @@ -769,14 +768,7 @@ public void preprocessOpenAPI(OpenAPI openAPI) { Schema s = e.getValue(); String nOneOf = toModelName(n + "OneOf"); if (ModelUtils.isComposedSchema(s)) { - if (e.getKey().contains("/") || (useOneOfInterfaces && LIBRARY_ONEOF_IMPL.equals(templateDir))) { - // if this is property schema, we also need to generate the oneOf interface model - addOneOfNameExtension((ComposedSchema) s, nOneOf); - addOneOfInterfaceModel((ComposedSchema) s, nOneOf); - } else { - // else this is a component schema, so we will just use that as the oneOf interface model - addOneOfNameExtension((ComposedSchema) s, n); - } + addOneOfForComposedSchema(e, n, (ComposedSchema) s, nOneOf); } else if (ModelUtils.isArraySchema(s)) { Schema items = ((ArraySchema) s).getItems(); if (ModelUtils.isComposedSchema(items)) { @@ -794,6 +786,18 @@ public void preprocessOpenAPI(OpenAPI openAPI) { } } + protected void addOneOfForComposedSchema(Entry stringSchemaEntry, String modelName, ComposedSchema composedSchema, + String nOneOf) { + if (stringSchemaEntry.getKey().contains("/")) { + // if this is property schema, we also need to generate the oneOf interface model + addOneOfNameExtension(composedSchema, nOneOf); + addOneOfInterfaceModel(composedSchema, nOneOf); + } else { + // else this is a component schema, so we will just use that as the oneOf interface model + addOneOfNameExtension(composedSchema, modelName); + } + } + // override with any special handling of the entire OpenAPI spec document @SuppressWarnings("unused") public void processOpenAPI(OpenAPI openAPI) { @@ -5449,11 +5453,8 @@ public CodegenParameter fromRequestBody(RequestBody body, Set imports, S "'application/x-www-form-urlencoded' or 'multipart/?'"); LOGGER.warn("schema: " + schema); LOGGER.warn("codegenModel is null. Default to UNKNOWN_BASE_TYPE"); - codegenModelName = "UNKNOWN_BASE_TYPE"; codegenModelDescription = "UNKNOWN_DESCRIPTION"; - if (useOneOfInterfaces && templateDir.equals(LIBRARY_ONEOF_IMPL)){ - codegenModelName = codegenProperty.getComplexType(); - } + codegenModelName = getCodegenModelName(codegenProperty); } if (StringUtils.isEmpty(bodyParameterName)) { @@ -5468,9 +5469,8 @@ public CodegenParameter fromRequestBody(RequestBody body, Set imports, S codegenParameter.description = codegenModelDescription; imports.add(codegenParameter.baseType); - if (codegenProperty.complexType != null && (useOneOfInterfaces && !templateDir.equals( - LIBRARY_ONEOF_IMPL))) { - imports.add(codegenProperty.complexType); + if (codegenProperty.complexType != null) { + addAdditionalImports(imports, codegenProperty.complexType); } } } @@ -5519,6 +5519,14 @@ public CodegenParameter fromRequestBody(RequestBody body, Set imports, S return codegenParameter; } + protected void addAdditionalImports(Set imports, String complexType) { + imports.add(complexType); + } + + protected String getCodegenModelName(CodegenProperty codegenProperty) { + return "UNKNOWN_BASE_TYPE"; + } + protected void addOption(String key, String description, String defaultValue) { CliOption option = new CliOption(key, description); if (defaultValue != null) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java index cad6828cd3fd..aeaea6b09f66 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java @@ -21,6 +21,9 @@ import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.PathItem; +import io.swagger.v3.oas.models.media.ComposedSchema; +import io.swagger.v3.oas.models.media.Schema; +import java.util.Map.Entry; import org.apache.commons.lang3.tuple.Pair; import org.openapitools.codegen.*; import org.openapitools.codegen.languages.features.BeanValidationFeatures; @@ -581,6 +584,34 @@ public void preprocessOpenAPI(OpenAPI openAPI) { } } + @Override + protected void addOneOfForComposedSchema(Entry stringSchemaEntry, String modelName, ComposedSchema composedSchema, + String nOneOf){ + if (useOneOfInterfaces) { + // if this is property schema, we also need to generate the oneOf interface model + addOneOfNameExtension(composedSchema, nOneOf); + addOneOfInterfaceModel(composedSchema, nOneOf); + } else { + super.addOneOfForComposedSchema(stringSchemaEntry, modelName, composedSchema, nOneOf); + } + } + + @Override + protected String getCodegenModelName(CodegenProperty codegenProperty) { + if (useOneOfInterfaces){ + return codegenProperty.getComplexType(); + } else { + return super.getCodegenModelName(codegenProperty); + } + } + + @Override + protected void addAdditionalImports(Set imports, String complexType) { + if (!useOneOfInterfaces){ + super.addAdditionalImports(imports, complexType); + } + } + @Override public Map postProcessOperationsWithModels(Map objs, List allModels) { Map operations = (Map) objs.get("operations"); From fbfd57d0effa2f4b17a32f83c2bc291023d2f449 Mon Sep 17 00:00:00 2001 From: Alexej Date: Sat, 21 Mar 2020 23:33:15 +0100 Subject: [PATCH 10/25] Fix OpenAPITools#5381 added x-is-one-of-interface extension for oneOf interface in mustache template --- .../java/org/openapitools/codegen/languages/SpringCodegen.java | 3 --- .../src/main/resources/JavaSpring/oneof_interface.mustache | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java index aeaea6b09f66..079f1d8c0591 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java @@ -21,9 +21,6 @@ import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.PathItem; -import io.swagger.v3.oas.models.media.ComposedSchema; -import io.swagger.v3.oas.models.media.Schema; -import java.util.Map.Entry; import org.apache.commons.lang3.tuple.Pair; import org.openapitools.codegen.*; import org.openapitools.codegen.languages.features.BeanValidationFeatures; diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache index 4500871766c1..02deb483d5fd 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache @@ -3,4 +3,4 @@ public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}exte {{#discriminator}} public {{propertyType}} {{propertyGetter}}(); {{/discriminator}} -} \ No newline at end of file +} From bfab3044e509ce60de669c893c47517ca74e9abf Mon Sep 17 00:00:00 2001 From: Alexej Date: Sun, 22 Mar 2020 09:06:32 +0100 Subject: [PATCH 11/25] Fix OpenAPITools#5381 fixed name of model from UNKNOWN_BASE_TYPE to right one in api: operationId + OneOf Fix OpenAPITools#5381 removed not needed methods Fix OpenAPITools#5381 fixed generation of oneOf Models Fix OpenAPITools#5381 addOneOfInterfaceModel only for cases when useOneOfInterfaces is true and for spring Fix OpenAPITools#5381 NPE fix for tests --- .../openapitools/codegen/DefaultCodegen.java | 39 +++---------------- .../JavaSpring/oneof_interface.mustache | 2 +- 2 files changed, 7 insertions(+), 34 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index ef771f6bb1eb..ad52150bd999 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -748,27 +748,16 @@ public void preprocessOpenAPI(OpenAPI openAPI) { } } - // also add all properties of all schemas to be checked for oneOf - Map propertySchemas = new HashMap(); - for (Map.Entry e : schemas.entrySet()) { - Schema s = e.getValue(); - Map props = s.getProperties(); - if (props == null) { - props = new HashMap(); - } - for (Map.Entry p : props.entrySet()) { - propertySchemas.put(e.getKey() + "/" + p.getKey(), p.getValue()); - } - } - schemas.putAll(propertySchemas); - // go through all gathered schemas and add them as interfaces to be created for (Map.Entry e : schemas.entrySet()) { String n = toModelName(e.getKey()); Schema s = e.getValue(); String nOneOf = toModelName(n + "OneOf"); if (ModelUtils.isComposedSchema(s)) { - addOneOfForComposedSchema(e, n, (ComposedSchema) s, nOneOf); + addOneOfNameExtension((ComposedSchema) s, n); + if (useOneOfInterfaces && "JavaSpring".equals(templateDir)){ + addOneOfInterfaceModel((ComposedSchema) s, nOneOf); + } } else if (ModelUtils.isArraySchema(s)) { Schema items = ((ArraySchema) s).getItems(); if (ModelUtils.isComposedSchema(items)) { @@ -786,18 +775,6 @@ public void preprocessOpenAPI(OpenAPI openAPI) { } } - protected void addOneOfForComposedSchema(Entry stringSchemaEntry, String modelName, ComposedSchema composedSchema, - String nOneOf) { - if (stringSchemaEntry.getKey().contains("/")) { - // if this is property schema, we also need to generate the oneOf interface model - addOneOfNameExtension(composedSchema, nOneOf); - addOneOfInterfaceModel(composedSchema, nOneOf); - } else { - // else this is a component schema, so we will just use that as the oneOf interface model - addOneOfNameExtension(composedSchema, modelName); - } - } - // override with any special handling of the entire OpenAPI spec document @SuppressWarnings("unused") public void processOpenAPI(OpenAPI openAPI) { @@ -5764,19 +5741,15 @@ public void addOneOfNameExtension(ComposedSchema s, String name) { } /** - * Add a given ComposedSchema as an interface model to be generated, assuming it has `oneOf` defined + * Add a given ComposedSchema as an interface model to be generated * @param cs ComposedSchema object to create as interface model * @param type name to use for the generated interface model */ public void addOneOfInterfaceModel(ComposedSchema cs, String type) { - if (cs.getOneOf() == null) { - return; - } CodegenModel cm = new CodegenModel(); cm.discriminator = createDiscriminator("", (Schema) cs); - - for (Schema o : Optional.ofNullable(cs.getOneOf()).orElse(Collections.emptyList())) { + for (Schema o : cs.getOneOf()) { if (o.get$ref() == null) { if (cm.discriminator != null && o.get$ref() == null) { // OpenAPI spec states that inline objects should not be considered when discriminator is used diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache index 02deb483d5fd..4500871766c1 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache @@ -3,4 +3,4 @@ public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}exte {{#discriminator}} public {{propertyType}} {{propertyGetter}}(); {{/discriminator}} -} +} \ No newline at end of file From 29003d8f99d655ada5f783ed13fe0e6359777e36 Mon Sep 17 00:00:00 2001 From: Alexej Date: Wed, 1 Apr 2020 21:22:46 +0200 Subject: [PATCH 12/25] Fix OpenAPITools#5381 fixed handing of composed schema with array --- .../openapitools/codegen/DefaultCodegen.java | 56 ++++++++++++++----- .../codegen/languages/SpringCodegen.java | 30 +++++----- 2 files changed, 57 insertions(+), 29 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index ad52150bd999..cb2142b6ebdf 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -748,24 +748,34 @@ public void preprocessOpenAPI(OpenAPI openAPI) { } } - // go through all gathered schemas and add them as interfaces to be created + // also add all properties of all schemas to be checked for oneOf + Map propertySchemas = new HashMap(); for (Map.Entry e : schemas.entrySet()) { - String n = toModelName(e.getKey()); Schema s = e.getValue(); - String nOneOf = toModelName(n + "OneOf"); - if (ModelUtils.isComposedSchema(s)) { - addOneOfNameExtension((ComposedSchema) s, n); - if (useOneOfInterfaces && "JavaSpring".equals(templateDir)){ - addOneOfInterfaceModel((ComposedSchema) s, nOneOf); - } - } else if (ModelUtils.isArraySchema(s)) { - Schema items = ((ArraySchema) s).getItems(); + Map props = s.getProperties(); + if (props == null) { + props = new HashMap(); + } + for (Map.Entry p : props.entrySet()) { + propertySchemas.put(e.getKey() + "/" + p.getKey(), p.getValue()); + } + } + schemas.putAll(propertySchemas); + + // go through all gathered schemas and add them as interfaces to be created + for (Map.Entry e : schemas.entrySet()) { + String modelName = toModelName(e.getKey()); + Schema schema = e.getValue(); + String nOneOf = toModelName(modelName + "OneOf"); + if (ModelUtils.isComposedSchema(schema)) { + addOneOfForComposedSchema(e, modelName, (ComposedSchema) schema, nOneOf); + } else if (ModelUtils.isArraySchema(schema)) { + Schema items = ((ArraySchema) schema).getItems(); if (ModelUtils.isComposedSchema(items)) { - addOneOfNameExtension((ComposedSchema) items, nOneOf); - addOneOfInterfaceModel((ComposedSchema) items, nOneOf); + addOneOfForComposedSchemaArray(nOneOf, modelName, (ComposedSchema) items); } - } else if (ModelUtils.isMapSchema(s)) { - Schema addProps = ModelUtils.getAdditionalProperties(s); + } else if (ModelUtils.isMapSchema(schema)) { + Schema addProps = ModelUtils.getAdditionalProperties(schema); if (addProps != null && ModelUtils.isComposedSchema(addProps)) { addOneOfNameExtension((ComposedSchema) addProps, nOneOf); addOneOfInterfaceModel((ComposedSchema) addProps, nOneOf); @@ -775,6 +785,24 @@ public void preprocessOpenAPI(OpenAPI openAPI) { } } + protected void addOneOfForComposedSchemaArray(String nOneOf, String modelName, + ComposedSchema items) { + addOneOfNameExtension(items, nOneOf); + addOneOfInterfaceModel(items, nOneOf); + } + + protected void addOneOfForComposedSchema(Entry stringSchemaEntry, String modelName, ComposedSchema composedSchema, + String nOneOf) { + if (stringSchemaEntry.getKey().contains("/")) { + // if this is property schema, we also need to generate the oneOf interface model + addOneOfNameExtension(composedSchema, nOneOf); + addOneOfInterfaceModel(composedSchema, nOneOf); + } else { + // else this is a component schema, so we will just use that as the oneOf interface model + addOneOfNameExtension(composedSchema, modelName); + } + } + // override with any special handling of the entire OpenAPI spec document @SuppressWarnings("unused") public void processOpenAPI(OpenAPI openAPI) { diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java index 079f1d8c0591..c843398930e2 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java @@ -21,6 +21,9 @@ import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.PathItem; +import io.swagger.v3.oas.models.media.ComposedSchema; +import io.swagger.v3.oas.models.media.Schema; +import java.util.Map.Entry; import org.apache.commons.lang3.tuple.Pair; import org.openapitools.codegen.*; import org.openapitools.codegen.languages.features.BeanValidationFeatures; @@ -584,29 +587,26 @@ public void preprocessOpenAPI(OpenAPI openAPI) { @Override protected void addOneOfForComposedSchema(Entry stringSchemaEntry, String modelName, ComposedSchema composedSchema, String nOneOf){ - if (useOneOfInterfaces) { - // if this is property schema, we also need to generate the oneOf interface model - addOneOfNameExtension(composedSchema, nOneOf); - addOneOfInterfaceModel(composedSchema, nOneOf); - } else { - super.addOneOfForComposedSchema(stringSchemaEntry, modelName, composedSchema, nOneOf); - } + // if this is property schema, we also need to generate the oneOf interface model + addOneOfNameExtension(composedSchema, modelName); + addOneOfInterfaceModel(composedSchema, modelName); + } + + @Override + protected void addOneOfForComposedSchemaArray(String nOneOf, String modelName, + ComposedSchema items) { + addOneOfNameExtension(items, modelName); + addOneOfInterfaceModel(items, modelName); } @Override protected String getCodegenModelName(CodegenProperty codegenProperty) { - if (useOneOfInterfaces){ - return codegenProperty.getComplexType(); - } else { - return super.getCodegenModelName(codegenProperty); - } + return codegenProperty.getComplexType(); } @Override protected void addAdditionalImports(Set imports, String complexType) { - if (!useOneOfInterfaces){ - super.addAdditionalImports(imports, complexType); - } + //nothing to do for spring } @Override From d8648310ba535838eaeca534e255adacfbe4c756 Mon Sep 17 00:00:00 2001 From: Alexej Date: Wed, 1 Apr 2020 22:13:53 +0200 Subject: [PATCH 13/25] Fix OpenAPITools#5381 fixed NPE in addOneOfInterfaceModel --- .../openapitools/codegen/DefaultCodegen.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index cb2142b6ebdf..71a5055a0e6e 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -5777,18 +5777,20 @@ public void addOneOfInterfaceModel(ComposedSchema cs, String type) { CodegenModel cm = new CodegenModel(); cm.discriminator = createDiscriminator("", (Schema) cs); - for (Schema o : cs.getOneOf()) { - if (o.get$ref() == null) { - if (cm.discriminator != null && o.get$ref() == null) { - // OpenAPI spec states that inline objects should not be considered when discriminator is used - // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#discriminatorObject - LOGGER.warn("Ignoring inline object in oneOf definition of {}, since discriminator is used", type); - } else { - LOGGER.warn("Inline models are not supported in oneOf definition right now"); + if (cs.getOneOf() != null){ + for (Schema o : cs.getOneOf()) { + if (o.get$ref() == null) { + if (cm.discriminator != null && o.get$ref() == null) { + // OpenAPI spec states that inline objects should not be considered when discriminator is used + // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#discriminatorObject + LOGGER.warn("Ignoring inline object in oneOf definition of {}, since discriminator is used", type); + } else { + LOGGER.warn("Inline models are not supported in oneOf definition right now"); + } + continue; } - continue; + cm.oneOf.add(toModelName(ModelUtils.getSimpleRef(o.get$ref()))); } - cm.oneOf.add(toModelName(ModelUtils.getSimpleRef(o.get$ref()))); } cm.name = type; cm.classname = type; From 6d54799992ee7cd78d624f8bbb3299677d66c1af Mon Sep 17 00:00:00 2001 From: Alexej Date: Thu, 2 Apr 2020 22:06:56 +0200 Subject: [PATCH 14/25] Fix OpenAPITools#5381 fixed generation of oneOf models with descriminator --- .../openapitools/codegen/DefaultCodegen.java | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 71a5055a0e6e..73db3b3f488a 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -5769,28 +5769,30 @@ public void addOneOfNameExtension(ComposedSchema s, String name) { } /** - * Add a given ComposedSchema as an interface model to be generated + * Add a given ComposedSchema as an interface model to be generated, assuming it has `oneOf` defined * @param cs ComposedSchema object to create as interface model * @param type name to use for the generated interface model */ public void addOneOfInterfaceModel(ComposedSchema cs, String type) { + if (cs.getOneOf() == null) { + return; + } CodegenModel cm = new CodegenModel(); cm.discriminator = createDiscriminator("", (Schema) cs); - if (cs.getOneOf() != null){ - for (Schema o : cs.getOneOf()) { - if (o.get$ref() == null) { - if (cm.discriminator != null && o.get$ref() == null) { - // OpenAPI spec states that inline objects should not be considered when discriminator is used - // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#discriminatorObject - LOGGER.warn("Ignoring inline object in oneOf definition of {}, since discriminator is used", type); - } else { - LOGGER.warn("Inline models are not supported in oneOf definition right now"); - } - continue; + + for (Schema o : cs.getOneOf()) { + if (o.get$ref() == null) { + if (cm.discriminator != null && o.get$ref() == null) { + // OpenAPI spec states that inline objects should not be considered when discriminator is used + // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#discriminatorObject + LOGGER.warn("Ignoring inline object in oneOf definition of {}, since discriminator is used", type); + } else { + LOGGER.warn("Inline models are not supported in oneOf definition right now"); } - cm.oneOf.add(toModelName(ModelUtils.getSimpleRef(o.get$ref()))); + continue; } + cm.oneOf.add(toModelName(ModelUtils.getSimpleRef(o.get$ref()))); } cm.name = type; cm.classname = type; From 8f09f529340813b58d660d5dfa66b40fe94c3072 Mon Sep 17 00:00:00 2001 From: JBurgess Date: Thu, 3 Dec 2020 16:10:13 -0500 Subject: [PATCH 15/25] Initial merge of 5.0 --- .../openapitools/codegen/DefaultCodegen.java | 18 --- .../languages/AbstractJavaCodegen.java | 10 ++ .../codegen/languages/SpringCodegen.java | 17 --- .../main/resources/JavaSpring/pojo.mustache | 2 +- .../java/spring/SpringCodegenTest.java | 39 +++++ .../src/test/resources/3_0/issue_5381.yaml | 134 ++++++++++++++++++ 6 files changed, 184 insertions(+), 36 deletions(-) create mode 100644 modules/openapi-generator/src/test/resources/3_0/issue_5381.yaml diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 0fa37833148e..de5fa1d653ce 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -855,24 +855,6 @@ public void preprocessOpenAPI(OpenAPI openAPI) { } } - protected void addOneOfForComposedSchemaArray(String nOneOf, String modelName, - ComposedSchema items) { - addOneOfNameExtension(items, nOneOf); - addOneOfInterfaceModel(items, nOneOf); - } - - protected void addOneOfForComposedSchema(Entry stringSchemaEntry, String modelName, ComposedSchema composedSchema, - String nOneOf) { - if (stringSchemaEntry.getKey().contains("/")) { - // if this is property schema, we also need to generate the oneOf interface model - addOneOfNameExtension(composedSchema, nOneOf); - addOneOfInterfaceModel(composedSchema, nOneOf); - } else { - // else this is a component schema, so we will just use that as the oneOf interface model - addOneOfNameExtension(composedSchema, modelName); - } - } - // override with any special handling of the entire OpenAPI spec document @SuppressWarnings("unused") public void processOpenAPI(OpenAPI openAPI) { diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java index 8bddc1feaf5d..fb48e9388e9e 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java @@ -1169,6 +1169,16 @@ public Map postProcessModels(Map objs) { } } + // add implements for serializable/parcelable to all models + List> models = (List>) objs.get("models"); + for (Map mo : models) { + CodegenModel cm = (CodegenModel) mo.get("model"); + if (this.serializableModel) { + cm.getVendorExtensions().putIfAbsent("x-implements", new ArrayList()); + ((ArrayList) cm.getVendorExtensions().get("x-implements")).add("Serializable"); + } + } + return postProcessModelsEnum(objs); } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java index 55cb59e57132..d125e94fbcdb 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java @@ -21,9 +21,6 @@ import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.PathItem; -import io.swagger.v3.oas.models.media.ComposedSchema; -import io.swagger.v3.oas.models.media.Schema; -import java.util.Map.Entry; import org.apache.commons.lang3.tuple.Pair; import org.openapitools.codegen.*; import org.openapitools.codegen.languages.features.BeanValidationFeatures; @@ -580,20 +577,6 @@ public void preprocessOpenAPI(OpenAPI openAPI) { } } - @Override - protected void addOneOfForComposedSchema(Entry stringSchemaEntry, String modelName, ComposedSchema composedSchema, - String nOneOf){ - // if this is property schema, we also need to generate the oneOf interface model - addOneOfNameExtension(composedSchema, modelName); - addOneOfInterfaceModel(composedSchema, modelName); - } - - @Override - protected void addOneOfForComposedSchemaArray(String nOneOf, String modelName, - ComposedSchema items) { - addOneOfNameExtension(items, modelName); - addOneOfInterfaceModel(items, modelName); - } @Override protected String getCodegenModelName(CodegenProperty codegenProperty) { diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache index a07d9a62f1d2..db2e82eac4d6 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache @@ -3,7 +3,7 @@ */{{#description}} @ApiModel(description = "{{{description}}}"){{/description}} {{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}}{{>additionalModelTypeAnnotations}} -public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}}{{^parent}}{{#hateoas}}extends RepresentationModel<{{classname}}> {{/hateoas}}{{/parent}} {{#serializableModel}}implements Serializable{{/serializableModel}} { +public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}}{{^parent}}{{#hateoas}}extends RepresentationModel<{{classname}}> {{/hateoas}}{{/parent}}{{#vendorExtensions.x-implements}}{{#-first}}implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{#-last}} {{/-last}}{{/vendorExtensions.x-implements}}{ {{#serializableModel}} private static final long serialVersionUID = 1L; diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java index 14e1f9262d87..b99c9f86a2a3 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java @@ -619,4 +619,43 @@ private void beanValidationForFormatEmail(boolean useBeanValidation, boolean per public void useBeanValidationTruePerformBeanValidationTrueJava8TrueForFormatEmail() throws IOException { beanValidationForFormatEmail(true, true, true, "@javax.validation.constraints.Email", "@org.hibernate.validator.constraints.Email"); } + + @Test + public void oneOf_5381() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + String outputPath = output.getAbsolutePath().replace('\\', '/'); + OpenAPI openAPI = new OpenAPIParser() + .readLocation("src/test/resources/3_0/issue_5381.yaml", null, new ParseOptions()).getOpenAPI(); + + SpringCodegen codegen = new SpringCodegen(); + codegen.setOutputDir(output.getAbsolutePath()); + codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true"); + codegen.setUseOneOfInterfaces(true); + + ClientOptInput input = new ClientOptInput(); + input.openAPI(openAPI); + input.config(codegen); + + DefaultGenerator generator = new DefaultGenerator(); + codegen.setHateoas(true); + generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true"); + //generator.setGeneratorPropertyDefault(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, "true"); + generator.setGeneratorPropertyDefault(CodegenConstants.LEGACY_DISCRIMINATOR_BEHAVIOR, "false"); + + codegen.setUseOneOfInterfaces(true); + codegen.setJava8(true); + codegen.setLegacyDiscriminatorBehavior(false); + + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true"); + generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); + + generator.opts(input).generate(); + + assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/Foo.java"), "public class Foo implements FooRefOrValue"); + assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/FooRef.java"), "public class FooRef implements FooRefOrValue"); + assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/FooRefOrValue.java"), "public interface FooRefOrValue"); + } } diff --git a/modules/openapi-generator/src/test/resources/3_0/issue_5381.yaml b/modules/openapi-generator/src/test/resources/3_0/issue_5381.yaml new file mode 100644 index 000000000000..192c958f7245 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/issue_5381.yaml @@ -0,0 +1,134 @@ +openapi: 3.0.1 +info: + title: ByRefOrValue + description: > + This tests for a oneOf interface representation + version: 0.0.1 +servers: + - url: "http://localhost:8080" +tags: + - name: Foo +paths: + /foo: + get: + tags: + - Foo + summary: GET all Foos + operationId: getAllFoos + responses: + '200': + $ref: '#/components/responses/200FooArray' + post: + tags: + - Foo + summary: Create a Foo + operationId: createFoo + requestBody: + $ref: '#/components/requestBodies/Foo' + responses: + '201': + $ref: '#/components/responses/201Foo' + +components: + schemas: + Entity: + type: object + allOf: + - "$ref": "#/components/schemas/Addressable" + - "$ref": "#/components/schemas/Extensible" + + EntityRef: + description: Entity reference schema to be use for all entityRef class. + type: object + properties: + name: + type: string + description: Name of the related entity. + '@referredType': + type: string + description: The actual type of the target instance when needed for disambiguation. + allOf: + - $ref: '#/components/schemas/Addressable' + - "$ref": "#/components/schemas/Extensible" + + + Addressable: + type: object + properties: + href: + type: string + description: Hyperlink reference + id: + type: string + description: unique identifier + description: Base schema for adressable entities + Extensible: + type: object + properties: + "@schemaLocation": + type: string + description: A URI to a JSON-Schema file that defines additional attributes + and relationships + "@baseType": + type: string + description: When sub-classing, this defines the super-class + "@type": + type: string + description: When sub-classing, this defines the sub-class Extensible name + required: + - '@type' + + FooRefOrValue: + type: object + oneOf: + - $ref: "#/components/schemas/Foo" + - $ref: "#/components/schemas/FooRef" + discriminator: + propertyName: "@type" + mapping: + Foo: "#/components/schemas/Foo" + FooRef: "#/components/schemas/FooRef" + + Foo: + type: object + properties: + fooPropA: + type: string + fooPropB: + type: string + allOf: + - $ref: '#/components/schemas/Entity' + + FooRef: + type: object + properties: + foorefPropA: + type: string + allOf: + - $ref: '#/components/schemas/EntityRef' + + requestBodies: + Foo: + description: The Foo to be created + content: + application/json;charset=utf-8: + schema: + $ref: '#/components/schemas/Foo' + responses: + '204': + description: Deleted + content: { } + 201Foo: + description: Error + content: + application/json: + schema: + $ref: '#/components/schemas/FooRefOrValue' + 200FooArray: + description: Success + content: + application/json;charset=utf-8: + schema: + type: array + items: + $ref: '#/components/schemas/FooRefOrValue' \ No newline at end of file From 0d31df4d437d5810f397985a0307129088b0b34f Mon Sep 17 00:00:00 2001 From: JBurgess Date: Thu, 3 Dec 2020 16:14:42 -0500 Subject: [PATCH 16/25] Aligned with master formatting --- .../openapitools/codegen/DefaultCodegen.java | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index de5fa1d653ce..4d5bf89af0ce 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -796,10 +796,8 @@ public void preprocessOpenAPI(OpenAPI openAPI) { } // process all response bodies if (op.getValue().getResponses() != null) { - for (Map.Entry ar : op.getValue().getResponses() - .entrySet()) { - ApiResponse a = ModelUtils - .getReferencedApiResponse(openAPI, ar.getValue()); + for (Map.Entry 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); @@ -2611,18 +2609,6 @@ public int compare(CodegenProperty one, CodegenProperty another) { postProcessModelProperty(m, prop); } } - - if (sortModelPropertiesByRequiredFlag) { - Collections.sort(m.vars, new Comparator() { - @Override - public int compare(CodegenProperty one, CodegenProperty another) { - if (one.required == another.required) return 0; - else if (one.required) return -1; - else return 1; - } - }); - } - return m; } From 397e7116770f943868ba13dfc723e0e27c6c076e Mon Sep 17 00:00:00 2001 From: jburgess Date: Thu, 3 Dec 2020 19:16:41 -0500 Subject: [PATCH 17/25] Corrected spacing for class names to align with samples. --- .../src/main/resources/JavaSpring/pojo.mustache | 2 +- .../src/main/java/org/openapitools/model/Category.java | 2 +- .../src/main/java/org/openapitools/model/ModelApiResponse.java | 2 +- .../src/main/java/org/openapitools/model/Order.java | 2 +- .../src/main/java/org/openapitools/model/Pet.java | 2 +- .../src/main/java/org/openapitools/model/Tag.java | 2 +- .../src/main/java/org/openapitools/model/User.java | 2 +- .../src/main/java/org/openapitools/model/Category.java | 2 +- .../src/main/java/org/openapitools/model/ModelApiResponse.java | 2 +- .../src/main/java/org/openapitools/model/Order.java | 2 +- .../src/main/java/org/openapitools/model/Pet.java | 2 +- .../src/main/java/org/openapitools/model/Tag.java | 2 +- .../src/main/java/org/openapitools/model/User.java | 2 +- .../src/main/java/org/openapitools/model/Category.java | 2 +- .../src/main/java/org/openapitools/model/ModelApiResponse.java | 2 +- .../src/main/java/org/openapitools/model/Order.java | 2 +- .../spring-cloud/src/main/java/org/openapitools/model/Pet.java | 2 +- .../spring-cloud/src/main/java/org/openapitools/model/Tag.java | 2 +- .../spring-cloud/src/main/java/org/openapitools/model/User.java | 2 +- .../src/main/java/org/openapitools/model/Category.java | 2 +- .../src/main/java/org/openapitools/model/ModelApiResponse.java | 2 +- .../src/main/java/org/openapitools/model/Order.java | 2 +- .../spring-stubs/src/main/java/org/openapitools/model/Pet.java | 2 +- .../spring-stubs/src/main/java/org/openapitools/model/Tag.java | 2 +- .../spring-stubs/src/main/java/org/openapitools/model/User.java | 2 +- 25 files changed, 25 insertions(+), 25 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache index db2e82eac4d6..18255bef6f39 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache @@ -3,7 +3,7 @@ */{{#description}} @ApiModel(description = "{{{description}}}"){{/description}} {{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}}{{>additionalModelTypeAnnotations}} -public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}}{{^parent}}{{#hateoas}}extends RepresentationModel<{{classname}}> {{/hateoas}}{{/parent}}{{#vendorExtensions.x-implements}}{{#-first}}implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{#-last}} {{/-last}}{{/vendorExtensions.x-implements}}{ +public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}}{{^parent}}{{#hateoas}}extends RepresentationModel<{{classname}}> {{/hateoas}}{{/parent}} {{#vendorExtensions.x-implements}}{{#-first}}implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{#-last}} {{/-last}}{{/vendorExtensions.x-implements}} { {{#serializableModel}} private static final long serialVersionUID = 1L; diff --git a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Category.java b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Category.java index 1114316e27f5..da1be544c177 100644 --- a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Category.java +++ b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Category.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A category for a pet") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Category { +public class Category { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/ModelApiResponse.java b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/ModelApiResponse.java index 523a64f1874d..713ec5a9014f 100644 --- a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/ModelApiResponse.java +++ b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/ModelApiResponse.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "Describes the result of uploading an image resource") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class ModelApiResponse { +public class ModelApiResponse { @JsonProperty("code") private Integer code; diff --git a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Order.java b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Order.java index 12230edbc050..d61cb72b0cd9 100644 --- a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Order.java +++ b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Order.java @@ -16,7 +16,7 @@ */ @ApiModel(description = "An order for a pets from the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Order { +public class Order { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Pet.java b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Pet.java index 1e1b76c7d117..fde2e07ff4e8 100644 --- a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Pet.java +++ b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Pet.java @@ -19,7 +19,7 @@ */ @ApiModel(description = "A pet for sale in the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Pet { +public class Pet { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Tag.java b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Tag.java index 1476aa7d343a..ab8fa9febba0 100644 --- a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Tag.java +++ b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Tag.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A tag for a pet") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Tag { +public class Tag { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/User.java b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/User.java index 8bfae36516d1..5555bf902de5 100644 --- a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/User.java +++ b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/User.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A User who is purchasing from the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class User { +public class User { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Category.java b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Category.java index 2c765a51de96..1945efef7248 100644 --- a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Category.java +++ b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Category.java @@ -13,7 +13,7 @@ */ @ApiModel(description = "A category for a pet") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Category { +public class Category { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/ModelApiResponse.java b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/ModelApiResponse.java index 8f7cd51e26da..58b383408012 100644 --- a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/ModelApiResponse.java +++ b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/ModelApiResponse.java @@ -13,7 +13,7 @@ */ @ApiModel(description = "Describes the result of uploading an image resource") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class ModelApiResponse { +public class ModelApiResponse { @JsonProperty("code") private Integer code; diff --git a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Order.java b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Order.java index 9a420ed8679c..6613254d4bf5 100644 --- a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Order.java +++ b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Order.java @@ -15,7 +15,7 @@ */ @ApiModel(description = "An order for a pets from the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Order { +public class Order { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Pet.java b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Pet.java index b2fc9539454f..fac713bba765 100644 --- a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Pet.java +++ b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Pet.java @@ -18,7 +18,7 @@ */ @ApiModel(description = "A pet for sale in the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Pet { +public class Pet { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Tag.java b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Tag.java index 7938da997ad1..7934322097c2 100644 --- a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Tag.java +++ b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Tag.java @@ -13,7 +13,7 @@ */ @ApiModel(description = "A tag for a pet") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Tag { +public class Tag { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/User.java b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/User.java index d43bccdd77d7..8378024b3334 100644 --- a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/User.java +++ b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/User.java @@ -13,7 +13,7 @@ */ @ApiModel(description = "A User who is purchasing from the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class User { +public class User { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Category.java b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Category.java index 1114316e27f5..da1be544c177 100644 --- a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Category.java +++ b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Category.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A category for a pet") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Category { +public class Category { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/ModelApiResponse.java b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/ModelApiResponse.java index 523a64f1874d..713ec5a9014f 100644 --- a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/ModelApiResponse.java +++ b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/ModelApiResponse.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "Describes the result of uploading an image resource") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class ModelApiResponse { +public class ModelApiResponse { @JsonProperty("code") private Integer code; diff --git a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Order.java b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Order.java index 12230edbc050..d61cb72b0cd9 100644 --- a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Order.java +++ b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Order.java @@ -16,7 +16,7 @@ */ @ApiModel(description = "An order for a pets from the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Order { +public class Order { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Pet.java b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Pet.java index 1e1b76c7d117..fde2e07ff4e8 100644 --- a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Pet.java +++ b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Pet.java @@ -19,7 +19,7 @@ */ @ApiModel(description = "A pet for sale in the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Pet { +public class Pet { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Tag.java b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Tag.java index 1476aa7d343a..ab8fa9febba0 100644 --- a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Tag.java +++ b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Tag.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A tag for a pet") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Tag { +public class Tag { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/User.java b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/User.java index 8bfae36516d1..5555bf902de5 100644 --- a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/User.java +++ b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/User.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A User who is purchasing from the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class User { +public class User { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Category.java b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Category.java index 1114316e27f5..da1be544c177 100644 --- a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Category.java +++ b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Category.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A category for a pet") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Category { +public class Category { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/ModelApiResponse.java b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/ModelApiResponse.java index 523a64f1874d..713ec5a9014f 100644 --- a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/ModelApiResponse.java +++ b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/ModelApiResponse.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "Describes the result of uploading an image resource") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class ModelApiResponse { +public class ModelApiResponse { @JsonProperty("code") private Integer code; diff --git a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Order.java b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Order.java index 12230edbc050..d61cb72b0cd9 100644 --- a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Order.java +++ b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Order.java @@ -16,7 +16,7 @@ */ @ApiModel(description = "An order for a pets from the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Order { +public class Order { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Pet.java b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Pet.java index 1e1b76c7d117..fde2e07ff4e8 100644 --- a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Pet.java +++ b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Pet.java @@ -19,7 +19,7 @@ */ @ApiModel(description = "A pet for sale in the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Pet { +public class Pet { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Tag.java b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Tag.java index 1476aa7d343a..ab8fa9febba0 100644 --- a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Tag.java +++ b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Tag.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A tag for a pet") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Tag { +public class Tag { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/User.java b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/User.java index 8bfae36516d1..5555bf902de5 100644 --- a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/User.java +++ b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/User.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A User who is purchasing from the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class User { +public class User { @JsonProperty("id") private Long id; From 05105fa97091db26da277f35905c142efd277e61 Mon Sep 17 00:00:00 2001 From: JBurgess Date: Wed, 11 Aug 2021 11:13:33 -0400 Subject: [PATCH 18/25] Merged master --- .../openapitools/codegen/languages/SpringCodegen.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java index e7479eb11335..19d4fe675b77 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java @@ -577,17 +577,6 @@ public void preprocessOpenAPI(OpenAPI openAPI) { } } - - @Override - protected String getCodegenModelName(CodegenProperty codegenProperty) { - return codegenProperty.getComplexType(); - } - - @Override - protected void addAdditionalImports(Set imports, String complexType) { - //nothing to do for spring - } - @Override public Map postProcessOperationsWithModels(Map objs, List allModels) { Map operations = (Map) objs.get("operations"); From c89a28b1cce88968357508b6ed87f8c9c765e7e6 Mon Sep 17 00:00:00 2001 From: JBurgess Date: Wed, 11 Aug 2021 14:55:52 -0400 Subject: [PATCH 19/25] Updated samples --- .../src/main/java/org/openapitools/model/Category.java | 2 +- .../src/main/java/org/openapitools/model/ModelApiResponse.java | 2 +- .../src/main/java/org/openapitools/model/Order.java | 2 +- .../src/main/java/org/openapitools/model/Pet.java | 2 +- .../src/main/java/org/openapitools/model/Tag.java | 2 +- .../src/main/java/org/openapitools/model/User.java | 2 +- .../src/main/java/org/openapitools/model/Category.java | 2 +- .../src/main/java/org/openapitools/model/ModelApiResponse.java | 2 +- .../src/main/java/org/openapitools/model/Order.java | 2 +- .../src/main/java/org/openapitools/model/Pet.java | 2 +- .../src/main/java/org/openapitools/model/Tag.java | 2 +- .../src/main/java/org/openapitools/model/User.java | 2 +- .../src/main/java/org/openapitools/model/Category.java | 2 +- .../src/main/java/org/openapitools/model/ModelApiResponse.java | 2 +- .../src/main/java/org/openapitools/model/Order.java | 2 +- .../spring-cloud/src/main/java/org/openapitools/model/Pet.java | 2 +- .../spring-cloud/src/main/java/org/openapitools/model/Tag.java | 2 +- .../spring-cloud/src/main/java/org/openapitools/model/User.java | 2 +- .../src/main/java/org/openapitools/model/Category.java | 2 +- .../src/main/java/org/openapitools/model/ModelApiResponse.java | 2 +- .../src/main/java/org/openapitools/model/Order.java | 2 +- .../spring-stubs/src/main/java/org/openapitools/model/Pet.java | 2 +- .../spring-stubs/src/main/java/org/openapitools/model/Tag.java | 2 +- .../spring-stubs/src/main/java/org/openapitools/model/User.java | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Category.java b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Category.java index da1be544c177..1114316e27f5 100644 --- a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Category.java +++ b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Category.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A category for a pet") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Category { +public class Category { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/ModelApiResponse.java b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/ModelApiResponse.java index 713ec5a9014f..523a64f1874d 100644 --- a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/ModelApiResponse.java +++ b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/ModelApiResponse.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "Describes the result of uploading an image resource") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class ModelApiResponse { +public class ModelApiResponse { @JsonProperty("code") private Integer code; diff --git a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Order.java b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Order.java index d61cb72b0cd9..12230edbc050 100644 --- a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Order.java +++ b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Order.java @@ -16,7 +16,7 @@ */ @ApiModel(description = "An order for a pets from the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Order { +public class Order { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Pet.java b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Pet.java index fde2e07ff4e8..1e1b76c7d117 100644 --- a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Pet.java +++ b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Pet.java @@ -19,7 +19,7 @@ */ @ApiModel(description = "A pet for sale in the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Pet { +public class Pet { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Tag.java b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Tag.java index ab8fa9febba0..1476aa7d343a 100644 --- a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Tag.java +++ b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/Tag.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A tag for a pet") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Tag { +public class Tag { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/User.java b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/User.java index 5555bf902de5..8bfae36516d1 100644 --- a/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/User.java +++ b/samples/client/petstore/spring-cloud-async/src/main/java/org/openapitools/model/User.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A User who is purchasing from the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class User { +public class User { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Category.java b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Category.java index 1945efef7248..2c765a51de96 100644 --- a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Category.java +++ b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Category.java @@ -13,7 +13,7 @@ */ @ApiModel(description = "A category for a pet") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Category { +public class Category { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/ModelApiResponse.java b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/ModelApiResponse.java index 58b383408012..8f7cd51e26da 100644 --- a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/ModelApiResponse.java +++ b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/ModelApiResponse.java @@ -13,7 +13,7 @@ */ @ApiModel(description = "Describes the result of uploading an image resource") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class ModelApiResponse { +public class ModelApiResponse { @JsonProperty("code") private Integer code; diff --git a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Order.java b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Order.java index 6613254d4bf5..9a420ed8679c 100644 --- a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Order.java +++ b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Order.java @@ -15,7 +15,7 @@ */ @ApiModel(description = "An order for a pets from the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Order { +public class Order { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Pet.java b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Pet.java index fac713bba765..b2fc9539454f 100644 --- a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Pet.java +++ b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Pet.java @@ -18,7 +18,7 @@ */ @ApiModel(description = "A pet for sale in the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Pet { +public class Pet { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Tag.java b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Tag.java index 7934322097c2..7938da997ad1 100644 --- a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Tag.java +++ b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/Tag.java @@ -13,7 +13,7 @@ */ @ApiModel(description = "A tag for a pet") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Tag { +public class Tag { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/User.java b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/User.java index 8378024b3334..d43bccdd77d7 100644 --- a/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/User.java +++ b/samples/client/petstore/spring-cloud-no-nullable/src/main/java/org/openapitools/model/User.java @@ -13,7 +13,7 @@ */ @ApiModel(description = "A User who is purchasing from the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class User { +public class User { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Category.java b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Category.java index da1be544c177..1114316e27f5 100644 --- a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Category.java +++ b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Category.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A category for a pet") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Category { +public class Category { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/ModelApiResponse.java b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/ModelApiResponse.java index 713ec5a9014f..523a64f1874d 100644 --- a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/ModelApiResponse.java +++ b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/ModelApiResponse.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "Describes the result of uploading an image resource") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class ModelApiResponse { +public class ModelApiResponse { @JsonProperty("code") private Integer code; diff --git a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Order.java b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Order.java index d61cb72b0cd9..12230edbc050 100644 --- a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Order.java +++ b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Order.java @@ -16,7 +16,7 @@ */ @ApiModel(description = "An order for a pets from the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Order { +public class Order { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Pet.java b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Pet.java index fde2e07ff4e8..1e1b76c7d117 100644 --- a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Pet.java +++ b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Pet.java @@ -19,7 +19,7 @@ */ @ApiModel(description = "A pet for sale in the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Pet { +public class Pet { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Tag.java b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Tag.java index ab8fa9febba0..1476aa7d343a 100644 --- a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Tag.java +++ b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/Tag.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A tag for a pet") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Tag { +public class Tag { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/User.java b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/User.java index 5555bf902de5..8bfae36516d1 100644 --- a/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/User.java +++ b/samples/client/petstore/spring-cloud/src/main/java/org/openapitools/model/User.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A User who is purchasing from the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class User { +public class User { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Category.java b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Category.java index da1be544c177..1114316e27f5 100644 --- a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Category.java +++ b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Category.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A category for a pet") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Category { +public class Category { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/ModelApiResponse.java b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/ModelApiResponse.java index 713ec5a9014f..523a64f1874d 100644 --- a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/ModelApiResponse.java +++ b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/ModelApiResponse.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "Describes the result of uploading an image resource") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class ModelApiResponse { +public class ModelApiResponse { @JsonProperty("code") private Integer code; diff --git a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Order.java b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Order.java index d61cb72b0cd9..12230edbc050 100644 --- a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Order.java +++ b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Order.java @@ -16,7 +16,7 @@ */ @ApiModel(description = "An order for a pets from the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Order { +public class Order { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Pet.java b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Pet.java index fde2e07ff4e8..1e1b76c7d117 100644 --- a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Pet.java +++ b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Pet.java @@ -19,7 +19,7 @@ */ @ApiModel(description = "A pet for sale in the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Pet { +public class Pet { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Tag.java b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Tag.java index ab8fa9febba0..1476aa7d343a 100644 --- a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Tag.java +++ b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/Tag.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A tag for a pet") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class Tag { +public class Tag { @JsonProperty("id") private Long id; diff --git a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/User.java b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/User.java index 5555bf902de5..8bfae36516d1 100644 --- a/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/User.java +++ b/samples/client/petstore/spring-stubs/src/main/java/org/openapitools/model/User.java @@ -14,7 +14,7 @@ */ @ApiModel(description = "A User who is purchasing from the pet store") @javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen") -public class User { +public class User { @JsonProperty("id") private Long id; From a7bae4ead26dc48e3dc1db5047b81259dbc23f82 Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 30 Aug 2021 12:01:11 +0300 Subject: [PATCH 20/25] TAP-232 OneOf fixes --- .../codegen/languages/JavaClientCodegen.java | 12 +-- .../codegen/languages/SpringCodegen.java | 15 ++++ .../spring-boot/oneof_interface.mustache | 6 ++ .../main/resources/JavaSpring/model.mustache | 2 +- .../JavaSpring/oneof_interface.mustache | 6 ++ .../main/resources/JavaSpring/pojo.mustache | 2 +- .../codegen/java/JavaClientCodegenTest.java | 76 +++++++++++++++++++ .../java/spring/SpringCodegenTest.java | 74 ++++++++++++++++++ 8 files changed, 186 insertions(+), 7 deletions(-) create mode 100644 modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/oneof_interface.mustache create mode 100644 modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java index 2ed09080b7f8..85f5bcffde38 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java @@ -1027,11 +1027,13 @@ public String toApiVarName(String name) { @Override public void addImportsToOneOfInterface(List> imports) { - for (String i : Arrays.asList("JsonSubTypes", "JsonTypeInfo")) { - Map oneImport = new HashMap<>(); - oneImport.put("import", importMapping.get(i)); - if (!imports.contains(oneImport)) { - imports.add(oneImport); + if (additionalProperties.containsKey(JACKSON)) { + for (String i : Arrays.asList("JsonSubTypes", "JsonTypeInfo")) { + Map oneImport = new HashMap<>(); + oneImport.put("import", importMapping.get(i)); + if (!imports.contains(oneImport)) { + imports.add(oneImport); + } } } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java index b0db9a4c124d..e4d46f4283d0 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java @@ -135,6 +135,8 @@ public SpringCodegen() { modelPackage = "org.openapitools.model"; invokerPackage = "org.openapitools.api"; artifactId = "openapi-spring"; + useOneOfInterfaces = true; + addOneOfInterfaceImports = true; // clioOptions default redefinition need to be updated updateOption(CodegenConstants.INVOKER_PACKAGE, this.getInvokerPackage()); @@ -862,6 +864,19 @@ public Map postProcessModelsEnum(Map objs) { return objs; } + @Override + public void addImportsToOneOfInterface(List> imports) { + if (additionalProperties.containsKey(JACKSON)) { + for (String i : Arrays.asList("JsonSubTypes", "JsonTypeInfo")) { + Map oneImport = new HashMap<>(); + oneImport.put("import", importMapping.get(i)); + if (!imports.contains(oneImport)) { + imports.add(oneImport); + } + } + } + } + public void setUseBeanValidation(boolean useBeanValidation) { this.useBeanValidation = useBeanValidation; } diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/oneof_interface.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/oneof_interface.mustache new file mode 100644 index 000000000000..02deb483d5fd --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/oneof_interface.mustache @@ -0,0 +1,6 @@ +{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{>typeInfoAnnotation}}{{>xmlAnnotation}} +public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} { + {{#discriminator}} + public {{propertyType}} {{propertyGetter}}(); + {{/discriminator}} +} diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/model.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/model.mustache index 78c3c9ae19d4..8b39ebd13c30 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/model.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/model.mustache @@ -37,7 +37,7 @@ import org.springframework.hateoas.RepresentationModel; {{>enumOuterClass}} {{/isEnum}} {{^isEnum}} -{{>pojo}} +{{#vendorExtensions.x-is-one-of-interface}}{{>oneof_interface}}{{/vendorExtensions.x-is-one-of-interface}}{{^vendorExtensions.x-is-one-of-interface}}{{>pojo}}{{/vendorExtensions.x-is-one-of-interface}} {{/isEnum}} {{/model}} {{/models}} diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache new file mode 100644 index 000000000000..02deb483d5fd --- /dev/null +++ b/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache @@ -0,0 +1,6 @@ +{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{>typeInfoAnnotation}}{{>xmlAnnotation}} +public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} { + {{#discriminator}} + public {{propertyType}} {{propertyGetter}}(); + {{/discriminator}} +} diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache index df0b98bfaf7f..4ca92f96e26a 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache @@ -3,7 +3,7 @@ */{{#description}} @ApiModel(description = "{{{.}}}"){{/description}} {{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}}{{>additionalModelTypeAnnotations}} -public class {{classname}} {{#parent}}extends {{{.}}}{{/parent}}{{^parent}}{{#hateoas}}extends RepresentationModel<{{classname}}> {{/hateoas}}{{/parent}} {{#serializableModel}}implements Serializable{{/serializableModel}} { +public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{^parent}}{{#hateoas}}extends RepresentationModel<{{classname}}> {{/hateoas}}{{/parent}}{{#vendorExtensions.x-implements}}{{#-first}}implements {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{#-last}} {{/-last}}{{/vendorExtensions.x-implements}}{ {{#serializableModel}} private static final long serialVersionUID = 1L; diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java index 48fa9cadcfbb..f2b177854180 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java @@ -17,6 +17,7 @@ package org.openapitools.codegen.java; +import static org.openapitools.codegen.TestUtils.assertFileContains; import static org.openapitools.codegen.TestUtils.validateJavaSourceFiles; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -55,6 +56,7 @@ import org.openapitools.codegen.config.CodegenConfigurator; import org.openapitools.codegen.languages.AbstractJavaCodegen; import org.openapitools.codegen.languages.JavaClientCodegen; +import org.openapitools.codegen.languages.SpringCodegen; import org.testng.Assert; import org.testng.annotations.Test; @@ -1164,4 +1166,78 @@ public void testWebClientWithUseAbstractionForFiles() throws IOException { "formParams.add(\"file\", file);" ); } + + @Test + public void reactiveOneOfInheritance() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + String outputPath = output.getAbsolutePath().replace('\\', '/'); + + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/composed-oneof.yaml"); + final SpringCodegen codegen = new SpringCodegen(); + codegen.setOpenAPI(openAPI); + codegen.setOutputDir(output.getAbsolutePath()); + + codegen.additionalProperties().put(SpringCodegen.REACTIVE, "true"); + codegen.additionalProperties().put(CodegenConstants.GENERATE_ALIAS_AS_MODEL, "false"); + + ClientOptInput input = new ClientOptInput(); + input.openAPI(openAPI); + input.config(codegen); + + DefaultGenerator generator = new DefaultGenerator(); + + generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); + + List files = generator.opts(input).generate(); + + Assert.assertEquals(files.size(), 4); + TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/CustomOneOfArraySchemaOneOf.java"); + TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/CustomOneOfSchema.java"); + TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/ObjA.java"); + TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/ObjB.java"); + assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/ObjA.java"), "implements CustomOneOfArraySchemaOneOf, CustomOneOfSchema"); + assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/ObjB.java"), "implements CustomOneOfArraySchemaOneOf, CustomOneOfSchema"); + } + + @Test + public void nonreactiveOneOfInheritance() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + String outputPath = output.getAbsolutePath().replace('\\', '/'); + + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/composed-oneof.yaml"); + final SpringCodegen codegen = new SpringCodegen(); + codegen.setOpenAPI(openAPI); + codegen.setOutputDir(output.getAbsolutePath()); + + codegen.additionalProperties().put(SpringCodegen.REACTIVE, "false"); + codegen.additionalProperties().put(CodegenConstants.GENERATE_ALIAS_AS_MODEL, "false"); + + ClientOptInput input = new ClientOptInput(); + input.openAPI(openAPI); + input.config(codegen); + + DefaultGenerator generator = new DefaultGenerator(); + + generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); + + List files = generator.opts(input).generate(); + + Assert.assertEquals(files.size(), 4); + TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/CustomOneOfArraySchemaOneOf.java"); + TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/CustomOneOfSchema.java"); + TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/ObjA.java"); + TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/ObjB.java"); + assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/ObjA.java"), "implements CustomOneOfArraySchemaOneOf, CustomOneOfSchema"); + assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/ObjB.java"), "implements CustomOneOfArraySchemaOneOf, CustomOneOfSchema"); + } } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java index 3e8d89772093..b276f05a812c 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java @@ -18,6 +18,7 @@ package org.openapitools.codegen.java.spring; import io.swagger.parser.OpenAPIParser; +import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.info.Info; @@ -34,6 +35,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -354,6 +356,7 @@ public void testAdditionalPropertiesPutForConfigValues() throws Exception { openAPI.addServersItem(new Server().url("https://api.abcde.xy:8082/v2")); openAPI.setInfo(new Info()); openAPI.getInfo().setTitle("Some test API"); + openAPI.setComponents(new Components().schemas(new HashMap<>())); codegen.preprocessOpenAPI(openAPI); Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.TRUE); @@ -451,6 +454,7 @@ public void testInitialConfigValues() throws Exception { OpenAPI openAPI = new OpenAPI(); openAPI.addServersItem(new Server().url("https://api.abcde.xy:8082/v2")); openAPI.setInfo(new Info()); + openAPI.setComponents(new Components().schemas(new HashMap<>())); codegen.preprocessOpenAPI(openAPI); Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.FALSE); @@ -653,4 +657,74 @@ public void reactiveMapTypeRequestMonoTest() throws IOException { assertFileNotContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/SomeApi.java"), "Mono"); assertFileNotContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/SomeApiDelegate.java"), "Mono"); } + + @Test + public void reactiveOneOfInheritance() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + String outputPath = output.getAbsolutePath().replace('\\', '/'); + + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/composed-oneof.yaml"); + final SpringCodegen codegen = new SpringCodegen(); + codegen.setOpenAPI(openAPI); + codegen.setOutputDir(output.getAbsolutePath()); + + codegen.additionalProperties().put(SpringCodegen.REACTIVE, "true"); + + ClientOptInput input = new ClientOptInput(); + input.openAPI(openAPI); + input.config(codegen); + + DefaultGenerator generator = new DefaultGenerator(); + + generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); + + List files = generator.opts(input).generate(); + + Assert.assertEquals(files.size(), 4); + TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/CustomOneOfArraySchemaOneOf.java"); + TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/CustomOneOfSchema.java"); + TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/ObjA.java"); + TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/ObjB.java"); + assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/ObjA.java"), "implements CustomOneOfArraySchemaOneOf, CustomOneOfSchema"); + assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/ObjB.java"), "implements CustomOneOfArraySchemaOneOf, CustomOneOfSchema"); + } + + @Test + public void nonreactiveOneOfInheritance() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + String outputPath = output.getAbsolutePath().replace('\\', '/'); + + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/composed-oneof.yaml"); + final SpringCodegen codegen = new SpringCodegen(); + codegen.setOpenAPI(openAPI); + codegen.setOutputDir(output.getAbsolutePath()); + + ClientOptInput input = new ClientOptInput(); + input.openAPI(openAPI); + input.config(codegen); + + DefaultGenerator generator = new DefaultGenerator(); + + generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); + + List files = generator.opts(input).generate(); + + Assert.assertEquals(files.size(), 4); + TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/CustomOneOfArraySchemaOneOf.java"); + TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/CustomOneOfSchema.java"); + TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/ObjA.java"); + TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/ObjB.java"); + assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/ObjA.java"), "implements CustomOneOfArraySchemaOneOf, CustomOneOfSchema"); + assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/ObjB.java"), "implements CustomOneOfArraySchemaOneOf, CustomOneOfSchema"); + } } From 51e981557cd7310979b7bee7aa8ed3df13306b68 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 11 Sep 2021 00:44:25 +0300 Subject: [PATCH 21/25] TAP-232 Added tests for issues 2906 and 8647 --- .../codegen/languages/JavaClientCodegen.java | 2 + .../codegen/java/JavaClientCodegenTest.java | 100 +++++++---------- .../java/spring/SpringCodegenTest.java | 30 +++++ .../src/test/resources/3_0/issue_2906.yaml | 105 ++++++++++++++++++ 4 files changed, 178 insertions(+), 59 deletions(-) create mode 100644 modules/openapi-generator/src/test/resources/3_0/issue_2906.yaml diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java index 85f5bcffde38..f413eca115ae 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java @@ -129,6 +129,8 @@ public JavaClientCodegen() { artifactId = "openapi-java-client"; apiPackage = "org.openapitools.client.api"; modelPackage = "org.openapitools.client.model"; + useOneOfInterfaces = true; + addOneOfInterfaceImports = true; // cliOptions default redefinition need to be updated updateOption(CodegenConstants.INVOKER_PACKAGE, this.getInvokerPackage()); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java index f2b177854180..c67c79ab83d7 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java @@ -17,7 +17,6 @@ package org.openapitools.codegen.java; -import static org.openapitools.codegen.TestUtils.assertFileContains; import static org.openapitools.codegen.TestUtils.validateJavaSourceFiles; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -56,8 +55,8 @@ import org.openapitools.codegen.config.CodegenConfigurator; import org.openapitools.codegen.languages.AbstractJavaCodegen; import org.openapitools.codegen.languages.JavaClientCodegen; -import org.openapitools.codegen.languages.SpringCodegen; import org.testng.Assert; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.google.common.collect.ImmutableMap; @@ -1167,77 +1166,60 @@ public void testWebClientWithUseAbstractionForFiles() throws IOException { ); } - @Test - public void reactiveOneOfInheritance() throws IOException { - File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); - output.deleteOnExit(); - String outputPath = output.getAbsolutePath().replace('\\', '/'); - - final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/composed-oneof.yaml"); - final SpringCodegen codegen = new SpringCodegen(); - codegen.setOpenAPI(openAPI); - codegen.setOutputDir(output.getAbsolutePath()); - - codegen.additionalProperties().put(SpringCodegen.REACTIVE, "true"); - codegen.additionalProperties().put(CodegenConstants.GENERATE_ALIAS_AS_MODEL, "false"); - - ClientOptInput input = new ClientOptInput(); - input.openAPI(openAPI); - input.config(codegen); - - DefaultGenerator generator = new DefaultGenerator(); - - generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true"); - generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); - generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); - generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false"); - generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); + // Currently, not for NATIVE, JERSEY2 or MICROPROFILE + @DataProvider(name = "libraries") + public static Object[][] librariesProviderMethod() { + return new Object[][] { + { JavaClientCodegen.FEIGN }, + { JavaClientCodegen.GOOGLE_API_CLIENT }, + { JavaClientCodegen.JERSEY1 }, + { JavaClientCodegen.OKHTTP_GSON }, + { JavaClientCodegen.RESTEASY }, + { JavaClientCodegen.RESTTEMPLATE }, + { JavaClientCodegen.WEBCLIENT }, + { JavaClientCodegen.REST_ASSURED }, + { JavaClientCodegen.RETROFIT_2 }, + { JavaClientCodegen.VERTX }, + { JavaClientCodegen.APACHE }, + }; + } - List files = generator.opts(input).generate(); + // issue https://github.com/OpenAPITools/openapi-generator/issues/2906 + @Test(dataProvider = "libraries") + public void oneOfClassesGeneration(String library) throws IOException { - Assert.assertEquals(files.size(), 4); - TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/CustomOneOfArraySchemaOneOf.java"); - TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/CustomOneOfSchema.java"); - TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/ObjA.java"); - TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/ObjB.java"); - assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/ObjA.java"), "implements CustomOneOfArraySchemaOneOf, CustomOneOfSchema"); - assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/ObjB.java"), "implements CustomOneOfArraySchemaOneOf, CustomOneOfSchema"); - } + Map properties = new HashMap<>(); + properties.put(JavaClientCodegen.JAVA8_MODE, true); + properties.put(CodegenConstants.MODEL_PACKAGE, "xyz.abcdef.model"); + properties.put(JavaClientCodegen.USE_ABSTRACTION_FOR_FILES, true); - @Test - public void nonreactiveOneOfInheritance() throws IOException { - File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + File output = Files.createTempDirectory("test").toFile(); output.deleteOnExit(); - String outputPath = output.getAbsolutePath().replace('\\', '/'); - - final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/composed-oneof.yaml"); - final SpringCodegen codegen = new SpringCodegen(); - codegen.setOpenAPI(openAPI); - codegen.setOutputDir(output.getAbsolutePath()); - codegen.additionalProperties().put(SpringCodegen.REACTIVE, "false"); - codegen.additionalProperties().put(CodegenConstants.GENERATE_ALIAS_AS_MODEL, "false"); + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName("java") + .setLibrary(library) + .setAdditionalProperties(properties) + .setInputSpec("src/test/resources/3_0/issue_2906.yaml") + .setOutputDir(output.getAbsolutePath().replace("\\", "/")); - ClientOptInput input = new ClientOptInput(); - input.openAPI(openAPI); - input.config(codegen); DefaultGenerator generator = new DefaultGenerator(); - generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true"); generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false"); generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); - List files = generator.opts(input).generate(); + List files = generator.opts(configurator.toClientOptInput()).generate(); + files.forEach(File::deleteOnExit); - Assert.assertEquals(files.size(), 4); - TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/CustomOneOfArraySchemaOneOf.java"); - TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/CustomOneOfSchema.java"); - TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/ObjA.java"); - TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/ObjB.java"); - assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/ObjA.java"), "implements CustomOneOfArraySchemaOneOf, CustomOneOfSchema"); - assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/ObjB.java"), "implements CustomOneOfArraySchemaOneOf, CustomOneOfSchema"); + Path generatedOneOf = Paths.get(output + "/src/main/java/xyz/abcdef/model/HomeSofaStyleOneOf.java"); + Path sofaModel = Paths.get(output + "/src/main/java/xyz/abcdef/model/Sofa1.java"); + TestUtils.assertFileContains(generatedOneOf, "getStyleType"); + TestUtils.assertFileContains(sofaModel, + "implements HomeSofaStyleOneOf", + "import xyz.abcdef.model.HomeSofaStyleOneOf" + ); } } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java index b276f05a812c..79f6cb14ac35 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java @@ -658,6 +658,36 @@ public void reactiveMapTypeRequestMonoTest() throws IOException { assertFileNotContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/SomeApiDelegate.java"), "Mono"); } + // issue https://github.com/OpenAPITools/openapi-generator/issues/8647 + @Test + public void oneOfClassesGeneration() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + String outputPath = output.getAbsolutePath().replace('\\', '/'); + + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_2906.yaml"); + final SpringCodegen codegen = new SpringCodegen(); + codegen.setOpenAPI(openAPI); + codegen.setOutputDir(output.getAbsolutePath()); + + ClientOptInput input = new ClientOptInput(); + input.openAPI(openAPI); + input.config(codegen); + + DefaultGenerator generator = new DefaultGenerator(); + + generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); + + generator.opts(input).generate(); + + assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/HomeSofaStyleOneOf.java"), "getStyleType"); + assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/Sofa1.java"), "implements HomeSofaStyleOneOf"); + } + @Test public void reactiveOneOfInheritance() throws IOException { File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); diff --git a/modules/openapi-generator/src/test/resources/3_0/issue_2906.yaml b/modules/openapi-generator/src/test/resources/3_0/issue_2906.yaml new file mode 100644 index 000000000000..d48bda8ffcfd --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/issue_2906.yaml @@ -0,0 +1,105 @@ +openapi: 3.0.0 +servers: +- description: Controller URL + url: https://localhost:8080/testApiDesign/ +info: + description: Apis + version: "1.0.0" + title: "Enum and Discriminator testing" + termsOfService: 'https://www.appdynamics.com/terms/' + contact: + email: demo@demo.com + license: + name: Apache 2.0 + url: 'http://www.apache.org/licenses/LICENSE-2.0.html' +tags: +- name: home + description: Manage your home + externalDocs: + description: Find out more + url: 'https://www.home.com' +paths: + /home : + post: + tags: + - home + summary: Create a new home + description: Creates a new home for given payload and returns the ID + operationId: createHome + responses: + '201': + description: Home created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Home' + '400': + description: Bad Request + '401': + description: Unauthorized + '403': + description: Forbidden + requestBody: + $ref: '#/components/requestBodies/Home' +externalDocs: + description: Find out more about Swagger + url: 'https://swagger.io' +components: + schemas: + Home: + type: object + properties: + name: + $ref: '#/components/schemas/Names' + sofaStyle: + oneOf: + - $ref: '#/components/schemas/Sofa1' + - $ref: '#/components/schemas/Sofa2' + discriminator: + propertyName: styleType + required: + - name + - sofaStyle + Names: + type: object + properties: + name: + type: string + enum: + - "home1" + - "home2" + required: + - name + SofaStyleType: + type: object + properties: + styleType: + type: string + required: + - styleType + discriminator: + propertyName: styleType + Sofa1: + allOf: + - $ref: '#/components/schemas/SofaStyleType' + - type: object + properties: + identifier: + type: string + enum: + - "big" + Sofa2: + allOf: + - $ref: '#/components/schemas/SofaStyleType' + - type: object + properties: + identifier: + type: string + enum: + - "small" + requestBodies: + Home: + content: + application/json: + schema: + $ref: '#/components/schemas/Home' \ No newline at end of file From 2979c38e06e1149c6da29aa995a82b81a188af48 Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 17 Sep 2021 19:35:33 +0300 Subject: [PATCH 22/25] TAP-232 Fixed inline OneOf, added tests for the majority of cases, added jackson DEDUCTION for cases without discriminator --- .../openapitools/codegen/DefaultCodegen.java | 14 +- .../languages/AbstractJavaCodegen.java | 26 ++- .../resources/Java/oneof_interface.mustache | 4 +- .../Java/typeInfoAnnotation.mustache | 11 +- .../spring-boot/oneof_interface.mustache | 4 +- .../JavaSpring/oneof_interface.mustache | 4 +- .../JavaSpring/typeInfoAnnotation.mustache | 6 + .../codegen/DefaultCodegenTest.java | 5 + .../codegen/java/JavaClientCodegenTest.java | 154 ++++++++++++----- .../java/spring/SpringCodegenTest.java | 159 +++++++++--------- .../src/test/resources/3_0/issue_2906.yaml | 105 ------------ .../resources/3_0/oneOf_inherited_class.yaml | 46 +++++ .../3_0/oneOf_inherited_class_array.yaml | 50 ++++++ .../test/resources/3_0/oneOf_interface.yaml | 52 ++++++ .../resources/3_0/oneOf_interface_array.yaml | 51 ++++++ .../3_0/oneOf_with_allOf_inherited_class.yaml | 46 +++++ ...neOf_with_allOf_inherited_class_array.yaml | 50 ++++++ 17 files changed, 555 insertions(+), 232 deletions(-) delete mode 100644 modules/openapi-generator/src/test/resources/3_0/issue_2906.yaml create mode 100644 modules/openapi-generator/src/test/resources/3_0/oneOf_inherited_class.yaml create mode 100644 modules/openapi-generator/src/test/resources/3_0/oneOf_inherited_class_array.yaml create mode 100644 modules/openapi-generator/src/test/resources/3_0/oneOf_interface.yaml create mode 100644 modules/openapi-generator/src/test/resources/3_0/oneOf_interface_array.yaml create mode 100644 modules/openapi-generator/src/test/resources/3_0/oneOf_with_allOf_inherited_class.yaml create mode 100644 modules/openapi-generator/src/test/resources/3_0/oneOf_with_allOf_inherited_class_array.yaml diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 789cbdcf755c..176fdd45a3dd 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -2403,6 +2403,18 @@ public CodegenModel fromModel(String name, Schema schema) { m.isAlias = (typeAliases.containsKey(name) || isAliasOfSimpleTypes(schema)); // check if the unaliased schema is an alias of simple OAS types m.setDiscriminator(createDiscriminator(name, schema, this.openAPI)); + if (ModelUtils.isComposedSchema(schema) + && m.discriminator == null + && schema.getExtensions() != null + && schema.getExtensions().containsKey("x-one-of-name")) { + m.vendorExtensions.put("x-deduction", true); + List deductionModelNames = new ArrayList<>(); + ((ComposedSchema) schema).getOneOf().forEach(model -> { + String modelName = ModelUtils.getSimpleRef(model.get$ref()); + deductionModelNames.add(toModelName(modelName)); + }); + m.vendorExtensions.put("x-deduction-model-names", deductionModelNames); + } if (!this.getLegacyDiscriminatorBehavior()) { m.addDiscriminatorMappedModelsImports(); } @@ -3144,7 +3156,7 @@ protected CodegenDiscriminator createDiscriminator(String schemaName, Schema sch } } // if there are composed oneOf/anyOf schemas, add them to this discriminator - if (ModelUtils.isComposedSchema(schema) && !this.getLegacyDiscriminatorBehavior()) { + if (ModelUtils.isComposedSchema(schema)) { List otherDescendants = getOneOfAnyOfDescendants(schemaName, discPropName, (ComposedSchema) schema, openAPI); for (MappedModel otherDescendant : otherDescendants) { if (!uniqueDescendants.contains(otherDescendant)) { diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java index 748e30815490..fa6c8a7a210c 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java @@ -1363,8 +1363,30 @@ public void preprocessOpenAPI(OpenAPI openAPI) { } for (Operation operation : path.readOperations()) { LOGGER.info("Processing operation {}", operation.getOperationId()); - if (hasBodyParameter(openAPI, operation) || hasFormParameter(openAPI, operation)) { - String defaultContentType = hasFormParameter(openAPI, operation) ? "application/x-www-form-urlencoded" : "application/json"; + boolean hasBodyParameter = hasBodyParameter(openAPI, operation); + boolean hasFormParameter = hasFormParameter(openAPI, operation); + // OpenAPI parser do not add Inline One Of models in Operations to Components/Schemas + if (hasBodyParameter) { + RequestBody requestBody = operation.getRequestBody(); + Optional.ofNullable(requestBody) + .map(ModelUtils::getSchemaFromRequestBody) + .ifPresent(schema -> { + if (schema instanceof ComposedSchema + && ((ComposedSchema) schema).getProperties() == null + && Optional.ofNullable(schema.getExtensions()).map(m -> m.containsKey("x-one-of-name")).orElse(false) + ) { + String oneOfModelName = (String) schema.getExtensions().get("x-one-of-name"); + Schema originalSchema = ModelUtils.getSchemaFromRequestBody(requestBody); + Schema replacedSchema = new Schema<>().$ref("#/components/schemas/" + oneOfModelName); + requestBody.getContent().values().forEach(mediaType -> { + mediaType.setSchema(replacedSchema); + ModelUtils.getSchemas(openAPI).put(oneOfModelName, originalSchema); + }); + } + }); + } + if (hasBodyParameter || hasFormParameter) { + String defaultContentType = hasFormParameter ? "application/x-www-form-urlencoded" : "application/json"; List consumes = new ArrayList<>(getConsumesInfo(openAPI, operation)); String contentType = consumes == null || consumes.isEmpty() ? defaultContentType : consumes.get(0); operation.addExtension("x-contentType", contentType); diff --git a/modules/openapi-generator/src/main/resources/Java/oneof_interface.mustache b/modules/openapi-generator/src/main/resources/Java/oneof_interface.mustache index 02deb483d5fd..fe696c971606 100644 --- a/modules/openapi-generator/src/main/resources/Java/oneof_interface.mustache +++ b/modules/openapi-generator/src/main/resources/Java/oneof_interface.mustache @@ -1,6 +1,6 @@ {{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{>typeInfoAnnotation}}{{>xmlAnnotation}} public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} { - {{#discriminator}} + {{^vendorExtensions.x-deduction}}{{#discriminator}} public {{propertyType}} {{propertyGetter}}(); - {{/discriminator}} + {{/discriminator}}{{/vendorExtensions.x-deduction}} } diff --git a/modules/openapi-generator/src/main/resources/Java/typeInfoAnnotation.mustache b/modules/openapi-generator/src/main/resources/Java/typeInfoAnnotation.mustache index 63eb42ea5001..2eda38e95cfb 100644 --- a/modules/openapi-generator/src/main/resources/Java/typeInfoAnnotation.mustache +++ b/modules/openapi-generator/src/main/resources/Java/typeInfoAnnotation.mustache @@ -1,6 +1,15 @@ {{#jackson}} +{{^vendorExtensions.x-deduction}} @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "{{{discriminator.propertyBaseName}}}", visible = true) +{{/vendorExtensions.x-deduction}}{{#vendorExtensions.x-deduction}} +@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION) +@JsonSubTypes({ +{{#vendorExtensions.x-deduction-model-names}} + @JsonSubTypes.Type(value = {{.}}.class, name = "{{.}}"), +{{/vendorExtensions.x-deduction-model-names}} +}) +{{/vendorExtensions.x-deduction}} {{#discriminator.mappedModels}} {{#-first}} @JsonSubTypes({ @@ -13,4 +22,4 @@ {{#isClassnameSanitized}} @JsonTypeName("{{name}}") {{/isClassnameSanitized}} -{{/jackson}} +{{/jackson}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/oneof_interface.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/oneof_interface.mustache index 02deb483d5fd..fe696c971606 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/oneof_interface.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-boot/oneof_interface.mustache @@ -1,6 +1,6 @@ {{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{>typeInfoAnnotation}}{{>xmlAnnotation}} public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} { - {{#discriminator}} + {{^vendorExtensions.x-deduction}}{{#discriminator}} public {{propertyType}} {{propertyGetter}}(); - {{/discriminator}} + {{/discriminator}}{{/vendorExtensions.x-deduction}} } diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache index 02deb483d5fd..fe696c971606 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/oneof_interface.mustache @@ -1,6 +1,6 @@ {{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{>typeInfoAnnotation}}{{>xmlAnnotation}} public interface {{classname}} {{#vendorExtensions.x-implements}}{{#-first}}extends {{{.}}}{{/-first}}{{^-first}}, {{{.}}}{{/-first}}{{/vendorExtensions.x-implements}} { - {{#discriminator}} + {{^vendorExtensions.x-deduction}}{{#discriminator}} public {{propertyType}} {{propertyGetter}}(); - {{/discriminator}} + {{/discriminator}}{{/vendorExtensions.x-deduction}} } diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/typeInfoAnnotation.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/typeInfoAnnotation.mustache index 81c2ba05f903..2aee24b387b2 100644 --- a/modules/openapi-generator/src/main/resources/JavaSpring/typeInfoAnnotation.mustache +++ b/modules/openapi-generator/src/main/resources/JavaSpring/typeInfoAnnotation.mustache @@ -1,8 +1,14 @@ {{#jackson}} +{{^vendorExtensions.x-deduction}} @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "{{{discriminator.propertyBaseName}}}", visible = true) +{{/vendorExtensions.x-deduction}}{{#vendorExtensions.x-deduction}} +@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION){{/vendorExtensions.x-deduction}} @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}}"), {{/discriminator.mappedModels}} + {{#vendorExtensions.x-deduction-model-names}} + @JsonSubTypes.Type(value = {{.}}.class, name = "{{.}}"), + {{/vendorExtensions.x-deduction-model-names}} }){{/jackson}} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java index 6d74693c21a3..c8ce597df0d4 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java @@ -1137,10 +1137,15 @@ public void testComposedSchemaAllOfDiscriminatorMapLegacy() { Assert.assertNull(reptile.discriminator); // the MyPets discriminator contains Cat and Lizard + List myPetsModelNames = Arrays.asList("Cat", "Lizard"); CodegenDiscriminator myPetDisc = new CodegenDiscriminator(); myPetDisc.setPropertyName(propertyName); myPetDisc.setPropertyBaseName(propertyBaseName); hs.clear(); + for (String myPetsModelName: myPetsModelNames) { + hs.add(new CodegenDiscriminator.MappedModel(myPetsModelName, codegen.toModelName(myPetsModelName))); + } + myPetDisc.setMappedModels(hs); modelName = "MyPets"; sc = openAPI.getComponents().getSchemas().get(modelName); CodegenModel myPets = codegen.fromModel(modelName, sc); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java index c67c79ab83d7..1e7b4269dde1 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java @@ -17,8 +17,10 @@ package org.openapitools.codegen.java; +import static org.openapitools.codegen.TestUtils.assertFileContains; import static org.openapitools.codegen.TestUtils.validateJavaSourceFiles; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; import java.io.File; @@ -43,6 +45,7 @@ import java.util.stream.Collectors; import org.openapitools.codegen.ClientOptInput; +import org.openapitools.codegen.CodegenConfig; import org.openapitools.codegen.CodegenConstants; import org.openapitools.codegen.CodegenModel; import org.openapitools.codegen.CodegenOperation; @@ -55,6 +58,8 @@ import org.openapitools.codegen.config.CodegenConfigurator; import org.openapitools.codegen.languages.AbstractJavaCodegen; import org.openapitools.codegen.languages.JavaClientCodegen; +import org.openapitools.codegen.languages.SpringCodegen; +import org.openapitools.codegen.utils.ModelUtils; import org.testng.Assert; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -1166,60 +1171,129 @@ public void testWebClientWithUseAbstractionForFiles() throws IOException { ); } - // Currently, not for NATIVE, JERSEY2 or MICROPROFILE - @DataProvider(name = "libraries") + @Test(dataProvider = "librariesToSpecificationsCartesianProduct") + public void oneOfModelsGeneration(String library, String specificationFile) throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + String outputPath = output.getAbsolutePath().replace('\\', '/'); + + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/" + specificationFile); + final CodegenConfig codegen = new JavaClientCodegen(); + ((JavaClientCodegen)codegen).setSerializationLibrary(JavaClientCodegen.SERIALIZATION_LIBRARY_JACKSON); + codegen.setLibrary(library); + codegen.setOpenAPI(openAPI); + codegen.setOutputDir(output.getAbsolutePath()); + + ClientOptInput input = new ClientOptInput(); + input.openAPI(openAPI); + input.config(codegen); + + DefaultGenerator generator = new DefaultGenerator(); + + generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true"); + generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); + + generator.opts(input).generate(); + + final String responseCode = "200"; + final String extension = "x-one-of-name"; + final Operation operation = openAPI.getPaths().get("/addFruits").getPost(); + List oneOfModels = new ArrayList<>(); + + // If response body contains oneOf definition - add OneOf model + final ApiResponse apiResponse = operation.getResponses().get(responseCode); + final Schema responseSchema = ModelUtils.getSchemaFromResponse(apiResponse); + if (ModelUtils.isArraySchema(responseSchema)) { + Schema responseItems = ((ArraySchema) responseSchema).getItems(); + if (responseItems.get$ref() == null) { + oneOfModels.add((String) (responseItems.getExtensions().get(extension))); + } + } + + // If request body contains oneOf definition - add OneOf model + final RequestBody requestBody = operation.getRequestBody(); + final Schema requestSchema = ModelUtils.getSchemaFromRequestBody(requestBody); + if (ModelUtils.isArraySchema(requestSchema)) { + Schema requestItems = ((ArraySchema) requestSchema).getItems(); + if (requestItems.get$ref() == null) { + oneOfModels.add((String) (requestItems.getExtensions().get(extension))); + } + } + + List models = new ArrayList<>(); + // If model contains discriminator - add to OneOf models, otherwise - generic models + openAPI.getComponents().getSchemas().forEach((modelName, modelSchema) -> { + if (modelSchema.getDiscriminator() != null || (modelSchema.getExtensions() != null && modelSchema.getExtensions().containsKey("x-one-of-name"))) { + oneOfModels.add(modelName); + } else { + // exclude allOf models + if (!modelName.contains("_")) { + models.add(modelName); + } + } + }); + assertFalse(oneOfModels.isEmpty()); + + final String pathFormat = "%s/%s/%s.java"; + final String relativePath = "/src/main/java/org/openapitools/client/model"; + final String jacksonSubTypeFormat = "@JsonSubTypes.Type(value = %s.class, name = \"%s\"),"; + + models.forEach(modelName -> { + final String modelPath = String.format(Locale.ROOT, pathFormat, outputPath, relativePath, modelName); + + oneOfModels.forEach(oneOfModelName -> { + // Models should implement all linked OneOf interfaces + assertFileContains(Paths.get(modelPath), oneOfModelName); + + // OneOf model should contain relevant jackson annotations + final String oneOfPath = String.format(Locale.ROOT, pathFormat, outputPath, relativePath, oneOfModelName); + assertFileContains(Paths.get(oneOfPath), String.format(Locale.ROOT, jacksonSubTypeFormat, modelName, modelName)); + }); + }); + } + + // Currently, not for NATIVE, JERSEY2, OKHTTP_GSON, MICROPROFILE or RETROFIT2 public static Object[][] librariesProviderMethod() { return new Object[][] { { JavaClientCodegen.FEIGN }, { JavaClientCodegen.GOOGLE_API_CLIENT }, { JavaClientCodegen.JERSEY1 }, - { JavaClientCodegen.OKHTTP_GSON }, { JavaClientCodegen.RESTEASY }, { JavaClientCodegen.RESTTEMPLATE }, { JavaClientCodegen.WEBCLIENT }, { JavaClientCodegen.REST_ASSURED }, - { JavaClientCodegen.RETROFIT_2 }, { JavaClientCodegen.VERTX }, { JavaClientCodegen.APACHE }, }; } - // issue https://github.com/OpenAPITools/openapi-generator/issues/2906 - @Test(dataProvider = "libraries") - public void oneOfClassesGeneration(String library) throws IOException { - - Map properties = new HashMap<>(); - properties.put(JavaClientCodegen.JAVA8_MODE, true); - properties.put(CodegenConstants.MODEL_PACKAGE, "xyz.abcdef.model"); - properties.put(JavaClientCodegen.USE_ABSTRACTION_FOR_FILES, true); - - File output = Files.createTempDirectory("test").toFile(); - output.deleteOnExit(); - - final CodegenConfigurator configurator = new CodegenConfigurator() - .setGeneratorName("java") - .setLibrary(library) - .setAdditionalProperties(properties) - .setInputSpec("src/test/resources/3_0/issue_2906.yaml") - .setOutputDir(output.getAbsolutePath().replace("\\", "/")); - - - DefaultGenerator generator = new DefaultGenerator(); - generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true"); - generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); - generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); - generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false"); - generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); - - List files = generator.opts(configurator.toClientOptInput()).generate(); - files.forEach(File::deleteOnExit); + public static Object[][] specificationsProviderMethod() { + return new Object[][] { + { "oneOf_inherited_class.yaml" }, + { "oneOf_inherited_class_array.yaml" }, + { "oneOf_interface.yaml" }, + { "oneOf_interface_array.yaml" }, + { "oneOf_with_allOf_inherited_class.yaml" }, + { "oneOf_with_allOf_inherited_class_array.yaml" }, + }; + } - Path generatedOneOf = Paths.get(output + "/src/main/java/xyz/abcdef/model/HomeSofaStyleOneOf.java"); - Path sofaModel = Paths.get(output + "/src/main/java/xyz/abcdef/model/Sofa1.java"); - TestUtils.assertFileContains(generatedOneOf, "getStyleType"); - TestUtils.assertFileContains(sofaModel, - "implements HomeSofaStyleOneOf", - "import xyz.abcdef.model.HomeSofaStyleOneOf" - ); + // Combines each library to each specification case + @DataProvider(name = "librariesToSpecificationsCartesianProduct") + public static Object[][] librariesToSpecificationsCartesianProduct() { + Object[][] librariesProvider = librariesProviderMethod(); + Object[][] specProvider = specificationsProviderMethod(); + Object[][] cartesianProduct = new Object[librariesProvider.length * specProvider.length][2]; + int i = 0; + for (Object[] library : librariesProvider) { + for (Object[] spec : specProvider) { + cartesianProduct[i][0] = library[0]; + cartesianProduct[i++][1] = spec[0]; + } + } + return cartesianProduct; } } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java index 0df5568592f5..787f39868059 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java @@ -22,29 +22,40 @@ import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.media.ArraySchema; 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 io.swagger.v3.oas.models.servers.Server; import io.swagger.v3.parser.core.models.ParseOptions; import org.openapitools.codegen.*; import org.openapitools.codegen.languages.SpringCodegen; import org.openapitools.codegen.languages.features.CXFServerFeatures; +import org.openapitools.codegen.utils.ModelUtils; import org.testng.Assert; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; +import java.util.stream.Stream; import static java.util.stream.Collectors.groupingBy; import static org.openapitools.codegen.TestUtils.assertFileContains; import static org.openapitools.codegen.TestUtils.assertFileNotContains; import static org.openapitools.codegen.languages.SpringCodegen.RESPONSE_WRAPPER; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; public class SpringCodegenTest { @@ -728,80 +739,26 @@ public void shouldGenerateDefaultValueForEnumRequestParameter() throws IOExcepti "@RequestParam(value = \"TestParameter2\", required = false, defaultValue = \"BAR\")"); } - // issue https://github.com/OpenAPITools/openapi-generator/issues/8647 - @Test - public void oneOfClassesGeneration() throws IOException { - File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); - output.deleteOnExit(); - String outputPath = output.getAbsolutePath().replace('\\', '/'); - - final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_2906.yaml"); - final SpringCodegen codegen = new SpringCodegen(); - codegen.setOpenAPI(openAPI); - codegen.setOutputDir(output.getAbsolutePath()); - - ClientOptInput input = new ClientOptInput(); - input.openAPI(openAPI); - input.config(codegen); - - DefaultGenerator generator = new DefaultGenerator(); - - generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true"); - generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); - generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); - generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false"); - generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); - - generator.opts(input).generate(); - - assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/HomeSofaStyleOneOf.java"), "getStyleType"); - assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/Sofa1.java"), "implements HomeSofaStyleOneOf"); - } - - @Test - public void reactiveOneOfInheritance() throws IOException { - File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); - output.deleteOnExit(); - String outputPath = output.getAbsolutePath().replace('\\', '/'); - - final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/composed-oneof.yaml"); - final SpringCodegen codegen = new SpringCodegen(); - codegen.setOpenAPI(openAPI); - codegen.setOutputDir(output.getAbsolutePath()); - - codegen.additionalProperties().put(SpringCodegen.REACTIVE, "true"); - - ClientOptInput input = new ClientOptInput(); - input.openAPI(openAPI); - input.config(codegen); - - DefaultGenerator generator = new DefaultGenerator(); - - generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true"); - generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); - generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); - generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false"); - generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); - - List files = generator.opts(input).generate(); - - Assert.assertEquals(files.size(), 4); - TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/CustomOneOfArraySchemaOneOf.java"); - TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/CustomOneOfSchema.java"); - TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/ObjA.java"); - TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/ObjB.java"); - assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/ObjA.java"), "implements CustomOneOfArraySchemaOneOf, CustomOneOfSchema"); - assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/ObjB.java"), "implements CustomOneOfArraySchemaOneOf, CustomOneOfSchema"); + @DataProvider(name = "specifications") + public static Object[][] specificationsProviderMethod() { + return new Object[][] { + { "oneOf_inherited_class.yaml" }, + { "oneOf_inherited_class_array.yaml" }, + { "oneOf_interface.yaml" }, + { "oneOf_interface_array.yaml" }, + { "oneOf_with_allOf_inherited_class.yaml" }, + { "oneOf_with_allOf_inherited_class_array.yaml" }, + }; } - @Test - public void nonreactiveOneOfInheritance() throws IOException { + @Test(dataProvider = "specifications") + public void oneOfModelsGeneration(String specificationFile) throws IOException { File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); output.deleteOnExit(); String outputPath = output.getAbsolutePath().replace('\\', '/'); - final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/composed-oneof.yaml"); - final SpringCodegen codegen = new SpringCodegen(); + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/" + specificationFile); + final CodegenConfig codegen = new SpringCodegen(); codegen.setOpenAPI(openAPI); codegen.setOutputDir(output.getAbsolutePath()); @@ -814,17 +771,65 @@ public void nonreactiveOneOfInheritance() throws IOException { generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true"); generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); - generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true"); generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); - List files = generator.opts(input).generate(); + generator.opts(input).generate(); - Assert.assertEquals(files.size(), 4); - TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/CustomOneOfArraySchemaOneOf.java"); - TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/CustomOneOfSchema.java"); - TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/ObjA.java"); - TestUtils.ensureContainsFile(files, output, "src/main/java/org/openapitools/model/ObjB.java"); - assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/ObjA.java"), "implements CustomOneOfArraySchemaOneOf, CustomOneOfSchema"); - assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/ObjB.java"), "implements CustomOneOfArraySchemaOneOf, CustomOneOfSchema"); + final String responseCode = "200"; + final String extension = "x-one-of-name"; + final Operation operation = openAPI.getPaths().get("/addFruits").getPost(); + List oneOfModels = new ArrayList<>(); + + // If response body contains oneOf definition - add OneOf model + final ApiResponse apiResponse = operation.getResponses().get(responseCode); + final Schema responseSchema = ModelUtils.getSchemaFromResponse(apiResponse); + if (ModelUtils.isArraySchema(responseSchema)) { + Schema responseItems = ((ArraySchema) responseSchema).getItems(); + if (responseItems.get$ref() == null) { + oneOfModels.add((String) (responseItems.getExtensions().get(extension))); + } + } + + // If request body contains oneOf definition - add OneOf model + final RequestBody requestBody = operation.getRequestBody(); + final Schema requestSchema = ModelUtils.getSchemaFromRequestBody(requestBody); + if (ModelUtils.isArraySchema(requestSchema)) { + Schema requestItems = ((ArraySchema) requestSchema).getItems(); + if (requestItems.get$ref() == null) { + oneOfModels.add((String) (requestItems.getExtensions().get(extension))); + } + } + + List models = new ArrayList<>(); + // If model contains discriminator - add to OneOf models, otherwise - generic models + openAPI.getComponents().getSchemas().forEach((modelName, modelSchema) -> { + if (modelSchema.getDiscriminator() != null || (modelSchema.getExtensions() != null && modelSchema.getExtensions().containsKey("x-one-of-name"))) { + oneOfModels.add(modelName); + } else { + // exclude allOf models + if (!modelName.contains("_")) { + models.add(modelName); + } + } + }); + assertFalse(oneOfModels.isEmpty()); + + final String pathFormat = "%s/%s/%s.java"; + final String relativePath = "/src/main/java/org/openapitools/model"; + final String jacksonSubTypeFormat = "@JsonSubTypes.Type(value = %s.class, name = \"%s\"),"; + + models.forEach(modelName -> { + final String modelPath = String.format(Locale.ROOT, pathFormat, outputPath, relativePath, modelName); + + oneOfModels.forEach(oneOfModelName -> { + // Models should implement all linked OneOf interfaces + assertFileContains(Paths.get(modelPath), oneOfModelName); + + // OneOf model should contain relevant jackson annotations + final String oneOfPath = String.format(Locale.ROOT, pathFormat, outputPath, relativePath, oneOfModelName); + assertFileContains(Paths.get(oneOfPath), String.format(Locale.ROOT, jacksonSubTypeFormat, modelName, modelName)); + }); + }); } } diff --git a/modules/openapi-generator/src/test/resources/3_0/issue_2906.yaml b/modules/openapi-generator/src/test/resources/3_0/issue_2906.yaml deleted file mode 100644 index d48bda8ffcfd..000000000000 --- a/modules/openapi-generator/src/test/resources/3_0/issue_2906.yaml +++ /dev/null @@ -1,105 +0,0 @@ -openapi: 3.0.0 -servers: -- description: Controller URL - url: https://localhost:8080/testApiDesign/ -info: - description: Apis - version: "1.0.0" - title: "Enum and Discriminator testing" - termsOfService: 'https://www.appdynamics.com/terms/' - contact: - email: demo@demo.com - license: - name: Apache 2.0 - url: 'http://www.apache.org/licenses/LICENSE-2.0.html' -tags: -- name: home - description: Manage your home - externalDocs: - description: Find out more - url: 'https://www.home.com' -paths: - /home : - post: - tags: - - home - summary: Create a new home - description: Creates a new home for given payload and returns the ID - operationId: createHome - responses: - '201': - description: Home created successfully - content: - application/json: - schema: - $ref: '#/components/schemas/Home' - '400': - description: Bad Request - '401': - description: Unauthorized - '403': - description: Forbidden - requestBody: - $ref: '#/components/requestBodies/Home' -externalDocs: - description: Find out more about Swagger - url: 'https://swagger.io' -components: - schemas: - Home: - type: object - properties: - name: - $ref: '#/components/schemas/Names' - sofaStyle: - oneOf: - - $ref: '#/components/schemas/Sofa1' - - $ref: '#/components/schemas/Sofa2' - discriminator: - propertyName: styleType - required: - - name - - sofaStyle - Names: - type: object - properties: - name: - type: string - enum: - - "home1" - - "home2" - required: - - name - SofaStyleType: - type: object - properties: - styleType: - type: string - required: - - styleType - discriminator: - propertyName: styleType - Sofa1: - allOf: - - $ref: '#/components/schemas/SofaStyleType' - - type: object - properties: - identifier: - type: string - enum: - - "big" - Sofa2: - allOf: - - $ref: '#/components/schemas/SofaStyleType' - - type: object - properties: - identifier: - type: string - enum: - - "small" - requestBodies: - Home: - content: - application/json: - schema: - $ref: '#/components/schemas/Home' \ No newline at end of file diff --git a/modules/openapi-generator/src/test/resources/3_0/oneOf_inherited_class.yaml b/modules/openapi-generator/src/test/resources/3_0/oneOf_inherited_class.yaml new file mode 100644 index 000000000000..e9a4a9360024 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/oneOf_inherited_class.yaml @@ -0,0 +1,46 @@ +openapi: 3.0.0 +info: + version: "1.0.0" + title: "API should have import for OneOf Class, models should extend OneOf Class" +paths: + /addFruits: + post: + responses: + '200': + description: Returns a list of fruits + content: + application/json: + schema: + $ref: '#/components/schemas/Fruit' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Fruit' +components: + schemas: + Fruit: + type: object + oneOf: + - $ref: '#/components/schemas/Apple' + - $ref: '#/components/schemas/Orange' + discriminator: + propertyName: kind + Apple: + type: object + properties: + kind: + type: string + identifier: + type: string + required: + - kind + Orange: + type: object + properties: + kind: + type: string + identifier2: + type: string + required: + - kind diff --git a/modules/openapi-generator/src/test/resources/3_0/oneOf_inherited_class_array.yaml b/modules/openapi-generator/src/test/resources/3_0/oneOf_inherited_class_array.yaml new file mode 100644 index 000000000000..6f56d61f530a --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/oneOf_inherited_class_array.yaml @@ -0,0 +1,50 @@ +openapi: 3.0.0 +info: + version: "1.0.0" + title: "API should have import for OneOf Class, models should extend OneOf Class" +paths: + /addFruits: + post: + responses: + '200': + description: Returns a list of fruits + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Fruit' + requestBody: + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Fruit' +components: + schemas: + Fruit: + type: object + oneOf: + - $ref: '#/components/schemas/Apple' + - $ref: '#/components/schemas/Orange' + discriminator: + propertyName: kind + Apple: + type: object + properties: + kind: + type: string + identifier: + type: string + required: + - kind + Orange: + type: object + properties: + kind: + type: string + identifier2: + type: string + required: + - kind diff --git a/modules/openapi-generator/src/test/resources/3_0/oneOf_interface.yaml b/modules/openapi-generator/src/test/resources/3_0/oneOf_interface.yaml new file mode 100644 index 000000000000..93d67198c866 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/oneOf_interface.yaml @@ -0,0 +1,52 @@ +openapi: 3.0.0 +info: + version: "1.0.0" + title: "OneOf interface should be generated, API has link to OneOf, models implement OneOf interface" +paths: + /addFruits: + post: + responses: + '200': + description: Returns a list of fruits + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/Apple' + - $ref: '#/components/schemas/Orange' + discriminator: + propertyName: kind + requestBody: + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/Apple' + - $ref: '#/components/schemas/Orange' +components: + schemas: + Apple: + type: object + properties: + kind: + type: string + identifier: + type: string + required: + - kind + Orange: + type: object + properties: + kind: + type: string + identifier2: + type: string + required: + - kind + Fruit: + type: object + oneOf: + - $ref: '#/components/schemas/Apple' + - $ref: '#/components/schemas/Orange' + discriminator: + propertyName: kind diff --git a/modules/openapi-generator/src/test/resources/3_0/oneOf_interface_array.yaml b/modules/openapi-generator/src/test/resources/3_0/oneOf_interface_array.yaml new file mode 100644 index 000000000000..77122d4b576d --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/oneOf_interface_array.yaml @@ -0,0 +1,51 @@ +openapi: 3.0.0 +info: + version: "1.0.0" + title: "OneOf interface should be generated, API has link to OneOf, models implement OneOf interface" +paths: + /addFruits: + post: + responses: + '200': + description: Returns a list of fruits + content: + application/json: + schema: + type: array + items: + oneOf: + - $ref: '#/components/schemas/Apple' + - $ref: '#/components/schemas/Orange' + discriminator: + propertyName: kind + requestBody: + content: + application/json: + schema: + type: array + items: + oneOf: + - $ref: '#/components/schemas/Apple' + - $ref: '#/components/schemas/Orange' + discriminator: + propertyName: kind +components: + schemas: + Apple: + type: object + properties: + kind: + type: string + identifier: + type: string + required: + - kind + Orange: + type: object + properties: + kind: + type: string + identifier2: + type: string + required: + - kind diff --git a/modules/openapi-generator/src/test/resources/3_0/oneOf_with_allOf_inherited_class.yaml b/modules/openapi-generator/src/test/resources/3_0/oneOf_with_allOf_inherited_class.yaml new file mode 100644 index 000000000000..76134cd5dd73 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/oneOf_with_allOf_inherited_class.yaml @@ -0,0 +1,46 @@ +openapi: 3.0.0 +info: + version: "1.0.0" + title: "API should have import for OneOf Class, models should extend OneOf Class" +paths: + /addFruits: + post: + responses: + '200': + description: Returns a list of fruits + content: + application/json: + schema: + $ref: '#/components/schemas/Fruit' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Fruit' +components: + schemas: + Apple: + type: object + allOf: + - $ref: '#/components/schemas/Fruit' + - type: object + properties: + identifier: + type: string + Orange: + type: object + allOf: + - $ref: '#/components/schemas/Fruit' + - type: object + properties: + identifier2: + type: string + Fruit: + type: object + properties: + kind: + type: string + required: + - kind + discriminator: + propertyName: kind diff --git a/modules/openapi-generator/src/test/resources/3_0/oneOf_with_allOf_inherited_class_array.yaml b/modules/openapi-generator/src/test/resources/3_0/oneOf_with_allOf_inherited_class_array.yaml new file mode 100644 index 000000000000..c067a483714d --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/oneOf_with_allOf_inherited_class_array.yaml @@ -0,0 +1,50 @@ +openapi: 3.0.0 +info: + version: "1.0.0" + title: "API should have import for OneOf Class, models should extend OneOf Class" +paths: + /addFruits: + post: + responses: + '200': + description: Returns a list of fruits + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Fruit' + requestBody: + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Fruit' +components: + schemas: + Apple: + type: object + allOf: + - $ref: '#/components/schemas/Fruit' + - type: object + properties: + identifier: + type: string + Orange: + type: object + allOf: + - $ref: '#/components/schemas/Fruit' + - type: object + properties: + identifier2: + type: string + Fruit: + type: object + properties: + kind: + type: string + required: + - kind + discriminator: + propertyName: kind From 7358de909bd6223b7b599d62b0d243802869467d Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 20 Sep 2021 13:37:36 +0300 Subject: [PATCH 23/25] TAP-232 Restart CI builds From 8a1cf1e0bb98f0d7b8bf9cb26dfbe68aea02eb04 Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 20 Sep 2021 15:50:01 +0300 Subject: [PATCH 24/25] TAP-232 Removed unused imports, fixed OneOf generation in response schema --- .../languages/AbstractJavaCodegen.java | 70 ++++++++++--------- .../codegen/java/JavaClientCodegenTest.java | 1 - .../java/spring/SpringCodegenTest.java | 3 - 3 files changed, 38 insertions(+), 36 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java index fa6c8a7a210c..079c604f75a4 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java @@ -43,6 +43,7 @@ import java.util.regex.Pattern; import java.util.stream.Stream; +import io.swagger.v3.oas.models.responses.ApiResponse; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; @@ -81,24 +82,9 @@ import io.swagger.v3.oas.models.parameters.RequestBody; import io.swagger.v3.oas.models.servers.Server; import io.swagger.v3.parser.util.SchemaTypeUtil; -import org.apache.commons.io.FilenameUtils; -import org.apache.commons.lang3.BooleanUtils; -import org.apache.commons.lang3.StringUtils; -import org.openapitools.codegen.*; -import org.openapitools.codegen.meta.features.*; -import org.openapitools.codegen.utils.ModelUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.io.File; import java.io.IOException; -import java.time.LocalDate; -import java.time.ZoneId; import java.util.*; -import java.util.regex.Pattern; -import java.util.stream.Stream; - -import static org.openapitools.codegen.utils.StringUtils.*; public abstract class AbstractJavaCodegen extends DefaultCodegen implements CodegenConfig { @@ -1365,26 +1351,19 @@ public void preprocessOpenAPI(OpenAPI openAPI) { LOGGER.info("Processing operation {}", operation.getOperationId()); boolean hasBodyParameter = hasBodyParameter(openAPI, operation); boolean hasFormParameter = hasFormParameter(openAPI, operation); + // OpenAPI parser do not add Inline One Of models in Operations to Components/Schemas if (hasBodyParameter) { - RequestBody requestBody = operation.getRequestBody(); - Optional.ofNullable(requestBody) - .map(ModelUtils::getSchemaFromRequestBody) - .ifPresent(schema -> { - if (schema instanceof ComposedSchema - && ((ComposedSchema) schema).getProperties() == null - && Optional.ofNullable(schema.getExtensions()).map(m -> m.containsKey("x-one-of-name")).orElse(false) - ) { - String oneOfModelName = (String) schema.getExtensions().get("x-one-of-name"); - Schema originalSchema = ModelUtils.getSchemaFromRequestBody(requestBody); - Schema replacedSchema = new Schema<>().$ref("#/components/schemas/" + oneOfModelName); - requestBody.getContent().values().forEach(mediaType -> { - mediaType.setSchema(replacedSchema); - ModelUtils.getSchemas(openAPI).put(oneOfModelName, originalSchema); - }); - } - }); + Optional.ofNullable(operation.getRequestBody()) + .map(RequestBody::getContent) + .ifPresent(this::repairInlineOneOf); } + if (operation.getResponses() != null) { + operation.getResponses().values().stream().map(ApiResponse::getContent) + .filter(Objects::nonNull) + .forEach(this::repairInlineOneOf); + } + if (hasBodyParameter || hasFormParameter) { String defaultContentType = hasFormParameter ? "application/x-www-form-urlencoded" : "application/json"; List consumes = new ArrayList<>(getConsumesInfo(openAPI, operation)); @@ -1443,6 +1422,33 @@ public void preprocessOpenAPI(OpenAPI openAPI) { } } + + /** + * Add all OneOf schemas to #/components/schemas and replace them in the original content by ref schema + * + * OpenAPI Parser does not add inline OneOf schemas to models to generate + * + * @param content a 'content' section in the OAS specification. + */ + private void repairInlineOneOf(final Content content) { + content.values().forEach(mediaType -> { + final Schema replacingSchema = mediaType.getSchema(); + if (isOneOfSchema(replacingSchema)) { + final String oneOfModelName = (String) replacingSchema.getExtensions().get("x-one-of-name"); + final Schema newRefSchema = new Schema<>().$ref("#/components/schemas/" + oneOfModelName); + mediaType.setSchema(newRefSchema); + ModelUtils.getSchemas(openAPI).put(oneOfModelName, replacingSchema); + } + }); + } + + private static boolean isOneOfSchema(final Schema schema) { + return schema instanceof ComposedSchema + && ((ComposedSchema) schema).getProperties() == null + && Optional.ofNullable(schema.getExtensions()).map(m -> m.containsKey("x-one-of-name")) + .orElse(false); + } + private static String getAccept(OpenAPI openAPI, Operation operation) { String accepts = null; String defaultContentType = "application/json"; diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java index 1e7b4269dde1..7b9a50127096 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java @@ -58,7 +58,6 @@ import org.openapitools.codegen.config.CodegenConfigurator; import org.openapitools.codegen.languages.AbstractJavaCodegen; import org.openapitools.codegen.languages.JavaClientCodegen; -import org.openapitools.codegen.languages.SpringCodegen; import org.openapitools.codegen.utils.ModelUtils; import org.testng.Assert; import org.testng.annotations.DataProvider; diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java index 787f39868059..5fb7bcf6b7c7 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java @@ -39,16 +39,13 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Optional; import java.util.stream.Collectors; -import java.util.stream.Stream; import static java.util.stream.Collectors.groupingBy; import static org.openapitools.codegen.TestUtils.assertFileContains; From a1cac51c32777c40f4afb80af687b41a74b8cf05 Mon Sep 17 00:00:00 2001 From: Alexander Date: Tue, 21 Sep 2021 10:05:42 +0300 Subject: [PATCH 25/25] TAP-232 Removed code duplicate --- .../codegen/languages/SpringCodegen.java | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java index 147fd7132636..e935c77ef104 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java @@ -916,16 +916,4 @@ public void postProcessParameter(CodegenParameter p) { } } - @Override - public void addImportsToOneOfInterface(List> imports) { - for (String i : Arrays.asList("JsonSubTypes", "JsonTypeInfo")) { - Map oneImport = new HashMap() {{ - put("import", importMapping.get(i)); - }}; - if (!imports.contains(oneImport)) { - imports.add(oneImport); - } - } - } - -} \ No newline at end of file +}