diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaJAXRSSpecServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaJAXRSSpecServerCodegen.java index 3a9d43e8cb27..a2c946454091 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaJAXRSSpecServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaJAXRSSpecServerCodegen.java @@ -26,6 +26,7 @@ import org.openapitools.codegen.meta.features.DocumentationFeature; import org.openapitools.codegen.meta.features.SecurityFeature; import org.openapitools.codegen.model.ModelMap; +import org.openapitools.codegen.model.ModelsMap; import org.openapitools.codegen.model.OperationsMap; import java.io.File; @@ -327,6 +328,11 @@ public void postProcessModelProperty(CodegenModel model, CodegenProperty propert } } + @Override + public ModelsMap postProcessModels(ModelsMap objs) { + return super.postProcessModels(objs); + } + @Override public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List allModels) { objs = super.postProcessOperationsWithModels(objs, allModels); @@ -334,4 +340,25 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List postProcessAllModels(Map objs) { + Map result = super.postProcessAllModels(objs); + for (ModelsMap modelsMap : result.values()) { + for (ModelMap modelMap : modelsMap.getModels()) { + CodegenModel model = modelMap.getModel(); + if (model.parentModel != null) { + CodegenDiscriminator discriminator = model.parentModel.getDiscriminator(); + if (discriminator != null) { + for (CodegenDiscriminator.MappedModel mappedModel : discriminator.getMappedModels()) { + if (mappedModel.getModelName().equals(model.name)) { + model.getVendorExtensions().put("x-discriminator-value", mappedModel.getMappingName()); + break; + } + } + } + } + } + } + return result; + } } diff --git a/modules/openapi-generator/src/main/resources/JavaJaxRS/spec/pojo.mustache b/modules/openapi-generator/src/main/resources/JavaJaxRS/spec/pojo.mustache index 83970c86ca74..61c0e66e4230 100644 --- a/modules/openapi-generator/src/main/resources/JavaJaxRS/spec/pojo.mustache +++ b/modules/openapi-generator/src/main/resources/JavaJaxRS/spec/pojo.mustache @@ -38,7 +38,7 @@ import {{javaxPackage}}.xml.bind.annotation.XmlEnumValue; @Schema({{#title}}title="{{{.}}}", {{/title}}{{#description}}description="{{{.}}}"{{/description}}{{^description}}description=""{{/description}}){{/useSwaggerV3Annotations}}{{#useMicroProfileOpenAPIAnnotations}} @org.eclipse.microprofile.openapi.annotations.media.Schema({{#title}}title="{{{.}}}", {{/title}}{{#description}}description="{{{.}}}"{{/description}}{{^description}}description=""{{/description}}){{/useMicroProfileOpenAPIAnnotations}} {{#jackson}} -@JsonTypeName("{{name}}") +@JsonTypeName("{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}") {{#additionalProperties}} @JsonFormat(shape=JsonFormat.Shape.OBJECT) {{/additionalProperties}} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/jaxrs/JavaJAXRSSpecServerCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/jaxrs/JavaJAXRSSpecServerCodegenTest.java index 2e9e2e2153d2..b360a6f49c4c 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/jaxrs/JavaJAXRSSpecServerCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/jaxrs/JavaJAXRSSpecServerCodegenTest.java @@ -1237,4 +1237,35 @@ public void disableGenerateJsonCreator() throws Exception { assertFileNotContains(files.get("RequiredProperties.java").toPath(), "@JsonCreator"); } + @Test + public void testDiscriminatorMappingUsedInJsonTypeName() throws Exception { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + + OpenAPI openAPI = new OpenAPIParser() + .readLocation("src/test/resources/3_0/jaxrs/pestore-with-discriminator.yaml", null, new ParseOptions()).getOpenAPI(); + + codegen.setOutputDir(output.getAbsolutePath()); + + ClientOptInput input = new ClientOptInput() + .openAPI(openAPI) + .config(codegen); + + DefaultGenerator generator = new DefaultGenerator(); + Map files = generator.opts(input).generate().stream() + .collect(Collectors.toMap(File::getName, Function.identity())); + + // Parent model uses its own name + JavaFileAssert.assertThat(files.get("PetRequest.java")) + .fileContains("@JsonTypeName(\"PetRequest\")"); + + // Child models must use the discriminator mapping value (e.g. "CAT"), not the class name (e.g. "CatRequest") + JavaFileAssert.assertThat(files.get("CatRequest.java")) + .fileContains("@JsonTypeName(\"CAT\")") + .fileDoesNotContain("@JsonTypeName(\"CatRequest\")"); + + JavaFileAssert.assertThat(files.get("DogRequest.java")) + .fileContains("@JsonTypeName(\"DOG\")") + .fileDoesNotContain("@JsonTypeName(\"DogRequest\")"); + } } diff --git a/modules/openapi-generator/src/test/resources/3_0/jaxrs/pestore-with-discriminator.yaml b/modules/openapi-generator/src/test/resources/3_0/jaxrs/pestore-with-discriminator.yaml new file mode 100644 index 000000000000..6259b82bbca3 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/jaxrs/pestore-with-discriminator.yaml @@ -0,0 +1,69 @@ +openapi: 3.0.0 +servers: + - url: 'http://petstore.swagger.io/v2' +info: + description: >- + This is a sample server Petstore server that uses polymorphism and inheritance with a discriminator. + version: 1.0.0 + title: OpenAPI Petstore + license: + name: Apache-2.0 + url: 'https://www.apache.org/licenses/LICENSE-2.0.html' + +tags: + - name: pet + description: Everything about your Pets + +paths: + /pets: + post: + operationId: createPet + security: [] + tags: [ pet ] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PetRequest' + responses: + '201': + description: Pet created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/PetRequest' + +components: + schemas: + PetRequest: + type: object + required: + - petType + properties: + petType: + type: string + name: + type: string + oneOf: + - $ref: '#/components/schemas/CatRequest' + - $ref: '#/components/schemas/DogRequest' + discriminator: + propertyName: petType + mapping: + CAT: '#/components/schemas/CatRequest' + DOG: '#/components/schemas/DogRequest' + CatRequest: + allOf: + - $ref: '#/components/schemas/PetRequest' + - type: object + properties: + indoor: + type: boolean + DogRequest: + allOf: + - $ref: '#/components/schemas/PetRequest' + - type: object + properties: + bark: + type: string