Skip to content

Commit

Permalink
fixes merging allOf when allOf is mixed with normal properties
Browse files Browse the repository at this point in the history
  • Loading branch information
ivangsa committed Nov 6, 2024
1 parent 0bde6bd commit 877af49
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 12 deletions.
26 changes: 14 additions & 12 deletions src/main/java/io/zenwave360/jsonrefparser/$RefParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> required = new ArrayList<>();
// Map<String, Object> properties = new LinkedHashMap<>();
// Map<String, Object> mergedAllOfObject = new LinkedHashMap<>();
String[] jsonPaths = Arrays.copyOf(paths, paths.length -1);
String jsonPath = jsonPath(jsonPaths);
Map<String, Object> 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<String, Object> item = (Map<String, Object>) allOf.get(i);
Expand All @@ -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);
Expand Down Expand Up @@ -199,7 +194,13 @@ private void merge(AllOfObject allOfObject, Map<String, Object> item) {
List<Map<String, Object>> items = (List) item.get("allOf");
merge(allOfObject, items);
} else {
allOfObject.allOf.putAll(item);
for (Map.Entry<String, Object> 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"));
}
Expand All @@ -214,6 +215,7 @@ private static class AllOfObject {
Map<String, Object> properties = new HashMap<>();
List<String> required = new ArrayList<>();


Map<String, Object> buildAllOfObject() {
Map<String, Object> allOfObject = new LinkedHashMap<>(allOf);
if(!required.isEmpty()) {
Expand Down
11 changes: 11 additions & 0 deletions src/test/java/io/zenwave360/jsonrefparser/ParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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 {
Expand Down
45 changes: 45 additions & 0 deletions src/test/resources/asyncapi/car-engine_chained_allOf.yml
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 877af49

Please sign in to comment.