Skip to content

Commit d3f1dd7

Browse files
committed
Finish the resolve
Signed-off-by: Paulo Lopes <[email protected]>
1 parent 6e71405 commit d3f1dd7

File tree

3 files changed

+58
-12
lines changed

3 files changed

+58
-12
lines changed

src/main/java/io/vertx/json/schema/JsonSchema.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,7 @@ static JsonSchema of(boolean bool) {
110110
Set<String> fieldNames();
111111

112112
/**
113-
* Tries to resolve all internal references. External references are resolved so you need to
114-
* inline them yourself if required.
113+
* Tries to resolve all internal references. External references are not resolved.
115114
*
116115
* The result is an object where all references have been resolved. Resolution of references is shallow This
117116
* should normally not be a problem for this use case.

src/main/java/io/vertx/json/schema/impl/JsonObjectSchema.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ public final class JsonObjectSchema extends JsonObject implements JsonSchema {
2525

2626
public JsonObjectSchema(JsonObject json) {
2727
super(json.getMap());
28+
// inherit the annotated flag
29+
this.annotated =
30+
json.containsKey("__absolute_uri__") ||
31+
json.containsKey("__absolute_ref__") ||
32+
json.containsKey("__absolute_recursive_ref__");
2833
}
2934

3035
@Override
@@ -81,7 +86,7 @@ public JsonObject resolve() {
8186
final Map<String, List<Ref>> pointers = new HashMap<>();
8287

8388
// find all refs
84-
parse(tree, "#", "", pointers);
89+
findRefsAndClean(tree, "#", "", pointers);
8590

8691
// resolve them
8792
final Map<String, JsonObject> anchors = new HashMap<>();
@@ -229,22 +234,31 @@ private static final class Ref {
229234
}
230235
}
231236

232-
private static void parse(Object obj, String path, String id, Map<String, List<Ref>> pointers) {
237+
private static void findRefsAndClean(Object obj, String path, String id, Map<String, List<Ref>> pointers) {
233238
if (!isObject(obj)) {
234239
return;
235240
}
236241
if (obj instanceof JsonObject) {
237242
final JsonObject json = (JsonObject) obj;
243+
244+
// clean up annotations
245+
json.remove("__absolute_uri__");
246+
json.remove("__absolute_ref__");
247+
json.remove("__absolute_recursive_ref__");
248+
249+
// compute the id (according to draft-4 or later)
238250
if (json.containsKey("$id") || json.containsKey("id")) {
239251
id = json.getString("$id", json.getString("id"));
240252
}
253+
254+
// process the object
241255
for (String prop : json.fieldNames()) {
242256
if (POINTER_KEYWORD.contains(prop)) {
243257
pointers
244258
.computeIfAbsent(prop, key -> new ArrayList<>())
245259
.add(new Ref(json.getString(prop), json, prop, path, id));
246260
}
247-
parse(json.getValue(prop), path + "/" + Utils.Pointers.encode(prop), id, pointers);
261+
findRefsAndClean(json.getValue(prop), path + "/" + Utils.Pointers.encode(prop), id, pointers);
248262
}
249263
}
250264
}
Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,31 @@
11
package io.vertx.json.schema;
22

3+
import io.vertx.core.buffer.Buffer;
34
import io.vertx.core.json.JsonObject;
4-
import io.vertx.junit5.Timeout;
55
import org.junit.jupiter.api.Test;
66

7-
import java.util.concurrent.TimeUnit;
7+
import java.io.IOException;
8+
import java.nio.file.Files;
9+
import java.nio.file.Paths;
810

911
import static org.assertj.core.api.Assertions.assertThat;
12+
import static org.assertj.core.api.Assertions.fail;
1013

1114
public class ResolverTest {
1215

1316
@Test
14-
@Timeout(value = 10, timeUnit = TimeUnit.SECONDS)
1517
public void testResolves() {
16-
JsonObject res =
17-
JsonSchema
18-
.of(new JsonObject("{\"$id\":\"http://www.example.com/\",\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"definitions\":{\"address\":{\"type\":\"object\",\"properties\":{\"street_address\":{\"type\":\"string\"},\"city\":{\"type\":\"string\"},\"state\":{\"type\":\"string\"},\"subAddress\":{\"$ref\":\"http://www.example.com/#/definitions/address\"}}},\"req\":{\"required\":[\"billing_address\"]}},\"type\":\"object\",\"properties\":{\"billing_address\":{\"$ref\":\"#/definitions/address\"},\"shipping_address\":{\"$ref\":\"#/definitions/address\"}},\"$ref\":\"#/definitions/req\"}"))
19-
.resolve();
18+
19+
SchemaRepository repo = SchemaRepository.create(new JsonSchemaOptions().setBaseUri("http://vertx.io"));
20+
21+
JsonSchema schema = JsonSchema
22+
.of(new JsonObject("{\"$id\":\"http://www.example.com/\",\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"definitions\":{\"address\":{\"type\":\"object\",\"properties\":{\"street_address\":{\"type\":\"string\"},\"city\":{\"type\":\"string\"},\"state\":{\"type\":\"string\"},\"subAddress\":{\"$ref\":\"http://www.example.com/#/definitions/address\"}}},\"req\":{\"required\":[\"billing_address\"]}},\"type\":\"object\",\"properties\":{\"billing_address\":{\"$ref\":\"#/definitions/address\"},\"shipping_address\":{\"$ref\":\"#/definitions/address\"}},\"$ref\":\"#/definitions/req\"}"));
23+
24+
repo.dereference(schema);
25+
26+
String before = schema.toString();
27+
28+
JsonObject res = schema.resolve();
2029

2130
JsonObject ptr = res.getJsonObject("properties").getJsonObject("billing_address").getJsonObject("properties");
2231
assertThat(ptr.getJsonObject("city").getString("type"))
@@ -30,5 +39,29 @@ public void testResolves() {
3039
// array checks
3140
assertThat(res.getJsonArray("required").getString(0))
3241
.isEqualTo("billing_address");
42+
43+
assertThat(res.encodePrettily().contains("__absolute_uri")).isFalse();
44+
assertThat(res.encodePrettily().contains("__absolute_ref")).isFalse();
45+
assertThat(res.encodePrettily().contains("__absolute_recursive_ref")).isFalse();
46+
47+
String after = schema.toString();
48+
49+
// ensure that the clean up operation doesn't affect the source object
50+
assertThat(before).isEqualTo(after);
51+
52+
}
53+
54+
@Test
55+
public void testRefResolverFail() throws IOException {
56+
try {
57+
JsonObject res =
58+
JsonSchema
59+
.of(new JsonObject(Buffer.buffer(Files.readAllBytes(Paths.get("src", "test", "resources", "ref_test", "person_draft201909.json")))))
60+
.resolve();
61+
62+
fail("Should not reach here");
63+
} catch (SchemaException e) {
64+
// OK
65+
}
3366
}
3467
}

0 commit comments

Comments
 (0)