Repository: johnzon Updated Branches: refs/heads/master 1aea0bbf4 -> 297654206
JOHNZON-191 support type validation when value is an array Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/29765420 Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/29765420 Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/29765420 Branch: refs/heads/master Commit: 297654206d56de2dd7b2de11e9de1f1eb7a81d41 Parents: 1aea0bb Author: Romain Manni-Bucau <[email protected]> Authored: Tue Oct 9 07:51:24 2018 +0200 Committer: Romain Manni-Bucau <[email protected]> Committed: Tue Oct 9 07:51:24 2018 +0200 ---------------------------------------------------------------------- .../jsonschema/spi/builtin/TypeValidation.java | 26 ++++++++++---- .../jsonschema/JsonSchemaValidatorTest.java | 37 ++++++++++++++++++++ 2 files changed, 56 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/johnzon/blob/29765420/johnzon-jsonschema/src/main/java/org/apache/johnzon/jsonschema/spi/builtin/TypeValidation.java ---------------------------------------------------------------------- diff --git a/johnzon-jsonschema/src/main/java/org/apache/johnzon/jsonschema/spi/builtin/TypeValidation.java b/johnzon-jsonschema/src/main/java/org/apache/johnzon/jsonschema/spi/builtin/TypeValidation.java index 182c6a1..18a5697 100644 --- a/johnzon-jsonschema/src/main/java/org/apache/johnzon/jsonschema/spi/builtin/TypeValidation.java +++ b/johnzon-jsonschema/src/main/java/org/apache/johnzon/jsonschema/spi/builtin/TypeValidation.java @@ -26,6 +26,7 @@ import java.util.Optional; import java.util.function.Function; import java.util.stream.Stream; +import javax.json.JsonArray; import javax.json.JsonString; import javax.json.JsonValue; @@ -37,21 +38,31 @@ public class TypeValidation implements ValidationExtension { @Override public Optional<Function<JsonValue, Stream<ValidationResult.ValidationError>>> create(final ValidationContext model) { final JsonValue value = model.getSchema().get("type"); - if (!JsonString.class.isInstance(value)) { // todo: other types? - return Optional.empty(); + if (JsonString.class.isInstance(value)) { + return Optional.of(new Impl(model.toPointer(), model.getValueProvider(), mapType(JsonString.class.cast(value)).toArray(JsonValue.ValueType[]::new))); } + if (JsonArray.class.isInstance(value)) { + return Optional.of(new Impl(model.toPointer(), model.getValueProvider(), + value.asJsonArray().stream().flatMap(this::mapType).toArray(JsonValue.ValueType[]::new))); + } + throw new IllegalArgumentException(value + " is neither an array or string nor a string"); + } + + private Stream<? extends JsonValue.ValueType> mapType(final JsonValue value) { switch (JsonString.class.cast(value).getString()) { + case "null": + return Stream.of(JsonValue.ValueType.NULL); case "string": - return Optional.of(new Impl(model.toPointer(), model.getValueProvider(), JsonValue.ValueType.STRING)); + return Stream.of(JsonValue.ValueType.STRING); case "number": - return Optional.of(new Impl(model.toPointer(), model.getValueProvider(), JsonValue.ValueType.NUMBER)); + return Stream.of(JsonValue.ValueType.NUMBER); case "array": - return Optional.of(new Impl(model.toPointer(), model.getValueProvider(), JsonValue.ValueType.ARRAY)); + return Stream.of(JsonValue.ValueType.ARRAY); case "boolean": - return Optional.of(new Impl(model.toPointer(), model.getValueProvider(), JsonValue.ValueType.FALSE, JsonValue.ValueType.TRUE)); + return Stream.of(JsonValue.ValueType.FALSE, JsonValue.ValueType.TRUE); case "object": default: - return Optional.of(new Impl(model.toPointer(), model.getValueProvider(), JsonValue.ValueType.OBJECT)); + return Stream.of(JsonValue.ValueType.OBJECT); } } @@ -60,6 +71,7 @@ public class TypeValidation implements ValidationExtension { private Impl(final String pointer, final Function<JsonValue, JsonValue> extractor, final JsonValue.ValueType... types) { super(pointer, extractor, types[0] /*ignored anyway*/); + // note: should we always add NULL? if not it leads to a very weird behavior for partial objects and required fixes it this.types = Stream.concat(Stream.of(types), Stream.of(JsonValue.ValueType.NULL)) .distinct() .sorted(comparing(JsonValue.ValueType::name)) http://git-wip-us.apache.org/repos/asf/johnzon/blob/29765420/johnzon-jsonschema/src/test/java/org/apache/johnzon/jsonschema/JsonSchemaValidatorTest.java ---------------------------------------------------------------------- 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 ed41c1e..d3247ff 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 @@ -111,6 +111,43 @@ 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()); + + { + final ValidationResult success = validator.apply(jsonFactory.createObjectBuilder().add("name", "ok").build()); + assertTrue(success.getErrors().toString(), success.isSuccess()); + } + { + final ValidationResult success = validator.apply(jsonFactory.createObjectBuilder().addNull("name").build()); + assertTrue(success.getErrors().toString(), success.isSuccess()); + } + { + final ValidationResult success = validator.apply(jsonFactory.createObjectBuilder().add("name", 5).build()); + assertTrue(success.getErrors().toString(), success.isSuccess()); + } + + final ValidationResult failure = validator.apply(jsonFactory.createObjectBuilder().add("name", true).build()); + assertFalse(failure.isSuccess()); + final Collection<ValidationResult.ValidationError> errors = failure.getErrors(); + assertEquals(1, errors.size()); + final ValidationResult.ValidationError error = errors.iterator().next(); + assertEquals("/name", error.getField()); + assertEquals("Expected [NULL, NUMBER, STRING] but got TRUE", error.getMessage()); + + validator.close(); + } + + @Test public void nestedType() { final JsonSchemaValidator validator = factory.newInstance(jsonFactory.createObjectBuilder() .add("type", "object")
