Skip to content

Commit 94ae2d1

Browse files
committed
refs #4771 - schema resolution for container types and oas31
1 parent 24e87c5 commit 94ae2d1

File tree

4 files changed

+121
-8
lines changed

4 files changed

+121
-8
lines changed

modules/swagger-core/src/main/java/io/swagger/v3/core/converter/ModelConverters.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ public static ModelConverters getInstance(boolean openapi31, Schema.SchemaResolu
8181
synchronized (ModelConverters.class) {
8282
if (openapi31) {
8383
if (SINGLETON31 == null) {
84-
SINGLETON31 = new ModelConverters(openapi31, Schema.SchemaResolution.DEFAULT);
84+
boolean applySchemaResolution = Boolean.parseBoolean(System.getProperty(Schema.APPLY_SCHEMA_RESOLUTION_PROPERTY, "false")) || Boolean.parseBoolean(System.getenv(Schema.APPLY_SCHEMA_RESOLUTION_PROPERTY));
85+
SINGLETON31 = new ModelConverters(openapi31, applySchemaResolution ? schemaResolution : Schema.SchemaResolution.DEFAULT);
8586
init(SINGLETON31);
8687
}
8788
return SINGLETON31;

modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java

+20-7
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,11 @@ public ObjectMapper objectMapper() {
141141
@Override
142142
public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context, Iterator<ModelConverter> next) {
143143

144+
145+
boolean applySchemaResolution =
146+
!openapi31 ||
147+
(Boolean.parseBoolean(System.getProperty(Schema.APPLY_SCHEMA_RESOLUTION_PROPERTY, "false")) ||
148+
Boolean.parseBoolean(System.getenv(Schema.APPLY_SCHEMA_RESOLUTION_PROPERTY)));
144149
boolean isPrimitive = false;
145150
Schema model = null;
146151
List<String> requiredProps = new ArrayList<>();
@@ -449,7 +454,7 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
449454
).collect(Collectors.toList()));
450455
}
451456

452-
457+
Schema.SchemaResolution containerResolvedSchemaResolution = AnnotationsUtils.resolveSchemaResolution(this.schemaResolution, resolvedSchemaAnnotation);
453458
if (keyType != null && valueType != null) {
454459
if (ReflectionUtils.isSystemTypeNotArray(type) && !annotatedType.isSchemaProperty() && !annotatedType.isResolveAsRef()) {
455460
context.resolve(new AnnotatedType().components(annotatedType.getComponents()).type(valueType).jsonViewAnnotation(annotatedType.getJsonViewAnnotation()));
@@ -471,9 +476,13 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
471476
pName = addPropertiesSchema.getName();
472477
}
473478
if (isObjectSchema(addPropertiesSchema) && pName != null) {
474-
// create a reference for the items
475479
if (context.getDefinedModels().containsKey(pName)) {
476-
addPropertiesSchema = new Schema().$ref(constructRef(pName));
480+
if (Schema.SchemaResolution.INLINE.equals(containerResolvedSchemaResolution) && applySchemaResolution) {
481+
addPropertiesSchema = context.getDefinedModels().get(pName);
482+
} else {
483+
// create a reference for the items
484+
addPropertiesSchema = new Schema().$ref(constructRef(pName));
485+
}
477486
}
478487
} else if (addPropertiesSchema.get$ref() != null) {
479488
addPropertiesSchema = new Schema().$ref(StringUtils.isNotEmpty(addPropertiesSchema.get$ref()) ? addPropertiesSchema.get$ref() : addPropertiesSchema.getName());
@@ -519,9 +528,13 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
519528
pName = items.getName();
520529
}
521530
if (isObjectSchema(items) && pName != null) {
522-
// create a reference for the items
523531
if (context.getDefinedModels().containsKey(pName)) {
524-
items = new Schema().$ref(constructRef(pName));
532+
if (Schema.SchemaResolution.INLINE.equals(containerResolvedSchemaResolution) && applySchemaResolution) {
533+
items = context.getDefinedModels().get(pName);
534+
} else {
535+
// create a reference for the items
536+
items = new Schema().$ref(constructRef(pName));
537+
}
525538
}
526539
} else if (items.get$ref() != null) {
527540
items = new Schema().$ref(StringUtils.isNotEmpty(items.get$ref()) ? items.get$ref() : items.getName());
@@ -738,7 +751,7 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
738751
property = context.resolve(aType);
739752
property = clone(property);
740753
Schema ctxProperty = null;
741-
if (openapi31) {
754+
if (!applySchemaResolution) {
742755
Optional<Schema> reResolvedProperty = AnnotationsUtils.getSchemaFromAnnotation(ctxSchema, annotatedType.getComponents(), null, openapi31, property, schemaResolution, context);
743756
if (reResolvedProperty.isPresent()) {
744757
property = reResolvedProperty.get();
@@ -822,7 +835,7 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
822835
}
823836
}
824837
} else if (property.get$ref() != null) {
825-
if (!openapi31) {
838+
if (applySchemaResolution) {
826839
if (Schema.SchemaResolution.ALL_OF.equals(resolvedSchemaResolution) && ctxProperty != null) {
827840
property = new Schema()
828841
.addAllOfItem(ctxProperty)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package io.swagger.v3.core.resolving;
2+
3+
import io.swagger.v3.core.converter.AnnotatedType;
4+
import io.swagger.v3.core.converter.ModelConverters;
5+
import io.swagger.v3.core.converter.ResolvedSchema;
6+
import io.swagger.v3.core.matchers.SerializationMatchers;
7+
import io.swagger.v3.oas.models.media.Schema;
8+
import org.testng.annotations.Test;
9+
10+
public class Ticket4771Test {
11+
12+
@Test
13+
public void testArraySchemaItemsValidation(){
14+
ModelConverters.reset();
15+
System.clearProperty(Schema.APPLY_SCHEMA_RESOLUTION_PROPERTY);
16+
ResolvedSchema schema = ModelConverters.getInstance(false, Schema.SchemaResolution.INLINE).resolveAsResolvedSchema(new AnnotatedType().type(CustomClass[].class));
17+
String expectedJson = "{\n" +
18+
" \"schema\" : {\n" +
19+
" \"type\" : \"array\",\n" +
20+
" \"items\" : {\n" +
21+
" \"type\" : \"object\",\n" +
22+
" \"properties\" : {\n" +
23+
" \"foo\" : {\n" +
24+
" \"type\" : \"string\"\n" +
25+
" }\n" +
26+
" }\n" +
27+
" }\n" +
28+
" },\n" +
29+
" \"referencedSchemas\" : {\n" +
30+
" \"CustomClass\" : {\n" +
31+
" \"type\" : \"object\",\n" +
32+
" \"properties\" : {\n" +
33+
" \"foo\" : {\n" +
34+
" \"type\" : \"string\"\n" +
35+
" }\n" +
36+
" }\n" +
37+
" }\n" +
38+
" }\n" +
39+
"}";
40+
SerializationMatchers.assertEqualsToJson(schema, expectedJson);
41+
ModelConverters.reset();
42+
schema = ModelConverters.getInstance(true, Schema.SchemaResolution.INLINE).resolveAsResolvedSchema(new AnnotatedType().type(CustomClass[].class));
43+
expectedJson = "{\n" +
44+
" \"schema\" : {\n" +
45+
" \"type\" : \"array\",\n" +
46+
" \"items\" : {\n" +
47+
" \"$ref\" : \"#/components/schemas/CustomClass\"\n" +
48+
" }\n" +
49+
" },\n" +
50+
" \"referencedSchemas\" : {\n" +
51+
" \"CustomClass\" : {\n" +
52+
" \"type\" : \"object\",\n" +
53+
" \"properties\" : {\n" +
54+
" \"foo\" : {\n" +
55+
" \"type\" : \"string\"\n" +
56+
" }\n" +
57+
" }\n" +
58+
" }\n" +
59+
" }\n" +
60+
"}";
61+
SerializationMatchers.assertEqualsToJson31(schema, expectedJson);
62+
ModelConverters.reset();
63+
System.setProperty(Schema.APPLY_SCHEMA_RESOLUTION_PROPERTY, "true");
64+
schema = ModelConverters.getInstance(true, Schema.SchemaResolution.INLINE).resolveAsResolvedSchema(new AnnotatedType().type(CustomClass[].class));
65+
expectedJson = "{\n" +
66+
" \"schema\" : {\n" +
67+
" \"type\" : \"array\",\n" +
68+
" \"items\" : {\n" +
69+
" \"type\" : \"object\",\n" +
70+
" \"properties\" : {\n" +
71+
" \"foo\" : {\n" +
72+
" \"type\" : \"string\"\n" +
73+
" }\n" +
74+
" }\n" +
75+
" }\n" +
76+
" },\n" +
77+
" \"referencedSchemas\" : {\n" +
78+
" \"CustomClass\" : {\n" +
79+
" \"type\" : \"object\",\n" +
80+
" \"properties\" : {\n" +
81+
" \"foo\" : {\n" +
82+
" \"type\" : \"string\"\n" +
83+
" }\n" +
84+
" }\n" +
85+
" }\n" +
86+
" }\n" +
87+
"}";
88+
SerializationMatchers.assertEqualsToJson31(schema, expectedJson);
89+
System.clearProperty(Schema.APPLY_SCHEMA_RESOLUTION_PROPERTY);
90+
ModelConverters.reset();
91+
92+
93+
}
94+
95+
private static class CustomClass {
96+
public String foo;
97+
}
98+
}

modules/swagger-models/src/main/java/io/swagger/v3/oas/models/media/Schema.java

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public String toString() {
4646
}
4747

4848
public static final String SCHEMA_RESOLUTION_PROPERTY = "schema-resolution";
49+
public static final String APPLY_SCHEMA_RESOLUTION_PROPERTY = "apply-schema-resolution";
4950
public enum SchemaResolution {
5051
@JsonProperty("default")
5152
DEFAULT("default"),

0 commit comments

Comments
 (0)