Skip to content

Commit e1fff95

Browse files
committed
Merge branch '2801-infinite-recursion-with-all-of' of https://github.com/martinitus/springdoc-openapi into martinitus-2801-infinite-recursion-with-all-of
2 parents 353ffae + c4d2078 commit e1fff95

File tree

4 files changed

+195
-24
lines changed

4 files changed

+195
-24
lines changed

Diff for: springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/PolymorphicModelConverter.java

+27-24
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
* * * *
2222
* * *
2323
* *
24-
*
24+
*
2525
*/
2626

2727
package org.springdoc.core.converters;
@@ -110,32 +110,35 @@ else if (resolvedSchema.getProperties().containsKey(javaType.getRawClass().getSi
110110
@Override
111111
public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) {
112112
JavaType javaType = springDocObjectMapper.jsonMapper().constructType(type.getType());
113-
if (javaType != null) {
114-
for (Field field : FieldUtils.getAllFields(javaType.getRawClass())) {
115-
if (field.isAnnotationPresent(JsonUnwrapped.class)) {
116-
PARENT_TYPES_TO_IGNORE.add(javaType.getRawClass().getSimpleName());
117-
}
113+
114+
if (javaType == null || !chain.hasNext()) {
115+
return null;
116+
}
117+
118+
for (Field field : FieldUtils.getAllFields(javaType.getRawClass())) {
119+
if (field.isAnnotationPresent(JsonUnwrapped.class)) {
120+
PARENT_TYPES_TO_IGNORE.add(javaType.getRawClass().getSimpleName());
118121
}
119-
if (chain.hasNext()) {
120-
if (!type.isResolveAsRef() && type.getParent() != null
121-
&& PARENT_TYPES_TO_IGNORE.stream().noneMatch(ignore -> type.getParent().getName().startsWith(ignore)))
122-
type.resolveAsRef(true);
123-
Schema<?> resolvedSchema = chain.next().resolve(type, context, chain);
124-
resolvedSchema = getResolvedSchema(javaType, resolvedSchema);
125-
if (resolvedSchema == null || resolvedSchema.get$ref() == null) {
126-
return resolvedSchema;
127-
}
128-
if(resolvedSchema.get$ref().contains(Components.COMPONENTS_SCHEMAS_REF)) {
129-
String schemaName = resolvedSchema.get$ref().substring(Components.COMPONENTS_SCHEMAS_REF.length());
130-
Schema existingSchema = context.getDefinedModels().get(schemaName);
131-
if (existingSchema != null && existingSchema.getOneOf() != null) {
132-
return resolvedSchema;
133-
}
134-
}
135-
return composePolymorphicSchema(type, resolvedSchema, context.getDefinedModels().values());
122+
}
123+
124+
String parentName = type.getParent() == null ? null : type.getParent().getName();
125+
if (parentName != null && PARENT_TYPES_TO_IGNORE.stream().noneMatch(parentName::startsWith)){
126+
type.resolveAsRef(true);
127+
}
128+
129+
Schema<?> resolvedSchema = getResolvedSchema(javaType, chain.next().resolve(type, context, chain));
130+
if (resolvedSchema == null || resolvedSchema.get$ref() == null) {
131+
return resolvedSchema;
132+
}
133+
134+
if(resolvedSchema.get$ref().contains(Components.COMPONENTS_SCHEMAS_REF)) {
135+
String schemaName = resolvedSchema.get$ref().substring(Components.COMPONENTS_SCHEMAS_REF.length());
136+
Schema existingSchema = context.getDefinedModels().get(schemaName);
137+
if (existingSchema != null && (existingSchema.getOneOf() != null || existingSchema.getAllOf() != null || existingSchema.getAnyOf() != null)) {
138+
return resolvedSchema;
136139
}
137140
}
138-
return null;
141+
return composePolymorphicSchema(type, resolvedSchema, context.getDefinedModels().values());
139142
}
140143

141144
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
*
3+
* * Copyright 2019-2020 the original author or authors.
4+
* *
5+
* * Licensed under the Apache License, Version 2.0 (the "License");
6+
* * you may not use this file except in compliance with the License.
7+
* * You may obtain a copy of the License at
8+
* *
9+
* * https://www.apache.org/licenses/LICENSE-2.0
10+
* *
11+
* * Unless required by applicable law or agreed to in writing, software
12+
* * distributed under the License is distributed on an "AS IS" BASIS,
13+
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* * See the License for the specific language governing permissions and
15+
* * limitations under the License.
16+
*
17+
*/
18+
19+
package test.org.springdoc.api.app13
20+
21+
import org.springdoc.core.properties.SpringDocConfigProperties
22+
import org.springdoc.core.properties.SpringDocConfigProperties.ApiDocs.OpenApiVersion
23+
import org.springframework.boot.autoconfigure.SpringBootApplication
24+
import org.springframework.boot.test.context.SpringBootTest
25+
import org.springframework.context.annotation.Bean
26+
import org.springframework.context.annotation.Configuration
27+
import test.org.springdoc.api.AbstractKotlinSpringDocMVCTest
28+
29+
30+
@SpringBootTest//(classes = [Config::class])
31+
class SpringDocApp13Test : AbstractKotlinSpringDocMVCTest() {
32+
33+
34+
@Configuration
35+
class Config{
36+
@Bean
37+
fun springDocConfigProperties():SpringDocConfigProperties{
38+
val x= SpringDocConfigProperties()
39+
x.apiDocs.version = OpenApiVersion.OPENAPI_3_1
40+
return x
41+
}
42+
43+
}
44+
45+
46+
@SpringBootApplication
47+
class DemoApplication
48+
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
*
3+
* * Copyright 2019-2020 the original author or authors.
4+
* *
5+
* * Licensed under the Apache License, Version 2.0 (the "License");
6+
* * you may not use this file except in compliance with the License.
7+
* * You may obtain a copy of the License at
8+
* *
9+
* * https://www.apache.org/licenses/LICENSE-2.0
10+
* *
11+
* * Unless required by applicable law or agreed to in writing, software
12+
* * distributed under the License is distributed on an "AS IS" BASIS,
13+
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* * See the License for the specific language governing permissions and
15+
* * limitations under the License.
16+
*
17+
*/
18+
19+
package test.org.springdoc.api.app13
20+
21+
22+
import io.swagger.v3.oas.annotations.OpenAPI31
23+
import io.swagger.v3.oas.annotations.media.Schema
24+
import org.springframework.web.bind.annotation.PostMapping
25+
import org.springframework.web.bind.annotation.RequestBody
26+
import org.springframework.web.bind.annotation.RequestMapping
27+
import org.springframework.web.bind.annotation.RestController
28+
29+
@Schema(description = "Generic description")
30+
data class KeyValue(
31+
val key: String,
32+
val value: String,
33+
)
34+
35+
@Schema
36+
data class SomeDTO(
37+
@Schema(description = "Description A") val fieldA: KeyValue,
38+
@Schema(description = "Description B") val fieldB: KeyValue,
39+
)
40+
41+
42+
43+
@RestController
44+
@RequestMapping("/test")
45+
class TestController {
46+
@PostMapping("/test")
47+
fun create(@RequestBody some: SomeDTO) {
48+
49+
}
50+
}
51+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{
2+
"openapi" : "3.1.0",
3+
"info" : {
4+
"title" : "OpenAPI definition",
5+
"version" : "v0"
6+
},
7+
"servers" : [ {
8+
"url" : "http://localhost",
9+
"description" : "Generated server url"
10+
} ],
11+
"paths" : {
12+
"/test/test" : {
13+
"post" : {
14+
"tags" : [ "test-controller" ],
15+
"operationId" : "create",
16+
"requestBody" : {
17+
"content" : {
18+
"application/json" : {
19+
"schema" : {
20+
"$ref" : "#/components/schemas/SomeDTO"
21+
}
22+
}
23+
},
24+
"required" : true
25+
},
26+
"responses" : {
27+
"200" : {
28+
"description" : "OK"
29+
}
30+
}
31+
}
32+
}
33+
},
34+
"components" : {
35+
"schemas" : {
36+
"KeyValue" : {
37+
"required" : [ "key", "value" ],
38+
"type" : "object",
39+
"description" : "Generic description",
40+
"properties" : {
41+
"key" : {
42+
"type" : "string"
43+
},
44+
"value" : {
45+
"type" : "string"
46+
}
47+
}
48+
},
49+
"SomeDTO" : {
50+
"required": [
51+
"fieldA",
52+
"fieldB"
53+
],
54+
"type": "object",
55+
"properties": {
56+
"fieldA": {
57+
"description": "Description A",
58+
"$ref": "#/components/schemas/KeyValue"
59+
},
60+
"fieldB": {
61+
"description": "Description B",
62+
"$ref": "#/components/schemas/KeyValue"
63+
}
64+
}
65+
}
66+
}
67+
}
68+
}

0 commit comments

Comments
 (0)