Skip to content

Commit

Permalink
Polymorphism - documentation not generated for subtypes when using Js…
Browse files Browse the repository at this point in the history
…onTypeInfo.As.WRAPPER_OBJECT and JsonTypeInfo.Id.NAME. fixes #1799
  • Loading branch information
bnasslahsen committed Aug 20, 2022
1 parent 2272cb3 commit 2478516
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 13 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Expand Up @@ -24,7 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- #1692 - More specific bean name for objectMapperProvider
- #1684 - Incorrect generic param for multi interfaces
- #1707 - Concurrent problems when initializing multiple GroupedOpenApi parallelly
- 1690 - Expected file to be in alphabetical order.
- #1690 - Expected file to be in alphabetical order.
- #1713 - ObjectMapperProvider to sort all properties.
- #1717, #1718 - javadoc of JsonUnwrapped fields not set
- #1748, #1712, Generated server url computation not cleared
Expand Down
Expand Up @@ -34,6 +34,7 @@
import io.swagger.v3.core.converter.ModelConverterContext;
import io.swagger.v3.core.util.AnnotationsUtils;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.ObjectSchema;
import io.swagger.v3.oas.models.media.Schema;
import org.springdoc.core.providers.ObjectMapperProvider;

Expand All @@ -48,6 +49,7 @@ public class PolymorphicModelConverter implements ModelConverter {
*/
private final ObjectMapperProvider springDocObjectMapper;


/**
* Instantiates a new Polymorphic model converter.
*
Expand All @@ -59,10 +61,17 @@ public PolymorphicModelConverter(ObjectMapperProvider springDocObjectMapper) {

@Override
public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) {
if (chain.hasNext()) {
Schema<?> resolvedSchema = chain.next().resolve(type, context, chain);
if (resolvedSchema == null || resolvedSchema.get$ref() == null) return resolvedSchema;
return composePolymorphicSchema(type, resolvedSchema, context.getDefinedModels().values());
JavaType javaType = springDocObjectMapper.jsonMapper().constructType(type.getType());
if (javaType != null) {
if (chain.hasNext()) {
Schema<?> resolvedSchema = chain.next().resolve(type, context, chain);
if (resolvedSchema instanceof ObjectSchema && resolvedSchema.getProperties() != null
&& resolvedSchema.getProperties().containsKey(javaType.getRawClass().getSimpleName()))
resolvedSchema = resolvedSchema.getProperties().get(javaType.getRawClass().getSimpleName());
if (resolvedSchema == null || resolvedSchema.get$ref() == null)
return resolvedSchema;
return composePolymorphicSchema(type, resolvedSchema, context.getDefinedModels().values());
}
}
return null;
}
Expand Down
Expand Up @@ -25,5 +25,12 @@

import test.org.springdoc.api.v30.AbstractSpringDocV30Test;

import org.springframework.boot.autoconfigure.SpringBootApplication;

public class SpringDocApp192Test extends AbstractSpringDocV30Test { }

public class SpringDocApp192Test extends AbstractSpringDocV30Test {

@SpringBootApplication
static class SpringDocTestApp {}

}
@@ -0,0 +1,17 @@
package test.org.springdoc.api.v30.app193;


import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.swagger.v3.oas.annotations.media.Schema;

/**
* Interface of the Animal.
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "dog"),
@JsonSubTypes.Type(value = Cat.class, name = "cat"),
})
@Schema(description = "Represents an Animal class.")
public interface Animal {}
@@ -0,0 +1,21 @@
package test.org.springdoc.api.v30.app193;

import io.swagger.v3.oas.annotations.Operation;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(path = "/")
public class BasicController {

@GetMapping("/test")
@Operation(summary = "get", description = "Provides an animal.")
public Animal get() {

return new Dog("Foo", 12);
}
}
@@ -0,0 +1,22 @@
package test.org.springdoc.api.v30.app193;


import io.swagger.v3.oas.annotations.media.Schema;

@Schema(description = "Represents a Cat class.")
public class Cat implements Animal {

private Integer speed;

public Cat(Integer speed) {
this.speed = speed;
}

public Integer getSpeed() {
return speed;
}

public void setSpeed(Integer speed) {
this.speed = speed;
}
}
@@ -0,0 +1,32 @@
package test.org.springdoc.api.v30.app193;


import io.swagger.v3.oas.annotations.media.Schema;

@Schema(description = "Represents a Dog class.")
public class Dog implements Animal {

private String name;
private Integer age;

public Dog(String name, Integer age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}
}
Expand Up @@ -20,15 +20,17 @@
*
*/

package test.org.springdoc.api.v30.app192;
package test.org.springdoc.api.v30.app193;


import test.org.springdoc.api.v30.AbstractSpringDocV30Test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringDocTestApp {

public static void main(String[] args) {
SpringApplication.run(SpringDocTestApp.class, args);
}
public class SpringDocApp193Test extends AbstractSpringDocV30Test {

@SpringBootApplication
static class SpringDocTestApp {}

}
@@ -0,0 +1,91 @@
{
"openapi": "3.0.1",
"info": {
"title": "OpenAPI definition",
"version": "v0"
},
"servers": [
{
"url": "http://localhost",
"description": "Generated server url"
}
],
"paths": {
"/test": {
"get": {
"tags": [
"basic-controller"
],
"summary": "get",
"description": "Provides an animal.",
"operationId": "get",
"responses": {
"200": {
"description": "OK",
"content": {
"*/*": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/Cat"
},
{
"$ref": "#/components/schemas/Dog"
}
]
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Animal": {
"type": "object",
"description": "Represents an Animal class."
},
"Cat": {
"type": "object",
"description": "Represents a Cat class.",
"allOf": [
{
"$ref": "#/components/schemas/Animal"
},
{
"type": "object",
"properties": {
"speed": {
"type": "integer",
"format": "int32"
}
}
}
]
},
"Dog": {
"type": "object",
"description": "Represents a Dog class.",
"allOf": [
{
"$ref": "#/components/schemas/Animal"
},
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "integer",
"format": "int32"
}
}
}
]
}
}
}
}

0 comments on commit 2478516

Please sign in to comment.