diff --git a/src/main/java/io/zenwave360/jsonrefparser/$RefParser.java b/src/main/java/io/zenwave360/jsonrefparser/$RefParser.java index 61a15db..e0f589f 100644 --- a/src/main/java/io/zenwave360/jsonrefparser/$RefParser.java +++ b/src/main/java/io/zenwave360/jsonrefparser/$RefParser.java @@ -146,10 +146,12 @@ private void mergeAllOf(Object value, String[] paths, URI currentFileURL) { // visited.add(value); if(paths.length > 0 && "allOf".equals(paths[paths.length -1])) { List allOf = (List) value; -// List required = new ArrayList<>(); -// Map properties = new LinkedHashMap<>(); -// Map mergedAllOfObject = new LinkedHashMap<>(); + String[] jsonPaths = Arrays.copyOf(paths, paths.length -1); + String jsonPath = jsonPath(jsonPaths); + Map originalAllOfRoot = refs.jsonContext.read(jsonPath); + AllOfObject allOfObject = new AllOfObject(); + merge(allOfObject, originalAllOfRoot); for (int i = 0; i < allOf.size(); i++) { if(allOf.get(i) instanceof Map) { Map item = (Map) allOf.get(i); @@ -158,14 +160,7 @@ private void mergeAllOf(Object value, String[] paths, URI currentFileURL) { throw new RuntimeException("Could not understand allOf: " + allOf.get(i)); } } -// if(!required.isEmpty()) { -// mergedAllOfObject.put("required", required); -// } -// if(!properties.isEmpty()) { -// mergedAllOfObject.put("properties", properties); -// } - String[] jsonPaths = Arrays.copyOf(paths, paths.length -1); - String jsonPath = jsonPath(jsonPaths); + try { var mergedAllOfObject = allOfObject.buildAllOfObject(); refs.jsonContext.set(jsonPath, mergedAllOfObject); @@ -199,7 +194,13 @@ private void merge(AllOfObject allOfObject, Map item) { List> items = (List) item.get("allOf"); merge(allOfObject, items); } else { - allOfObject.allOf.putAll(item); + for (Map.Entry entry : item.entrySet()) { + if(entry.getKey().equals("allOf")) { + merge(allOfObject, (List) item.get("allOf")); + } else { + allOfObject.allOf.put(entry.getKey(), entry.getValue()); + } + } if(item.containsKey("properties")) { allOfObject.properties.putAll((Map) item.get("properties")); } @@ -214,6 +215,7 @@ private static class AllOfObject { Map properties = new HashMap<>(); List required = new ArrayList<>(); + Map buildAllOfObject() { Map allOfObject = new LinkedHashMap<>(allOf); if(!required.isEmpty()) { diff --git a/src/test/java/io/zenwave360/jsonrefparser/ParserTest.java b/src/test/java/io/zenwave360/jsonrefparser/ParserTest.java index 1d92f64..e6ab47a 100644 --- a/src/test/java/io/zenwave360/jsonrefparser/ParserTest.java +++ b/src/test/java/io/zenwave360/jsonrefparser/ParserTest.java @@ -38,6 +38,8 @@ private void assertNoRefs(Object object) throws JsonProcessingException { Assert.assertFalse(hasRefs); } + + private void assertNoAllOfs(Object object) throws JsonProcessingException { String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object); boolean hasRefs = json.contains("allOf"); @@ -186,6 +188,15 @@ public void testDereferenceAndMerge_MultipleAllOf2() throws IOException { Assert.assertEquals(5, properties.size()); } + @Test + public void testDereferenceAndMergeChainedAllOf() throws IOException { + File file = new File("src/test/resources/asyncapi/car-engine_chained_allOf.yml"); + $RefParser parser = new $RefParser(file).parse(); + $Refs refs = parser.dereference().mergeAllOf().getRefs(); + // Assert.assertFalse(refs.circular); + System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(refs.schema())); + assertNoAllOfs(refs.schema()); + } @Test public void testDereference() throws IOException { diff --git a/src/test/resources/asyncapi/car-engine_chained_allOf.yml b/src/test/resources/asyncapi/car-engine_chained_allOf.yml new file mode 100644 index 0000000..cac5b7f --- /dev/null +++ b/src/test/resources/asyncapi/car-engine_chained_allOf.yml @@ -0,0 +1,45 @@ +asyncapi: '2.6.0' +info: + title: Account Service + version: 1.0.0 + description: This service is in charge of processing user signups +channels: + exampleOp: + subscribe: + operationId: exampleOp + message: + $ref: '#/components/messages/ExampleMessage' +components: + messages: + ExampleMessage: + payload: + $ref: '#/components/schemas/Car' + schemas: + Base: + type: object + additionalProperties: false + title: Base + properties: + reference: + type: string + Engine: + title: Engine + allOf: + - $ref: '#/components/schemas/Base' + - type: object + title: Engine + additionalProperties: false + properties: + mileage: + type: string + Car: + title: Car + allOf: + - $ref: '#/components/schemas/Engine' + - type: object + title: Car + additionalProperties: false + properties: + make: + type: string +