Skip to content

Commit 9d20dcb

Browse files
authored
Merge pull request #1386 from swagger-api/issue_1385
Fix for Flatten Map Schema when Inline ComposedSchema
2 parents 0915dc4 + de21010 commit 9d20dcb

File tree

5 files changed

+140
-78
lines changed

5 files changed

+140
-78
lines changed

modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java

Lines changed: 69 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ public void flatten(OpenAPI openAPI) {
9696
} else if (model instanceof ArraySchema) {
9797
ArraySchema am = (ArraySchema) model;
9898
Schema inner = am.getItems();
99-
10099
if (isObjectSchema(inner)) {
101100
if (inner.getProperties() != null && inner.getProperties().size() > 0) {
102101
flattenProperties(inner.getProperties(), pathname);
@@ -186,7 +185,7 @@ public void flatten(OpenAPI openAPI) {
186185
if (media.getSchema() != null) {
187186
Schema mediaSchema = media.getSchema();
188187
if (isObjectSchema(mediaSchema)) {
189-
if (mediaSchema.getProperties() != null && mediaSchema.getProperties().size() > 0) {
188+
if (mediaSchema.getProperties() != null && mediaSchema.getProperties().size() > 0 || mediaSchema instanceof ComposedSchema) {
190189
String modelName = resolveModelName(mediaSchema.getTitle(), "inline_response_" + key);
191190
String existing = matchGenerated(mediaSchema);
192191
if (existing != null) {
@@ -196,63 +195,31 @@ public void flatten(OpenAPI openAPI) {
196195
addGenerated(modelName, mediaSchema);
197196
openAPI.getComponents().addSchemas(modelName, mediaSchema);
198197
}
199-
}else if (mediaSchema instanceof ComposedSchema) {
200-
String modelName = resolveModelName(mediaSchema.getTitle(), "inline_response_" + key);
201-
String existing = matchGenerated(mediaSchema);
202-
if (existing != null) {
203-
media.setSchema(this.makeRefProperty(existing, mediaSchema));
204-
} else {
205-
media.setSchema(this.makeRefProperty(modelName, mediaSchema));
206-
addGenerated(modelName, mediaSchema);
207-
openAPI.getComponents().addSchemas(modelName, mediaSchema);
198+
}else if (mediaSchema.getAdditionalProperties() != null && !(mediaSchema.getAdditionalProperties() instanceof Boolean)) {
199+
Schema innerProperty = (Schema) mediaSchema.getAdditionalProperties();
200+
if (isObjectSchema(innerProperty)) {
201+
key = "inline_response_map" + key;
202+
flattenMapSchema(innerProperty, key, pathname, mediaSchema);
203+
} else if (innerProperty instanceof ArraySchema) {
204+
ArraySchema arraySchema = (ArraySchema) innerProperty;
205+
Schema inner = arraySchema.getItems();
206+
if (isObjectSchema(inner)) {
207+
key = "inline_response_map_items" + key;
208+
flattenMapSchema(inner,key,pathname,mediaSchema);
209+
}
208210
}
209211
}
210-
211212
}else if (mediaSchema instanceof ArraySchema) {
212213
ArraySchema ap = (ArraySchema) mediaSchema;
213214
Schema inner = ap.getItems();
214-
215215
if (isObjectSchema(inner)) {
216-
if (inner.getProperties() != null && inner.getProperties().size() > 0) {
217-
flattenProperties(inner.getProperties(), pathname);
218-
String modelName = resolveModelName(inner.getTitle(),
219-
"inline_response_" + key);
220-
String existing = matchGenerated(inner);
221-
if (existing != null) {
222-
ap.setItems(this.makeRefProperty(existing, inner));
223-
} else {
224-
ap.setItems(this.makeRefProperty(modelName, inner));
225-
addGenerated(modelName, inner);
226-
openAPI.getComponents().addSchemas(modelName, inner);
227-
}
228-
}else if (inner instanceof ComposedSchema && this.flattenComposedSchemas){
229-
flattenComposedSchema(inner,key);
230-
if (inner.get$ref() == null) {
231-
String modelName = resolveModelName(inner.getTitle(), "inline_response_items" + key);
232-
ap.setItems(this.makeRefProperty(modelName, inner));
233-
addGenerated(modelName, inner);
234-
openAPI.getComponents().addSchemas(modelName, inner);
235-
}
236-
}
216+
flattenArraySchema(inner, key, pathname, ap);
237217
}
238-
239-
} else if (mediaSchema.getAdditionalProperties() != null && mediaSchema.getAdditionalProperties() instanceof Schema) {
240-
218+
} else if (mediaSchema.getAdditionalProperties() != null && !(mediaSchema.getAdditionalProperties() instanceof Boolean)) {
241219
Schema innerProperty = (Schema) mediaSchema.getAdditionalProperties();
242220
if (isObjectSchema(innerProperty)) {
243-
if (innerProperty.getProperties() != null && innerProperty.getProperties().size() > 0) {
244-
flattenProperties(innerProperty.getProperties(), pathname);
245-
String modelName = resolveModelName(innerProperty.getTitle(),
246-
"inline_response_" + key);
247-
String existing = matchGenerated(innerProperty);
248-
if (existing != null) {
249-
mediaSchema.setAdditionalProperties(new Schema().$ref(existing));
250-
} else {
251-
mediaSchema.setAdditionalProperties(new Schema().$ref(modelName));
252-
addGenerated(modelName, innerProperty);
253-
openAPI.getComponents().addSchemas(modelName, innerProperty);
254-
}
255-
}
221+
key = "inline_response_map" + key;
222+
flattenMapSchema(innerProperty, key, pathname, mediaSchema);
256223
}
257224
}
258225
}
@@ -301,7 +268,6 @@ public void flatten(OpenAPI openAPI) {
301268
} else if (model instanceof ComposedSchema) {
302269
ComposedSchema composedSchema = (ComposedSchema) model;
303270
String inlineModelName = "";
304-
305271
List<Schema> list = null;
306272
if (composedSchema.getAllOf() != null) {
307273
list = composedSchema.getAllOf();
@@ -334,6 +300,54 @@ public void flatten(OpenAPI openAPI) {
334300
}
335301
}
336302

303+
private void flattenArraySchema(Schema inner, String key, String pathname, ArraySchema ap) {
304+
if (inner.getProperties() != null && inner.getProperties().size() > 0) {
305+
flattenProperties(inner.getProperties(), pathname);
306+
key = "inline_response_" + key;
307+
String modelName = resolveModelName(inner.getTitle(), key);
308+
String existing = matchGenerated(inner);
309+
if (existing != null) {
310+
ap.setItems(this.makeRefProperty(existing, inner));
311+
} else {
312+
ap.setItems(this.makeRefProperty(modelName, inner));
313+
addGenerated(modelName, inner);
314+
openAPI.getComponents().addSchemas(modelName, inner);
315+
}
316+
}else if (inner instanceof ComposedSchema && this.flattenComposedSchemas){
317+
flattenComposedSchema(inner,key);
318+
if (inner.get$ref() == null) {
319+
key = "inline_response_items" + key;
320+
String modelName = resolveModelName(inner.getTitle(), key );
321+
ap.setItems(this.makeRefProperty(modelName, inner));
322+
addGenerated(modelName, inner);
323+
openAPI.getComponents().addSchemas(modelName, inner);
324+
}
325+
}
326+
}
327+
328+
329+
private void flattenMapSchema(Schema innerProperty, String key, String pathname, Schema mediaSchema) {
330+
if (innerProperty.getProperties() != null && innerProperty.getProperties().size() > 0) {
331+
flattenProperties(innerProperty.getProperties(), pathname);
332+
String modelName = resolveModelName(innerProperty.getTitle(), key);
333+
String existing = matchGenerated(innerProperty);
334+
if (existing != null) {
335+
mediaSchema.setAdditionalProperties(new Schema().$ref(existing));
336+
} else {
337+
mediaSchema.setAdditionalProperties(new Schema().$ref(modelName));
338+
addGenerated(modelName, innerProperty);
339+
openAPI.getComponents().addSchemas(modelName, innerProperty);
340+
}
341+
}else if (innerProperty instanceof ComposedSchema && this.flattenComposedSchemas){
342+
flattenComposedSchema(innerProperty,key);
343+
if (innerProperty.get$ref() == null) {
344+
String modelName = resolveModelName(innerProperty.getTitle(), key);
345+
mediaSchema.setAdditionalProperties(new Schema().$ref(modelName));
346+
addGenerated(modelName, innerProperty);
347+
openAPI.getComponents().addSchemas(modelName, innerProperty);
348+
}
349+
}
350+
}
337351

338352

339353
/**
@@ -418,12 +432,9 @@ public void flattenProperties(Map<String, Schema> properties, String path) {
418432
for (String key : properties.keySet()) {
419433
Schema property = properties.get(key);
420434
if (isObjectSchema(property) && property.getProperties() != null && property.getProperties().size() > 0) {
421-
422435
String modelName = resolveModelName(property.getTitle(), path + "_" + key);
423436
Schema model = createModelFromProperty(property, modelName);
424-
425437
String existing = matchGenerated(model);
426-
427438
if (existing != null) {
428439
propsToUpdate.put(key, new Schema().$ref(existing));
429440
} else {
@@ -435,7 +446,6 @@ public void flattenProperties(Map<String, Schema> properties, String path) {
435446
} else if (property instanceof ArraySchema) {
436447
ArraySchema ap = (ArraySchema) property;
437448
Schema inner = ap.getItems();
438-
439449
if (isObjectSchema(inner)) {
440450
if (inner.getProperties() != null && inner.getProperties().size() > 0) {
441451
flattenProperties(inner.getProperties(), path);
@@ -449,23 +459,9 @@ public void flattenProperties(Map<String, Schema> properties, String path) {
449459
addGenerated(modelName, innerModel);
450460
openAPI.getComponents().addSchemas(modelName, innerModel);
451461
}
452-
}else if (inner instanceof ComposedSchema && this.flattenComposedSchemas){
453-
ComposedSchema composedSchema = (ComposedSchema) inner;
462+
}else if (inner instanceof ComposedSchema && this.flattenComposedSchemas) {
463+
flattenComposedSchema(inner,key);
454464
String modelName = resolveModelName(inner.getTitle(), path + "_" + key);
455-
List<Schema> list = null;
456-
if (composedSchema.getAllOf() != null) {
457-
list = composedSchema.getAllOf();
458-
}else if (composedSchema.getAnyOf() != null) {
459-
list = composedSchema.getAnyOf();
460-
}else if (composedSchema.getOneOf() != null) {
461-
list = composedSchema.getOneOf();
462-
}
463-
for(int i= 0; i<list.size();i++){
464-
if (list.get(i).getProperties()!= null){
465-
flattenProperties(list.get(i).getProperties(), modelName);
466-
}
467-
}
468-
469465
Schema innerModel = createModelFromProperty(inner, modelName);
470466
String existing = matchGenerated(innerModel);
471467
if (existing != null) {
@@ -476,11 +472,9 @@ public void flattenProperties(Map<String, Schema> properties, String path) {
476472
openAPI.getComponents().addSchemas(modelName, innerModel);
477473
}
478474
}
479-
480475
}
481-
} else if (property.getAdditionalProperties() != null && property.getAdditionalProperties() instanceof Schema) {
476+
} else if (property.getAdditionalProperties() != null && !(property.getAdditionalProperties() instanceof Boolean)) {
482477
Schema inner = (Schema) property.getAdditionalProperties();
483-
484478
if (isObjectSchema(inner)) {
485479
if (inner.getProperties() != null && inner.getProperties().size() > 0) {
486480
flattenProperties(inner.getProperties(), path);
@@ -623,11 +617,9 @@ public Schema modelFromProperty(Schema object, @SuppressWarnings("unused") Strin
623617
ArraySchema model = new ArraySchema();
624618
model.setDescription(description);
625619
model.setExample(example);
626-
if (object.getAdditionalProperties() != null && object.getAdditionalProperties() instanceof Schema) {
620+
if (object.getAdditionalProperties() != null && !(object.getAdditionalProperties() instanceof Boolean)) {
627621
model.setItems((Schema) object.getAdditionalProperties());
628622
}
629-
630-
631623
return model;
632624
}
633625

modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,27 @@ public class OpenAPIV3ParserTest {
8282
protected int serverPort = getDynamicPort();
8383
protected WireMockServer wireMockServer;
8484

85+
86+
@Test
87+
public void testIssueFlattenAdditionalPropertiesSchemaInlineModelTrue() {
88+
OpenAPIV3Parser openApiParser = new OpenAPIV3Parser();
89+
ParseOptions options = new ParseOptions();
90+
options.setResolve(true);
91+
options.setFlatten(true);
92+
options.setFlattenComposedSchemas(true);
93+
options.setCamelCaseFlattenNaming(true);
94+
SwaggerParseResult parseResult = openApiParser.readLocation("additionalPropertiesFlatten.yaml", null, options);
95+
OpenAPI openAPI = parseResult.getOpenAPI();
96+
97+
//responses
98+
assertNotNull(openAPI.getComponents().getSchemas().get("Inline_response_map200"));
99+
assertEquals(((ComposedSchema)openAPI.getComponents().getSchemas().get("Inline_response_map200")).getOneOf().get(0).get$ref(),"#/components/schemas/Macaw1");
100+
assertNotNull(openAPI.getComponents().getSchemas().get("Inline_response_map_items404"));
101+
assertEquals(((ComposedSchema)openAPI.getComponents().getSchemas().get("Inline_response_map_items404")).getAnyOf().get(0).get$ref(),"#/components/schemas/Macaw2");
102+
103+
}
104+
105+
85106
@Test
86107
public void testIssueFlattenArraySchemaItemsInlineModelFalse() {
87108
OpenAPIV3Parser openApiParser = new OpenAPIV3Parser();

modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/InlineModelResolverTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,7 @@ public void testInlineMapResponseWithObjectSchema() throws Exception {
951951
assertEquals("ext-prop", property.getExtensions().get("x-ext"));
952952
assertTrue(openAPI.getComponents().getSchemas().size() == 1);
953953

954-
Schema inline = openAPI.getComponents().getSchemas().get("inline_response_200");
954+
Schema inline = openAPI.getComponents().getSchemas().get("inline_response_map200");
955955
assertTrue(inline instanceof Schema);
956956
assertNotNull(inline.getProperties().get("name"));
957957
assertTrue(inline.getProperties().get("name") instanceof StringSchema);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
openapi: 3.0.2
2+
info:
3+
title: test - OAS3
4+
version: 1.0.0
5+
paths:
6+
/responses:
7+
get:
8+
responses:
9+
'200':
10+
description: it works!
11+
content:
12+
application/json:
13+
schema:
14+
additionalProperties:
15+
oneOf:
16+
- "$ref": "#/components/schemas/Macaw1"
17+
- "$ref": "#/components/schemas/Parakeet1"
18+
'404':
19+
description: it works!
20+
content:
21+
application/json:
22+
schema:
23+
additionalProperties:
24+
type: array
25+
items:
26+
anyOf:
27+
- "$ref": "#/components/schemas/Macaw2"
28+
- "$ref": "#/components/schemas/Parakeet2"
29+

modules/swagger-parser-v3/src/test/resources/flattenArrayItems.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,26 @@ paths:
4242
anyOf:
4343
- "$ref": "#/components/schemas/Macaw3"
4444
- "$ref": "#/components/schemas/Parakeet3"
45+
'404':
46+
description: it works!
47+
content:
48+
application/json:
49+
schema:
50+
additionalProperties:
51+
oneOf:
52+
- "$ref": "#/components/schemas/Macaw4"
53+
- "$ref": "#/components/schemas/Parakeet4"
54+
'500':
55+
description: it works!
56+
content:
57+
application/json:
58+
schema:
59+
additionalProperties:
60+
type: array
61+
items:
62+
anyOf:
63+
- "$ref": "#/components/schemas/Macaw5"
64+
- "$ref": "#/components/schemas/Parakeet5"
4565
/requestBodies:
4666
post:
4767
requestBody:

0 commit comments

Comments
 (0)