From d7cceca3f66d27efb87cc37204b4abee87519cb2 Mon Sep 17 00:00:00 2001 From: Radu Dan Almasan Date: Wed, 15 Dec 2021 13:35:57 -0600 Subject: [PATCH] fix using patternProperties in nested objects --- .../JsonSchemaValidatorFactory.java | 8 ++- .../jsonschema/JsonSchemaValidatorTest.java | 63 ++++++++++++++----- 2 files changed, 52 insertions(+), 19 deletions(-) diff --git a/johnzon-jsonschema/src/main/java/org/apache/johnzon/jsonschema/JsonSchemaValidatorFactory.java b/johnzon-jsonschema/src/main/java/org/apache/johnzon/jsonschema/JsonSchemaValidatorFactory.java index 14103bc..ffe5b8d 100644 --- a/johnzon-jsonschema/src/main/java/org/apache/johnzon/jsonschema/JsonSchemaValidatorFactory.java +++ b/johnzon-jsonschema/src/main/java/org/apache/johnzon/jsonschema/JsonSchemaValidatorFactory.java @@ -197,7 +197,11 @@ public class JsonSchemaValidatorFactory implements AutoCloseable { final Predicate pattern = regexFactory.get().apply(obj.getKey()); final JsonObject currentSchema = obj.getValue().asJsonObject(); // no cache cause otherwise it could be in properties - return (Function>) validable -> { + return (Function>) root -> { + JsonValue validable = Optional.ofNullable(valueProvider) + .map(p -> p.apply(root)) + .orElse(root); + if (validable.getValueType() != JsonValue.ValueType.OBJECT) { return Stream.empty(); } @@ -206,7 +210,7 @@ public class JsonSchemaValidatorFactory implements AutoCloseable { .flatMap(e -> { final String[] subPath = Stream.concat(Stream.of(path), Stream.of(e.getKey())).toArray(String[]::new); final Function provider = new ChainedValueAccessor(valueProvider, e.getKey()); - return buildValidator(subPath, currentSchema, provider).apply(validable); + return buildValidator(subPath, currentSchema, provider).apply(root); }); }; }) diff --git a/johnzon-jsonschema/src/test/java/org/apache/johnzon/jsonschema/JsonSchemaValidatorTest.java b/johnzon-jsonschema/src/test/java/org/apache/johnzon/jsonschema/JsonSchemaValidatorTest.java index 3331ed3..6e70228 100644 --- a/johnzon-jsonschema/src/test/java/org/apache/johnzon/jsonschema/JsonSchemaValidatorTest.java +++ b/johnzon-jsonschema/src/test/java/org/apache/johnzon/jsonschema/JsonSchemaValidatorTest.java @@ -115,15 +115,15 @@ public class JsonSchemaValidatorTest { @Test public void typeArray() { final JsonSchemaValidator validator = factory.newInstance(jsonFactory.createObjectBuilder() - .add("type", "object") - .add("properties", jsonFactory.createObjectBuilder() - .add("name", jsonFactory.createObjectBuilder() - .add("type", jsonFactory.createArrayBuilder() - .add("string") - .add("number")) - .build()) - .build()) - .build()); + .add("type", "object") + .add("properties", jsonFactory.createObjectBuilder() + .add("name", jsonFactory.createObjectBuilder() + .add("type", jsonFactory.createArrayBuilder() + .add("string") + .add("number")) + .build()) + .build()) + .build()); { final ValidationResult success = validator.apply(jsonFactory.createObjectBuilder().add("name", "ok").build()); @@ -357,7 +357,7 @@ public class JsonSchemaValidatorTest { validator.close(); } - + @Test public void integerType() { final JsonSchemaValidator validator = factory.newInstance(jsonFactory.createObjectBuilder() @@ -374,10 +374,10 @@ public class JsonSchemaValidatorTest { assertTrue(validator.apply(jsonFactory.createObjectBuilder().add("age", -10).build()).isSuccess()); assertTrue(validator.apply(jsonFactory.createObjectBuilder().add("age", BigInteger.valueOf(50)).build()).isSuccess()); // check no decimal numbers allowed - assertFalse(validator.apply(jsonFactory.createObjectBuilder() .add("age", 30.3f) .build()).isSuccess()); - assertFalse(validator.apply(jsonFactory.createObjectBuilder() .add("age", -7.4d) .build()).isSuccess()); - assertFalse(validator.apply(jsonFactory.createObjectBuilder() .add("age", BigDecimal.valueOf(50.35613d)).build()).isSuccess()); - + assertFalse(validator.apply(jsonFactory.createObjectBuilder().add("age", 30.3f).build()).isSuccess()); + assertFalse(validator.apply(jsonFactory.createObjectBuilder().add("age", -7.4d).build()).isSuccess()); + assertFalse(validator.apply(jsonFactory.createObjectBuilder().add("age", BigDecimal.valueOf(50.35613d)).build()).isSuccess()); + validator.close(); } @@ -467,7 +467,7 @@ public class JsonSchemaValidatorTest { .add("names", jsonFactory.createObjectBuilder() .add("type", "array") .add("items", jsonFactory.createArrayBuilder().add(jsonFactory.createObjectBuilder() - .add("type", "string")) + .add("type", "string")) .build()).build()) .build()) .build()); @@ -651,7 +651,7 @@ public class JsonSchemaValidatorTest { .add("type", "object") .add("patternProperties", jsonFactory.createObjectBuilder() .add("[0-9]+", jsonFactory.createObjectBuilder().add("type", "number")) - .build()) + .build()) .build()); assertTrue(validator.apply(jsonFactory.createObjectBuilder().build()).isSuccess()); @@ -665,6 +665,35 @@ public class JsonSchemaValidatorTest { validator.close(); } + @Test + public void patternPropertiesNested() { + try (JsonSchemaValidator validator = factory.newInstance(jsonFactory.createObjectBuilder() + .add("type", "object") + .add("properties", jsonFactory.createObjectBuilder() + .add("nested", jsonFactory.createObjectBuilder() + .add("type", "object") + .add("patternProperties", jsonFactory.createObjectBuilder() + .add("[0-9]+", jsonFactory.createObjectBuilder().add("type", "number")) + .build())) + ) + .build())) { + + assertTrue(validator.apply(jsonFactory.createObjectBuilder().build()).isSuccess()); + assertTrue(validator.apply(jsonFactory.createObjectBuilder() + .add("nested", jsonFactory.createObjectBuilder() + .add("1", 1) + .build()) + .build()) + .isSuccess()); + assertFalse(validator.apply(jsonFactory.createObjectBuilder() + .add("nested", jsonFactory.createObjectBuilder() + .add("1", "test") + .build()) + .build()) + .isSuccess()); + } + } + @Test public void additionalProperties() { final JsonSchemaValidator validator = factory.newInstance(jsonFactory.createObjectBuilder() @@ -682,6 +711,6 @@ public class JsonSchemaValidatorTest { validator.close(); } - + } -- 2.32.0