Skip to content

Commit 7391200

Browse files
committed
Fix array references rewrites
1 parent 38f0949 commit 7391200

File tree

6 files changed

+191
-0
lines changed

6 files changed

+191
-0
lines changed

schema-util/json/src/main/java/io/apicurio/registry/content/dereference/JsonSchemaDereferencer.java

+11
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.fasterxml.jackson.databind.DeserializationFeature;
2121
import com.fasterxml.jackson.databind.JsonNode;
2222
import com.fasterxml.jackson.databind.ObjectMapper;
23+
import com.fasterxml.jackson.databind.node.ArrayNode;
2324
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
2425
import com.fasterxml.jackson.databind.node.ObjectNode;
2526
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
@@ -132,6 +133,8 @@ public ContentHandle rewriteReferences(ContentHandle content, Map<String, String
132133
private void rewriteIn(JsonNode node, Map<String, String> resolvedReferenceUrls) {
133134
if (node.isObject()) {
134135
rewriteInObject((ObjectNode) node, resolvedReferenceUrls);
136+
} else if (node.isArray()) {
137+
rewriteInArray((ArrayNode) node, resolvedReferenceUrls);
135138
}
136139
}
137140

@@ -155,7 +158,15 @@ private void rewriteInObject(ObjectNode node, Map<String, String> resolvedRefere
155158
JsonNode fieldValue = node.get(fieldName);
156159
if (fieldValue.isObject()) {
157160
rewriteInObject((ObjectNode) fieldValue, resolvedReferenceUrls);
161+
} else if (fieldValue.isArray()) {
162+
rewriteInArray((ArrayNode) fieldValue, resolvedReferenceUrls);
158163
}
159164
}
160165
}
166+
167+
private void rewriteInArray(ArrayNode node, Map<String, String> resolvedReferenceUrls) {
168+
node.forEach(innerNode -> {
169+
rewriteIn(innerNode, resolvedReferenceUrls);
170+
});
171+
}
161172
}

schema-util/json/src/main/java/io/apicurio/registry/content/refs/JsonSchemaReferenceFinder.java

+4
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ private static void findExternalTypesIn(JsonNode schema, Set<String> externalTyp
7474
Entry<String, JsonNode> field = fields.next();
7575
findExternalTypesIn(field.getValue(), externalTypes);
7676
}
77+
} else if (schema.isArray()) {
78+
schema.forEach(innerNode -> {
79+
findExternalTypesIn(innerNode, externalTypes);
80+
});
7781
}
7882
}
7983

schema-util/util-provider/src/test/java/io/apicurio/registry/content/dereference/JsonSchemaContentDereferencerTest.java

+29
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,33 @@ public void testMultipleRefsUseSingleFile() {
9898
String expectedContent = resourceToString("expected-testDereference-property-level-json.json");
9999
Assertions.assertEquals(normalizeMultiLineString(expectedContent), normalizeMultiLineString(modifiedContent.content()));
100100
}
101+
102+
@Test
103+
public void testDerefAllOf() throws Exception {
104+
ContentHandle content = resourceToContentHandle("order.json");
105+
JsonSchemaDereferencer dereferencer = new JsonSchemaDereferencer();
106+
107+
Map<String, ContentHandle> resolvedReferences = new LinkedHashMap<>();
108+
109+
resolvedReferences.put("customer.json",resourceToContentHandle("customer.json"));
110+
111+
ContentHandle modifiedContent = dereferencer.dereference(content, resolvedReferences);
112+
113+
String expectedContent = resourceToString("expected-order-deref.json");
114+
Assertions.assertEquals(normalizeMultiLineString(expectedContent),
115+
normalizeMultiLineString(modifiedContent.content()));
116+
}
117+
118+
@Test
119+
public void testRewriteAllOfReferences() {
120+
ContentHandle content = resourceToContentHandle("order.json");
121+
JsonSchemaDereferencer dereferencer = new JsonSchemaDereferencer();
122+
ContentHandle modifiedContent = dereferencer.rewriteReferences(content,
123+
Map.of("customer.json", "https://www.example.org/schemas/customer.json"));
124+
125+
ReferenceFinder finder = new JsonSchemaReferenceFinder();
126+
Set<ExternalReference> externalReferences = finder.findExternalReferences(modifiedContent);
127+
Assertions.assertTrue(externalReferences
128+
.contains(new JsonPointerExternalReference("https://www.example.org/schemas/customer.json")));
129+
}
101130
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"$id": "https://test/schemas/CustomerSchema.json",
3+
"$schema": "https://json-schema.org/draft/2020-12/schema",
4+
"title": "Customer",
5+
"type": "object",
6+
"properties": {
7+
"customerId": {
8+
"type": "string",
9+
"description": "A unique identifier for the customer."
10+
},
11+
"name": {
12+
"type": "string",
13+
"description": "The full name of the customer."
14+
},
15+
"email": {
16+
"type": "string",
17+
"format": "email",
18+
"description": "The email address of the customer."
19+
}
20+
},
21+
"required": ["customerId", "name", "email"]
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
{
2+
"allOf" : [ {
3+
"title" : "Customer",
4+
"type" : "object",
5+
"properties" : {
6+
"customerId" : {
7+
"description" : "A unique identifier for the customer.",
8+
"type" : "string"
9+
},
10+
"name" : {
11+
"description" : "The full name of the customer.",
12+
"type" : "string"
13+
},
14+
"email" : {
15+
"format" : "email",
16+
"description" : "The email address of the customer.",
17+
"type" : "string"
18+
}
19+
},
20+
"required" : [ "customerId", "name", "email" ]
21+
} ],
22+
"oneOf" : [ {
23+
"title" : "Customer",
24+
"type" : "object",
25+
"properties" : {
26+
"customerId" : {
27+
"description" : "A unique identifier for the customer.",
28+
"type" : "string"
29+
},
30+
"name" : {
31+
"description" : "The full name of the customer.",
32+
"type" : "string"
33+
},
34+
"email" : {
35+
"format" : "email",
36+
"description" : "The email address of the customer.",
37+
"type" : "string"
38+
}
39+
},
40+
"required" : [ "customerId", "name", "email" ]
41+
} ],
42+
"$schema" : "http://json-schema.org/draft-07/schema#",
43+
"anyOf" : [ {
44+
"title" : "Customer",
45+
"type" : "object",
46+
"properties" : {
47+
"customerId" : {
48+
"description" : "A unique identifier for the customer.",
49+
"type" : "string"
50+
},
51+
"name" : {
52+
"description" : "The full name of the customer.",
53+
"type" : "string"
54+
},
55+
"email" : {
56+
"format" : "email",
57+
"description" : "The email address of the customer.",
58+
"type" : "string"
59+
}
60+
},
61+
"required" : [ "customerId", "name", "email" ]
62+
} ],
63+
"title" : "Order",
64+
"type" : "object",
65+
"properties" : {
66+
"orderId" : {
67+
"description" : "A unique identifier for the order.",
68+
"type" : "string"
69+
},
70+
"orderDate" : {
71+
"format" : "date-time",
72+
"description" : "The date when the order was placed.",
73+
"type" : "string"
74+
},
75+
"orderTotal" : {
76+
"format" : "float",
77+
"description" : "The total amount of the order.",
78+
"type" : "number"
79+
}
80+
},
81+
"required" : [ "orderId", "customer", "orderTotal" ],
82+
"$id" : "https://test/schemas/OrderSchema.json"
83+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"$id": "https://test/schemas/OrderSchema.json",
3+
"$schema": "http://json-schema.org/draft-07/schema#",
4+
"title": "Order",
5+
"type": "object",
6+
"allOf": [
7+
{
8+
"$ref": "customer.json"
9+
}
10+
],
11+
"anyOf": [
12+
{
13+
"$ref": "customer.json"
14+
}
15+
],
16+
"oneOf": [
17+
{
18+
"$ref": "customer.json"
19+
}
20+
],
21+
"properties": {
22+
"orderId": {
23+
"type": "string",
24+
"description": "A unique identifier for the order."
25+
},
26+
"orderDate": {
27+
"type": "string",
28+
"format": "date-time",
29+
"description": "The date when the order was placed."
30+
},
31+
"orderTotal": {
32+
"type": "number",
33+
"format": "float",
34+
"description": "The total amount of the order."
35+
}
36+
},
37+
"required": [
38+
"orderId",
39+
"customer",
40+
"orderTotal"
41+
]
42+
}

0 commit comments

Comments
 (0)