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")

Reply via email to