Skip to content

Commit 16d3633

Browse files
committed
Changes report: Allow ComposedSchemas to replace non-composed so we can respect polymorphic links discovered in later methods #1620
1 parent 0cd5052 commit 16d3633

File tree

7 files changed

+225
-2
lines changed

7 files changed

+225
-2
lines changed

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocAnnotationsUtils.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,13 @@ public static Schema extractSchema(Components components, Type returnType, JsonV
131131
componentSchemas.putAll(schemaMap);
132132
}
133133
else
134-
for (Map.Entry<String, Schema> entry : schemaMap.entrySet())
135-
if (!componentSchemas.containsKey(entry.getKey()))
134+
for (Map.Entry<String, Schema> entry : schemaMap.entrySet()) {
135+
// If we've seen this schema before but find later it should be polymorphic,
136+
// replace the existing schema with this richer version.
137+
if (!componentSchemas.containsKey(entry.getKey()) || !entry.getValue().getClass().equals(componentSchemas.get(entry.getKey()).getClass())) {
136138
componentSchemas.put(entry.getKey(), entry.getValue());
139+
}
140+
}
137141
components.setSchemas(componentSchemas);
138142
}
139143
if (resolvedSchema.schema != null) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package test.org.springdoc.api.app185;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
5+
@Schema
6+
public class Cat extends Pet {
7+
8+
private final boolean meows;
9+
10+
public Cat() {
11+
super();
12+
this.meows = false;
13+
}
14+
15+
public Cat(boolean meows, String name) {
16+
super(name);
17+
this.meows = meows;
18+
}
19+
20+
public boolean getMeows() {
21+
return meows;
22+
}
23+
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package test.org.springdoc.api.app185;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
5+
@Schema
6+
public class Dog extends Pet {
7+
8+
private final boolean barks;
9+
10+
public Dog() {
11+
super();
12+
this.barks = false;
13+
}
14+
15+
public Dog(boolean barks, String name) {
16+
super(name);
17+
this.barks = barks;
18+
}
19+
20+
public boolean getBarks() {
21+
return barks;
22+
}
23+
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package test.org.springdoc.api.app185;
2+
3+
import com.fasterxml.jackson.annotation.JsonSubTypes;
4+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
5+
6+
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
7+
@JsonSubTypes({
8+
@JsonSubTypes.Type(Dog.class),
9+
@JsonSubTypes.Type(Cat.class)
10+
})
11+
public class Pet {
12+
13+
public final String name;
14+
15+
public Pet() {
16+
this.name = null;
17+
}
18+
19+
public Pet(String name) {
20+
this.name = name;
21+
}
22+
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package test.org.springdoc.api.app185;
2+
3+
import org.springframework.web.bind.annotation.GetMapping;
4+
import org.springframework.web.bind.annotation.RestController;
5+
6+
@RestController
7+
public class PetController {
8+
9+
@GetMapping("/any")
10+
public Pet getAnyPet() {
11+
return new Cat(true, "cat");
12+
}
13+
14+
@GetMapping("/dog")
15+
public Dog getDog() {
16+
return new Dog(true, "dog");
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package test.org.springdoc.api.app185;
2+
3+
import test.org.springdoc.api.AbstractSpringDocTest;
4+
5+
import org.springframework.boot.autoconfigure.SpringBootApplication;
6+
7+
public class SpringDocApp185Test extends AbstractSpringDocTest {
8+
9+
@SpringBootApplication
10+
static class SpringDocTestApp {}
11+
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
{
2+
"openapi": "3.0.1",
3+
"info": {
4+
"title": "OpenAPI definition",
5+
"version": "v0"
6+
},
7+
"servers": [
8+
{
9+
"url": "http://localhost",
10+
"description": "Generated server url"
11+
}
12+
],
13+
"paths": {
14+
"/dog": {
15+
"get": {
16+
"tags": [
17+
"pet-controller"
18+
],
19+
"operationId": "getDog",
20+
"responses": {
21+
"200": {
22+
"description": "OK",
23+
"content": {
24+
"*/*": {
25+
"schema": {
26+
"$ref": "#/components/schemas/Dog"
27+
}
28+
}
29+
}
30+
}
31+
}
32+
}
33+
},
34+
"/any": {
35+
"get": {
36+
"tags": [
37+
"pet-controller"
38+
],
39+
"operationId": "getAnyPet",
40+
"responses": {
41+
"200": {
42+
"description": "OK",
43+
"content": {
44+
"*/*": {
45+
"schema": {
46+
"oneOf": [
47+
{
48+
"$ref": "#/components/schemas/Pet"
49+
},
50+
{
51+
"$ref": "#/components/schemas/Cat"
52+
},
53+
{
54+
"$ref": "#/components/schemas/Dog"
55+
}
56+
]
57+
}
58+
}
59+
}
60+
}
61+
}
62+
}
63+
}
64+
},
65+
"components": {
66+
"schemas": {
67+
"Dog": {
68+
"type": "object",
69+
"allOf": [
70+
{
71+
"$ref": "#/components/schemas/Pet"
72+
},
73+
{
74+
"type": "object",
75+
"properties": {
76+
"barks": {
77+
"type": "boolean"
78+
}
79+
}
80+
}
81+
]
82+
},
83+
"Cat": {
84+
"type": "object",
85+
"allOf": [
86+
{
87+
"$ref": "#/components/schemas/Pet"
88+
},
89+
{
90+
"type": "object",
91+
"properties": {
92+
"meows": {
93+
"type": "boolean"
94+
}
95+
}
96+
}
97+
]
98+
},
99+
"Pet": {
100+
"required": [
101+
"type"
102+
],
103+
"type": "object",
104+
"properties": {
105+
"name": {
106+
"type": "string"
107+
},
108+
"type": {
109+
"type": "string"
110+
}
111+
},
112+
"discriminator": {
113+
"propertyName": "type"
114+
}
115+
}
116+
}
117+
}
118+
}

0 commit comments

Comments
 (0)