diff --git a/src/main/java/com/networknt/schema/BaseJsonValidator.java b/src/main/java/com/networknt/schema/BaseJsonValidator.java index 840c723f9..e9af87adf 100644 --- a/src/main/java/com/networknt/schema/BaseJsonValidator.java +++ b/src/main/java/com/networknt/schema/BaseJsonValidator.java @@ -41,6 +41,15 @@ public BaseJsonValidator(String schemaPath, JsonNode schemaNode, JsonSchema pare this.subSchema = obainSubSchemaNode(schemaNode); } + public BaseJsonValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, + ValidatorTypeCode validatorType, JsonSchema subSchema) { + this.schemaPath = schemaPath; + this.schemaNode = schemaNode; + this.parentSchema = parentSchema; + this.validatorType = validatorType; + this.subSchema = subSchema; + } + protected String getSchemaPath() { return schemaPath; } diff --git a/src/main/java/com/networknt/schema/JsonSchema.java b/src/main/java/com/networknt/schema/JsonSchema.java index 7136e05cb..9447b0c43 100644 --- a/src/main/java/com/networknt/schema/JsonSchema.java +++ b/src/main/java/com/networknt/schema/JsonSchema.java @@ -47,11 +47,23 @@ public class JsonSchema extends BaseJsonValidator { JsonSchema(ObjectMapper mapper, String schemaPath, JsonNode schemaNode, JsonSchema parent) { super(schemaPath, schemaNode, parent, null); - this.mapper = mapper; + this.init(mapper, schemaNode); + } - validators = new LinkedHashMap(); + JsonSchema(ObjectMapper mapper, String schemaPath, JsonNode schemaNode, + JsonSchema parent, JsonSchema subSchema) { + super(schemaPath, schemaNode, parent, null, subSchema); + this.init(mapper, schemaNode); + } - read(schemaNode); + public JsonSchema(ObjectMapper mapper, JsonNode schemaNode, JsonSchema subSchema) { + this(mapper, "#", schemaNode, null, subSchema); + } + + private void init(ObjectMapper mapper, JsonNode schemaNode) { + this.mapper = mapper; + this.validators = new LinkedHashMap(); + this.read(schemaNode); } /** diff --git a/src/main/java/com/networknt/schema/JsonSchemaFactory.java b/src/main/java/com/networknt/schema/JsonSchemaFactory.java index 97609d81e..3e53e3613 100644 --- a/src/main/java/com/networknt/schema/JsonSchemaFactory.java +++ b/src/main/java/com/networknt/schema/JsonSchemaFactory.java @@ -26,6 +26,10 @@ import java.net.URL; public class JsonSchemaFactory { + + // Draft 6 uses "$id" + private static final String DRAFT_4_ID = "id"; + private static final Logger logger = LoggerFactory .getLogger(JsonSchemaFactory.class); private ObjectMapper mapper; @@ -60,8 +64,15 @@ public JsonSchema getSchema(InputStream schemaStream) { public JsonSchema getSchema(URL schemaURL) { try { + JsonNode schemaNode = mapper.readTree(schemaURL.openStream()); + + if (this.idMatchesSourceUrl(schemaNode, schemaURL)) { + return new JsonSchema(mapper, schemaNode, null); + } + return new JsonSchema(mapper, schemaNode); + } catch (IOException ioe) { logger.error("Failed to load json schema!", ioe); throw new JsonSchemaException(ioe); @@ -72,4 +83,18 @@ public JsonSchema getSchema(JsonNode jsonNode) { return new JsonSchema(mapper, jsonNode); } + private boolean idMatchesSourceUrl(JsonNode schema, URL schemaUrl) { + + JsonNode idNode = schema.get(DRAFT_4_ID); + + if (idNode == null) { + return false; + } + + String id = idNode.asText(); + logger.info("Matching " + id + " to " + schemaUrl.toString()); + return id.equals(schemaUrl.toString()); + + } + } diff --git a/src/test/java/com/networknt/schema/JsonSchemaTest.java b/src/test/java/com/networknt/schema/JsonSchemaTest.java index adb4b4c6e..055f8523d 100644 --- a/src/test/java/com/networknt/schema/JsonSchemaTest.java +++ b/src/test/java/com/networknt/schema/JsonSchemaTest.java @@ -30,6 +30,7 @@ import java.io.File; import java.io.InputStream; +import java.net.URL; import java.util.ArrayList; import java.util.List; @@ -105,6 +106,14 @@ private void runTestFile(String testCaseFile) throws Exception { } } + @Test(/*expected = java.lang.StackOverflowError.class*/) + public void testLoadingWithId() throws Exception { + URL url = new URL("http://localhost:1234/self_ref/selfRef.json"); + JsonNode schemaJson = mapper.readTree(url); + JsonSchemaFactory factory = new JsonSchemaFactory(); + JsonSchema schema = factory.getSchema(schemaJson); + } + @Test public void testBignumValidator() throws Exception { runTestFile("tests/optional/bignum.json"); diff --git a/src/test/resources/tests/self_ref/selfRef.json b/src/test/resources/tests/self_ref/selfRef.json new file mode 100644 index 000000000..10b45dd68 --- /dev/null +++ b/src/test/resources/tests/self_ref/selfRef.json @@ -0,0 +1,4 @@ +{ + "id": "http://localhost:1234/self_ref/selfRef.json", + "description": "Schema with ID set to its own URL" +}