fixes #456 OneOf only validate the first sub schema
diff --git a/src/main/java/com/networknt/schema/OneOfValidator.java b/src/main/java/com/networknt/schema/OneOfValidator.java
index 283875e..5e48902 100644
--- a/src/main/java/com/networknt/schema/OneOfValidator.java
+++ b/src/main/java/com/networknt/schema/OneOfValidator.java
@@ -17,27 +17,19 @@
 package com.networknt.schema;

 

 import com.fasterxml.jackson.databind.JsonNode;

-import com.fasterxml.jackson.databind.node.ArrayNode;

-import com.fasterxml.jackson.databind.node.NullNode;

-import com.fasterxml.jackson.databind.node.ObjectNode;

-import com.networknt.schema.utils.JsonNodeUtil;

 import org.slf4j.Logger;

 import org.slf4j.LoggerFactory;

 

 import java.util.*;

 

 public class OneOfValidator extends BaseJsonValidator implements JsonValidator {

-

     private static final Logger logger = LoggerFactory.getLogger(OneOfValidator.class);

 

     private final List<ShortcutValidator> schemas = new ArrayList<ShortcutValidator>();

 

-    private final ValidationContext validationContext;

-

     private static class ShortcutValidator {

         private final JsonSchema schema;

         private final Map<String, String> constants;

-        private final ValidationContext validationContext;

 

         ShortcutValidator(JsonNode schemaNode, JsonSchema parentSchema,

                           ValidationContext validationContext, JsonSchema schema) {

@@ -45,7 +37,6 @@
             JsonSchema resolvedRefSchema = refNode != null && refNode.isTextual() ? RefValidator.getRefSchema(parentSchema, validationContext, refNode.textValue()).getSchema() : null;

             this.constants = extractConstants(schemaNode, resolvedRefSchema);

             this.schema = schema;

-            this.validationContext = validationContext;

         }

 

         private Map<String, String> extractConstants(JsonNode schemaNode, JsonSchema resolvedRefSchema) {

@@ -130,7 +121,6 @@
             JsonSchema childSchema = new JsonSchema(validationContext, getValidatorType().getValue(), parentSchema.getCurrentUri(), childNode, parentSchema);

             schemas.add(new ShortcutValidator(childNode, parentSchema, validationContext, childSchema));

         }

-        this.validationContext = validationContext;

         parseErrorCode(getValidatorType().getErrorCodeKey());

     }

 

@@ -163,49 +153,33 @@
                 continue;

             }*/

 

-            //Check to see if it is already validated.

-            if(!childErrors.isEmpty() && JsonNodeUtil.matchOneOfTypeNode(schemaNode,TypeFactory.getValueNodeType(node, this.validationContext.getConfig()))){

-                continue;

-            }

-

             // get the current validator

             JsonSchema schema = validator.schema;

-

-            //Skip the validation when the current node is oneOf type and it is not equal to schemaType.

-            if (JsonNodeUtil.matchOneOfTypeNode(schemaNode, TypeFactory.getValueNodeType(node, this.validationContext.getConfig())) &&

-                    !JsonNodeUtil.equalsToSchemaType(node, schema, this.validationContext.getConfig()) && !(JsonType.UNKNOWN.equals(JsonNodeUtil.getSchemaJsonType(schema)))) {

-                continue;

-            }

-

             if (!state.isWalkEnabled()) {

                 schemaErrors = schema.validate(node, rootNode, at);

             } else {

                 schemaErrors = schema.walk(node, rootNode, at, state.isValidationEnabled());

             }

 

-

             // check if any validation errors have occurred

             if (schemaErrors.isEmpty()) {

                 // check whether there are no errors HOWEVER we have validated the exact validator

                 if (!state.hasMatchedNode())

                     continue;

-                else

-                    numberOfValidSchema++;

+

+                numberOfValidSchema++;

             }

             childErrors.addAll(schemaErrors);

         }

+

+

         // ensure there is always an "OneOf" error reported if number of valid schemas is not equal to 1.

-        if (numberOfValidSchema > 1) {

-            // check if the parent schema declares the fields as nullable

-            if (!JsonType.NULL.equals(TypeFactory.getValueNodeType(node, this.validationContext.getConfig())) ||

-                    !JsonNodeUtil.isNodeNullable(parentSchema.getSchemaNode(), this.validationContext.getConfig()) &&

-                            !JsonNodeUtil.isChildNodeNullable((ArrayNode) schemaNode, this.validationContext.getConfig())) {

-                final ValidationMessage message = getMultiSchemasValidErrorMsg(at);

-                if (failFast) {

-                    throw new JsonSchemaException(message);

-                }

-                errors.add(message);

+        if(numberOfValidSchema > 1){

+            final ValidationMessage message = getMultiSchemasValidErrorMsg(at);

+            if( failFast ) {

+                throw new JsonSchemaException(message);

             }

+            errors.add(message);

         }

         // ensure there is always an "OneOf" error reported if number of valid schemas is not equal to 1.

         else if (numberOfValidSchema < 1) {

@@ -262,7 +236,7 @@
         }

 

         return ValidationMessage.of(getValidatorType().getValue(), ValidatorTypeCode.ONE_OF ,

-                                    at, String.format("but more than one schemas {%s} are valid ",msg));

+                at, String.format("but more than one schemas {%s} are valid ",msg));

     }

 

     @Override

diff --git a/src/test/java/com/networknt/schema/Issue456Test.java b/src/test/java/com/networknt/schema/Issue456Test.java
new file mode 100644
index 0000000..c96c389
--- /dev/null
+++ b/src/test/java/com/networknt/schema/Issue456Test.java
@@ -0,0 +1,48 @@
+package com.networknt.schema;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.io.InputStream;
+import java.util.Set;
+
+public class Issue456Test {
+
+    protected JsonSchema getJsonSchemaFromStreamContentV7(InputStream schemaContent) {
+        JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7);
+        return factory.getSchema(schemaContent);
+    }
+
+    protected JsonNode getJsonNodeFromStreamContent(InputStream content) throws Exception {
+        ObjectMapper mapper = new ObjectMapper();
+        return mapper.readTree(content);
+    }
+
+    @Test
+    public void shouldWorkT2() throws Exception {
+        String schemaPath = "/schema/issue456-v7.json";
+        String dataPath = "/data/issue456-T2.json";
+        String dataT3Path = "/data/issue456-T3.json";
+        InputStream schemaInputStream = getClass().getResourceAsStream(schemaPath);
+        JsonSchema schema = getJsonSchemaFromStreamContentV7(schemaInputStream);
+        InputStream dataInputStream = getClass().getResourceAsStream(dataPath);
+        JsonNode node = getJsonNodeFromStreamContent(dataInputStream);
+        Set<ValidationMessage> errors = schema.validate(node);
+        Assertions.assertEquals(0, errors.size());
+    }
+
+    @Test
+    public void shouldWorkT3() throws Exception {
+        String schemaPath = "/schema/issue456-v7.json";
+        String dataPath = "/data/issue456-T3.json";
+        InputStream schemaInputStream = getClass().getResourceAsStream(schemaPath);
+        JsonSchema schema = getJsonSchemaFromStreamContentV7(schemaInputStream);
+        InputStream dataInputStream = getClass().getResourceAsStream(dataPath);
+        JsonNode node = getJsonNodeFromStreamContent(dataInputStream);
+        Set<ValidationMessage> errors = schema.validate(node);
+        Assertions.assertEquals(0, errors.size());
+    }
+
+}
diff --git a/src/test/resources/data/issue456-T2.json b/src/test/resources/data/issue456-T2.json
new file mode 100644
index 0000000..b39deea
--- /dev/null
+++ b/src/test/resources/data/issue456-T2.json
@@ -0,0 +1,7 @@
+{
+  "id": "abc",
+  "details": {
+    "__typename": "T2",
+    "name": "Bob"
+  }
+}
diff --git a/src/test/resources/data/issue456-T3.json b/src/test/resources/data/issue456-T3.json
new file mode 100644
index 0000000..a4688b7
--- /dev/null
+++ b/src/test/resources/data/issue456-T3.json
@@ -0,0 +1,7 @@
+{
+  "id": "def",
+  "details": {
+    "__typename": "T3",
+    "description": "Something"
+  }
+}
diff --git a/src/test/resources/schema/issue456-v7.json b/src/test/resources/schema/issue456-v7.json
new file mode 100644
index 0000000..46fbe08
--- /dev/null
+++ b/src/test/resources/schema/issue456-v7.json
@@ -0,0 +1,44 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "$id": "https://example.com/issue-456.json",
+  "title": "OneOf validates first child only",
+  "description": "Test description",
+  "type": "object",
+  "properties": {
+    "id": "string",
+    "details": {
+      "oneOf": [
+        {
+          "type": "object",
+          "properties": {
+            "name": {
+              "type": "string"
+            },
+            "__typename": {
+              "const": "T2"
+            }
+          },
+          "required": [
+            "name",
+            "__typename"
+          ]
+        },
+        {
+          "type": "object",
+          "properties": {
+            "description": {
+              "type": "string"
+            },
+            "__typename": {
+              "const": "T3"
+            }
+          },
+          "required": [
+            "description",
+            "__typename"
+          ]
+        }
+      ]
+    }
+  }
+}