Repository: swagger-api/swagger-parser
Pull request #1276 (2019-12-19 18:36:20)

flattenComposedSchema Option - refs - #1275
flattenComposedSchema Option - refs - #1275


Patch:
diff --git a/modules/swagger-parser-core/src/main/java/io/swagger/v3/parser/core/models/ParseOptions.java b/modules/swagger-parser-core/src/main/java/io/swagger/v3/parser/core/models/ParseOptions.java
index 84569dfa..8de23203 100644
--- a/modules/swagger-parser-core/src/main/java/io/swagger/v3/parser/core/models/ParseOptions.java
+++ b/modules/swagger-parser-core/src/main/java/io/swagger/v3/parser/core/models/ParseOptions.java
@@ -5,6 +5,7 @@ public class ParseOptions {
     private boolean resolveCombinators = true;
     private boolean resolveFully;
     private boolean flatten;
+    private boolean flattenComposedSchemas;
     private boolean skipMatches;
 
     public boolean isResolve() {
@@ -42,4 +43,12 @@ public class ParseOptions {
     public void setSkipMatches(boolean skipMatches) {
         this.skipMatches = skipMatches;
     }
+
+    public boolean isFlattenComposedSchemas() {
+        return flattenComposedSchemas;
+    }
+
+    public void setFlattenComposedSchemas(boolean flattenComposedSchemas) {
+        this.flattenComposedSchemas = flattenComposedSchemas;
+    }
 }
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java
index 86e93afa..e4af7e1a 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java
@@ -70,7 +70,7 @@ public class OpenAPIV3Parser implements SwaggerParserExtension {
                             result.setOpenAPI(resolver.resolve());
                             new ResolverFully(options.isResolveCombinators()).resolveFully(result.getOpenAPI());
                         } else if (options.isFlatten()) {
-                            InlineModelResolver inlineModelResolver = new InlineModelResolver();
+                            InlineModelResolver inlineModelResolver = new InlineModelResolver(options.isFlattenComposedSchemas());
                             inlineModelResolver.setSkipMatches(options.isSkipMatches());
                             inlineModelResolver.flatten(result.getOpenAPI());
                         }
@@ -207,7 +207,7 @@ public class OpenAPIV3Parser implements SwaggerParserExtension {
                         result.setOpenAPI(new OpenAPIResolver(result.getOpenAPI(), auth, null).resolve());
                         new ResolverFully(options.isResolveCombinators()).resolveFully(result.getOpenAPI());
                     } else if (options.isFlatten()) {
-                        InlineModelResolver inlineModelResolver = new InlineModelResolver();
+                        InlineModelResolver inlineModelResolver = new InlineModelResolver(options.isFlattenComposedSchemas());
                         inlineModelResolver.setSkipMatches(options.isSkipMatches());
                         inlineModelResolver.flatten(result.getOpenAPI());
                     }
diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java
index c0fe565a..bd6e6b6d 100644
--- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java
+++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java
@@ -32,6 +32,15 @@ public class InlineModelResolver {
     Map<String, Schema> addedModels = new HashMap<>();
     Map<String, String> generatedSignature = new HashMap<>();
 
+    private boolean flattenComposedSchemas;
+
+
+    public InlineModelResolver(){this(false);}
+
+    public InlineModelResolver(boolean flattenComposedSchemas) {
+        this.flattenComposedSchemas = flattenComposedSchemas;
+    }
+
     public void flatten(OpenAPI openAPI) {
         this.openAPI = openAPI;
 
@@ -359,6 +368,32 @@ public class InlineModelResolver {
                     if (inner.getProperties() != null && inner.getProperties().size() > 0) {
                         flattenProperties(inner.getProperties(), path);
                         String modelName = resolveModelName(inner.getTitle(), path + "_" + key);
+                        Schema innerModel = createModelFromProperty(inner, modelName);
+                        String existing = matchGenerated(innerModel);
+                        if (existing != null) {
+                            ap.setItems(new Schema().$ref(existing));
+                        } else {
+                            ap.setItems(new Schema().$ref(modelName));
+                            addGenerated(modelName, innerModel);
+                            openAPI.getComponents().addSchemas(modelName, innerModel);
+                        }
+                    }else if(inner instanceof ComposedSchema && this.flattenComposedSchemas){
+                        ComposedSchema composedSchema = (ComposedSchema) inner;
+                        String modelName = resolveModelName(inner.getTitle(), path + "_" + key);
+                        List<Schema> list = null;
+                        if (composedSchema.getAllOf() != null) {
+                            list  = composedSchema.getAllOf();
+                        }else if (composedSchema.getAnyOf() != null) {
+                            list  = composedSchema.getAnyOf();
+                        }else if (composedSchema.getOneOf() != null) {
+                            list  = composedSchema.getOneOf();
+                        }
+                        for(int i= 0; i<list.size();i++){
+                            if(list.get(i).getProperties()!= null){
+                                flattenProperties(list.get(i).getProperties(), modelName);
+                            }
+                        }
+
                         Schema innerModel = createModelFromProperty(inner, modelName);
                         String existing = matchGenerated(innerModel);
                         if (existing != null) {
@@ -369,6 +404,7 @@ public class InlineModelResolver {
                             openAPI.getComponents().addSchemas(modelName, innerModel);
                         }
                     }
+
                 }
             } else if (property.getAdditionalProperties() != null && property.getAdditionalProperties() instanceof Schema) {
                 Schema inner = (Schema) property.getAdditionalProperties();
@@ -437,20 +473,36 @@ public class InlineModelResolver {
         XML xml = schema.getXml();
         Map<String, Schema> properties = schema.getProperties();
 
-        Schema model = new Schema();//TODO Verify this!
-        model.setDescription(description);
-        model.setExample(example);
-        model.setName(name);
-        model.setXml(xml);
-        model.setType(schema.getType());
-        model.setRequired(requiredList);
-
-        if (properties != null) {
-            flattenProperties(properties, path);
-            model.setProperties(properties);
-        }
 
-        return model;
+        if (schema instanceof ComposedSchema && this.flattenComposedSchemas){
+            ComposedSchema composedModel = (ComposedSchema) schema;
+
+            composedModel.setDescription(description);
+            composedModel.setExample(example);
+            composedModel.setName(name);
+            composedModel.setXml(xml);
+            composedModel.setType(schema.getType());
+            composedModel.setRequired(requiredList);
+
+            return composedModel;
+
+
+        } else {
+            Schema model = new Schema();//TODO Verify this!
+            model.setDescription(description);
+            model.setExample(example);
+            model.setName(name);
+            model.setXml(xml);
+            model.setType(schema.getType());
+            model.setRequired(requiredList);
+
+            if (properties != null) {
+                flattenProperties(properties, path);
+                model.setProperties(properties);
+            }
+
+            return model;
+        }
     }
 
     @SuppressWarnings("static-method")


Test patch:
diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java
index d19c9deb..e1c83bb2 100644
--- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java
+++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java
@@ -66,6 +66,37 @@ public class OpenAPIV3ParserTest {
     protected int serverPort = getDynamicPort();
     protected WireMockServer wireMockServer;
 
+
+    @Test
+    public void testFlattenComposedSchema() {
+        OpenAPIV3Parser openApiParser = new OpenAPIV3Parser();
+        ParseOptions options = new ParseOptions();
+        options.setResolve(true);
+        options.setFlatten(true);
+        options.setFlattenComposedSchemas(true);
+        SwaggerParseResult parseResult = openApiParser.readLocation("flattenComposedSchemaComplete.json", null, options);
+
+        OpenAPI openAPI = parseResult.getOpenAPI();
+        assertNotNull(openAPI.getComponents().getSchemas().get("val_Members_val_member"));
+        assertNotNull(openAPI.getComponents().getSchemas().get("val_MemberProducts_val_product"));
+
+    }
+
+    @Test
+    public void testNotFlattenComposedSchema() {
+        OpenAPIV3Parser openApiParser = new OpenAPIV3Parser();
+        ParseOptions options = new ParseOptions();
+        options.setResolve(true);
+        options.setFlatten(true);
+
+        SwaggerParseResult parseResult = openApiParser.readLocation("flattenComposedSchemaComplete.json", null, options);
+
+        OpenAPI openAPI = parseResult.getOpenAPI();
+        assertNull(openAPI.getComponents().getSchemas().get("val_Members_val_member"));
+        assertNotNull(openAPI.getComponents().getSchemas().get("val_MemberProducts_val_product"));
+
+    }
+
     @Test
     public void testCodegenIssue8601() {
         OpenAPIV3Parser openApiParser = new OpenAPIV3Parser();
diff --git a/modules/swagger-parser-v3/src/test/resources/flattenComposedSchemaComplete.json b/modules/swagger-parser-v3/src/test/resources/flattenComposedSchemaComplete.json
new file mode 100644
index 00000000..deddab71
--- /dev/null
+++ b/modules/swagger-parser-v3/src/test/resources/flattenComposedSchemaComplete.json
@@ -0,0 +1,115 @@
+{
+  "openapi": "3.0.2",
+  "info": {
+    "title": "test",
+    "version": "1.0.0"
+  },
+  "paths": {
+    "/validation": {
+      "post": {
+        "tags": [
+          "mytag"
+        ],
+        "summary": "summary",
+        "requestBody": {
+          "required": true,
+          "content": {
+            "application/json": {
+              "schema": {
+                "$ref": "#/components/schemas/mtg_Message"
+              }
+            }
+          }
+        },
+        "responses": {
+          "200": {
+            "description": "desc",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/mtg_Message"
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  },
+  "components": {
+    "schemas": {
+      "mtg_Message": {
+        "type": "object"
+      },
+      "val_MemberProducts": {
+        "additionalProperties": false,
+        "description": "val_MemberProducts desc",
+        "properties": {
+          "val_product": {
+            "items": {
+              "type": "object",
+              "properties": {
+                "val_unique_reference1": {
+                  "type": "string"
+                }
+              }
+            },
+            "maxItems": 4,
+            "minItems": 1,
+            "type": "array"
+          }
+        },
+        "required": [
+          "val_product"
+        ],
+        "type": "object"
+      },
+      "val_Members": {
+        "additionalProperties": false,
+        "description": "valmembers desc",
+        "properties": {
+          "val_member": {
+            "description": "valmember desc",
+            "items": {
+              "type": "object",
+              "oneOf": [
+                {
+                  "$ref": "#/components/schemas/val_MemberChoice1"
+                },
+                {
+                  "$ref": "#/components/schemas/val_MemberChoice2"
+                }
+              ]
+            },
+            "minItems": 1,
+            "type": "array"
+          }
+        },
+        "required": [
+          "val_member"
+        ],
+        "type": "object"
+      },
+      "val_MemberChoice1": {
+        "additionalProperties": false,
+        "description": "val_MemberChoice1 desc",
+        "properties": {
+          "val_unique_reference1": {
+            "type": "string"
+          }
+        },
+        "type": "object"
+      },
+      "val_MemberChoice2": {
+        "additionalProperties": false,
+        "description": "val_MemberChoice2 desc",
+        "properties": {
+          "val_unique_reference2": {
+            "type": "string"
+          }
+        },
+        "type": "object"
+      }
+    }
+  }
+}
\ No newline at end of file