boundsViolated(ValidatorTypeCode validatorTypeCod
} else if (ValidatorTypeCode.MAX_CONTAINS.equals(validatorTypeCode)) {
messageKey = CONTAINS_MAX;
}
- return Collections
- .singleton(message().instanceNode(instanceNode).instanceLocation(instanceLocation).messageKey(messageKey)
+ executionContext.addError(message().instanceNode(instanceNode).instanceLocation(instanceLocation).messageKey(messageKey)
.locale(locale).failFast(failFast).arguments(String.valueOf(bounds), this.schema.getSchemaNode().toString())
.code(validatorTypeCode.getErrorCode()).type(validatorTypeCode.getValue()).build());
}
diff --git a/src/main/java/com/networknt/schema/ContentEncodingValidator.java b/src/main/java/com/networknt/schema/ContentEncodingValidator.java
index 5c9e29608..66335052d 100644
--- a/src/main/java/com/networknt/schema/ContentEncodingValidator.java
+++ b/src/main/java/com/networknt/schema/ContentEncodingValidator.java
@@ -22,8 +22,7 @@
import org.slf4j.LoggerFactory;
import java.util.Base64;
-import java.util.Collections;
-import java.util.Set;
+
/**
* {@link JsonValidator} for contentEncoding.
*
@@ -64,14 +63,14 @@ private boolean matches(String value) {
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
// Ignore non-strings
JsonType nodeType = TypeFactory.getValueNodeType(node, this.validationContext.getConfig());
if (nodeType != JsonType.STRING) {
- return Collections.emptySet();
+ return;
}
if (collectAnnotations(executionContext)) {
@@ -80,11 +79,10 @@ public Set validate(ExecutionContext executionContext, JsonNo
}
if (!matches(node.asText())) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(this.contentEncoding)
.build());
}
- return Collections.emptySet();
}
}
diff --git a/src/main/java/com/networknt/schema/ContentMediaTypeValidator.java b/src/main/java/com/networknt/schema/ContentMediaTypeValidator.java
index 28e435b68..465f0d5f3 100644
--- a/src/main/java/com/networknt/schema/ContentMediaTypeValidator.java
+++ b/src/main/java/com/networknt/schema/ContentMediaTypeValidator.java
@@ -18,8 +18,6 @@
import java.nio.charset.StandardCharsets;
import java.util.Base64;
-import java.util.Collections;
-import java.util.Set;
import java.util.regex.Pattern;
import org.slf4j.Logger;
@@ -88,14 +86,14 @@ else if (!PATTERN.matcher(this.contentMediaType).matches()) {
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
// Ignore non-strings
JsonType nodeType = TypeFactory.getValueNodeType(node, this.validationContext.getConfig());
if (nodeType != JsonType.STRING) {
- return Collections.emptySet();
+ return;
}
if (collectAnnotations(executionContext)) {
@@ -104,11 +102,10 @@ public Set validate(ExecutionContext executionContext, JsonNo
}
if (!matches(node.asText())) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(this.contentMediaType)
.build());
}
- return Collections.emptySet();
}
}
diff --git a/src/main/java/com/networknt/schema/DependenciesValidator.java b/src/main/java/com/networknt/schema/DependenciesValidator.java
index 882d66592..876f431bc 100644
--- a/src/main/java/com/networknt/schema/DependenciesValidator.java
+++ b/src/main/java/com/networknt/schema/DependenciesValidator.java
@@ -62,21 +62,16 @@ public DependenciesValidator(SchemaLocation schemaLocation, JsonNodePath evaluat
}
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
- Set errors = null;
-
for (Iterator it = node.fieldNames(); it.hasNext(); ) {
String pname = it.next();
List deps = propertyDeps.get(pname);
if (deps != null && !deps.isEmpty()) {
for (String field : deps) {
if (node.get(field) == null) {
- if (errors == null) {
- errors = new LinkedHashSet<>();
- }
- errors.add(message().instanceNode(node).property(pname).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).property(pname).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast())
.arguments(propertyDeps.toString()).build());
@@ -85,16 +80,9 @@ public Set validate(ExecutionContext executionContext, JsonNo
}
JsonSchema schema = schemaDeps.get(pname);
if (schema != null) {
- Set schemaDepsErrors = schema.validate(executionContext, node, rootNode, instanceLocation);
- if (!schemaDepsErrors.isEmpty()) {
- if (errors == null) {
- errors = new LinkedHashSet<>();
- }
- errors.addAll(schemaDepsErrors);
- }
+ schema.validate(executionContext, node, rootNode, instanceLocation);
}
}
- return errors == null || errors.isEmpty() ? Collections.emptySet() : Collections.unmodifiableSet(errors);
}
@Override
diff --git a/src/main/java/com/networknt/schema/DependentRequired.java b/src/main/java/com/networknt/schema/DependentRequired.java
index 14a7bc21b..da9294af7 100644
--- a/src/main/java/com/networknt/schema/DependentRequired.java
+++ b/src/main/java/com/networknt/schema/DependentRequired.java
@@ -46,18 +46,16 @@ public DependentRequired(SchemaLocation schemaLocation, JsonNodePath evaluationP
}
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
- Set errors = new LinkedHashSet<>();
-
for (Iterator it = node.fieldNames(); it.hasNext(); ) {
String pname = it.next();
List dependencies = propertyDependencies.get(pname);
if (dependencies != null && !dependencies.isEmpty()) {
for (String field : dependencies) {
if (node.get(field) == null) {
- errors.add(message().instanceNode(node).property(pname).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).property(pname).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(field, pname)
.build());
@@ -65,8 +63,6 @@ public Set validate(ExecutionContext executionContext, JsonNo
}
}
}
-
- return Collections.unmodifiableSet(errors);
}
}
diff --git a/src/main/java/com/networknt/schema/DependentSchemas.java b/src/main/java/com/networknt/schema/DependentSchemas.java
index 589a8e5c3..b9bfa47b4 100644
--- a/src/main/java/com/networknt/schema/DependentSchemas.java
+++ b/src/main/java/com/networknt/schema/DependentSchemas.java
@@ -44,32 +44,26 @@ public DependentSchemas(SchemaLocation schemaLocation, JsonNodePath evaluationPa
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation) {
- return validate(executionContext, node, rootNode, instanceLocation, false);
+ validate(executionContext, node, rootNode, instanceLocation, false);
}
- protected Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ protected void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation, boolean walk) {
debug(logger, executionContext, node, rootNode, instanceLocation);
- Set errors = null;
for (Iterator it = node.fieldNames(); it.hasNext(); ) {
String pname = it.next();
JsonSchema schema = this.schemaDependencies.get(pname);
if (schema != null) {
- Set schemaDependenciesErrors = !walk
- ? schema.validate(executionContext, node, rootNode, instanceLocation)
- : schema.walk(executionContext, node, rootNode, instanceLocation, true);
- if (!schemaDependenciesErrors.isEmpty()) {
- if (errors == null) {
- errors = new LinkedHashSet<>();
- }
- errors.addAll(schemaDependenciesErrors);
+ if(!walk) {
+ schema.validate(executionContext, node, rootNode, instanceLocation);
+ } else {
+ schema.walk(executionContext, node, rootNode, instanceLocation, true);
}
}
}
- return errors == null || errors.isEmpty() ? Collections.emptySet() : Collections.unmodifiableSet(errors);
}
@Override
@@ -78,14 +72,14 @@ public void preloadJsonSchema() {
}
@Override
- public Set walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
+ public void walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
if (shouldValidateSchema) {
- return validate(executionContext, node, rootNode, instanceLocation, true);
+ validate(executionContext, node, rootNode, instanceLocation, true);
+ return;
}
for (JsonSchema schema : this.schemaDependencies.values()) {
schema.walk(executionContext, node, rootNode, instanceLocation, false);
}
- return Collections.emptySet();
}
}
diff --git a/src/main/java/com/networknt/schema/DiscriminatorValidator.java b/src/main/java/com/networknt/schema/DiscriminatorValidator.java
index 8cc08df18..c87ef6f7a 100644
--- a/src/main/java/com/networknt/schema/DiscriminatorValidator.java
+++ b/src/main/java/com/networknt/schema/DiscriminatorValidator.java
@@ -21,7 +21,6 @@
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.Set;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -59,9 +58,9 @@ public DiscriminatorValidator(SchemaLocation schemaLocation, JsonNodePath evalua
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation) {
- return Collections.emptySet();
+ // Do nothing
}
/**
diff --git a/src/main/java/com/networknt/schema/DynamicRefValidator.java b/src/main/java/com/networknt/schema/DynamicRefValidator.java
index 10ce6017b..1cf2d0632 100644
--- a/src/main/java/com/networknt/schema/DynamicRefValidator.java
+++ b/src/main/java/com/networknt/schema/DynamicRefValidator.java
@@ -20,8 +20,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Collections;
-import java.util.Set;
import java.util.function.Supplier;
/**
@@ -92,7 +90,7 @@ private static String resolve(JsonSchema parentSchema, String refValue) {
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
JsonSchema refSchema = this.schema.getSchema();
if (refSchema == null) {
@@ -102,11 +100,11 @@ public Set validate(ExecutionContext executionContext, JsonNo
.arguments(schemaNode.asText()).build();
throw new InvalidSchemaRefException(validationMessage);
}
- return refSchema.validate(executionContext, node, rootNode, instanceLocation);
+ refSchema.validate(executionContext, node, rootNode, instanceLocation);
}
@Override
- public Set walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
+ public void walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
debug(logger, executionContext, node, rootNode, instanceLocation);
// This is important because if we use same JsonSchemaFactory for creating multiple JSONSchema instances,
// these schemas will be cached along with config. We have to replace the config for cached $ref references
@@ -132,10 +130,10 @@ public Set walk(ExecutionContext executionContext, JsonNode n
}
}
if (circularDependency) {
- return Collections.emptySet();
+ return;
}
}
- return refSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema);
+ refSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema);
}
public JsonSchemaRef getSchemaRef() {
diff --git a/src/main/java/com/networknt/schema/EnumValidator.java b/src/main/java/com/networknt/schema/EnumValidator.java
index 44983f26c..e474bcd4d 100644
--- a/src/main/java/com/networknt/schema/EnumValidator.java
+++ b/src/main/java/com/networknt/schema/EnumValidator.java
@@ -89,7 +89,7 @@ public EnumValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath,
}
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
if (node.isNumber()) {
@@ -98,12 +98,10 @@ public Set validate(ExecutionContext executionContext, JsonNo
node = processArrayNode((ArrayNode) node);
}
if (!nodes.contains(node) && !( this.validationContext.getConfig().isTypeLoose() && isTypeLooseContainsInEnum(node))) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(error).build());
}
-
- return Collections.emptySet();
}
/**
diff --git a/src/main/java/com/networknt/schema/ExclusiveMaximumValidator.java b/src/main/java/com/networknt/schema/ExclusiveMaximumValidator.java
index 0460481a1..c461a01c8 100644
--- a/src/main/java/com/networknt/schema/ExclusiveMaximumValidator.java
+++ b/src/main/java/com/networknt/schema/ExclusiveMaximumValidator.java
@@ -24,8 +24,6 @@
import java.math.BigDecimal;
import java.math.BigInteger;
-import java.util.Collections;
-import java.util.Set;
/**
* {@link JsonValidator} for exclusiveMaximum.
@@ -97,20 +95,19 @@ public String thresholdValue() {
}
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
if (!JsonNodeUtil.isNumber(node, validationContext.getConfig())) {
// maximum only applies to numbers
- return Collections.emptySet();
+ return;
}
if (typedMaximum.crossesThreshold(node)) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast())
.arguments(typedMaximum.thresholdValue()).build());
}
- return Collections.emptySet();
}
}
diff --git a/src/main/java/com/networknt/schema/ExclusiveMinimumValidator.java b/src/main/java/com/networknt/schema/ExclusiveMinimumValidator.java
index aea9c36d8..c00281ae1 100644
--- a/src/main/java/com/networknt/schema/ExclusiveMinimumValidator.java
+++ b/src/main/java/com/networknt/schema/ExclusiveMinimumValidator.java
@@ -24,8 +24,6 @@
import java.math.BigDecimal;
import java.math.BigInteger;
-import java.util.Collections;
-import java.util.Set;
/**
* {@link JsonValidator} for exclusiveMinimum.
@@ -104,21 +102,20 @@ public String thresholdValue() {
}
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
if (!JsonNodeUtil.isNumber(node, this.validationContext.getConfig())) {
// minimum only applies to numbers
- return Collections.emptySet();
+ return;
}
if (typedMinimum.crossesThreshold(node)) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast())
.arguments(typedMinimum.thresholdValue()).build());
}
- return Collections.emptySet();
}
}
diff --git a/src/main/java/com/networknt/schema/ExecutionContext.java b/src/main/java/com/networknt/schema/ExecutionContext.java
index f2ca8e198..57e6b7ac8 100644
--- a/src/main/java/com/networknt/schema/ExecutionContext.java
+++ b/src/main/java/com/networknt/schema/ExecutionContext.java
@@ -19,6 +19,9 @@
import com.networknt.schema.annotation.JsonNodeAnnotations;
import com.networknt.schema.result.JsonNodeResults;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.Stack;
/**
@@ -30,6 +33,7 @@ public class ExecutionContext {
private Stack discriminatorContexts = null;
private JsonNodeAnnotations annotations = null;
private JsonNodeResults results = null;
+ private List errors = new ArrayList<>();
/**
* This is used during the execution to determine if the validator should fail fast.
@@ -173,4 +177,20 @@ public void enterDiscriminatorContext(final DiscriminatorContext ctx, @SuppressW
public void leaveDiscriminatorContextImmediately(@SuppressWarnings("unused") JsonNodePath instanceLocation) {
this.discriminatorContexts.pop();
}
+
+ public List getErrors() {
+ return this.errors;
+ }
+
+ public void addError(ValidationMessage error) {
+ if (this.isFailFast()) {
+ this.errors = Collections.singletonList(error);
+ throw new FailFastAssertionException(error);
+ }
+ this.errors.add(error);
+ }
+
+ public void setErrors(List errors) {
+ this.errors = errors;
+ }
}
diff --git a/src/main/java/com/networknt/schema/FailFastAssertionException.java b/src/main/java/com/networknt/schema/FailFastAssertionException.java
index 6ea3cf455..84f8f6e84 100644
--- a/src/main/java/com/networknt/schema/FailFastAssertionException.java
+++ b/src/main/java/com/networknt/schema/FailFastAssertionException.java
@@ -17,8 +17,8 @@
package com.networknt.schema;
import java.util.Collections;
+import java.util.List;
import java.util.Objects;
-import java.util.Set;
/**
* Thrown when an assertion happens and the evaluation can fail fast.
@@ -32,15 +32,15 @@
public class FailFastAssertionException extends RuntimeException {
private static final long serialVersionUID = 1L;
- private final ValidationMessage validationMessage;
+ private final ValidationMessage error;
/**
* Constructor.
*
- * @param validationMessage the validation message
+ * @param error the validation message
*/
- public FailFastAssertionException(ValidationMessage validationMessage) {
- this.validationMessage = Objects.requireNonNull(validationMessage);
+ public FailFastAssertionException(ValidationMessage error) {
+ this.error = Objects.requireNonNull(error);
}
/**
@@ -48,8 +48,8 @@ public FailFastAssertionException(ValidationMessage validationMessage) {
*
* @return the validation message
*/
- public ValidationMessage getValidationMessage() {
- return this.validationMessage;
+ public ValidationMessage getError() {
+ return this.error;
}
/**
@@ -57,13 +57,13 @@ public ValidationMessage getValidationMessage() {
*
* @return the validation message
*/
- public Set getValidationMessages() {
- return Collections.singleton(this.validationMessage);
+ public List getErrors() {
+ return Collections.singletonList(this.error);
}
@Override
public String getMessage() {
- return this.validationMessage != null ? this.validationMessage.getMessage() : super.getMessage();
+ return this.error != null ? this.error.getMessage() : super.getMessage();
}
@Override
diff --git a/src/main/java/com/networknt/schema/FalseValidator.java b/src/main/java/com/networknt/schema/FalseValidator.java
index 8032e3ecc..a33a2b745 100644
--- a/src/main/java/com/networknt/schema/FalseValidator.java
+++ b/src/main/java/com/networknt/schema/FalseValidator.java
@@ -19,9 +19,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Collections;
-import java.util.Set;
-
/**
* {@link JsonValidator} for false.
*/
@@ -35,10 +32,10 @@ public FalseValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath
this.reason = this.evaluationPath.getParent().getName(-1);
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
// For the false validator, it is always not valid
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(reason).build());
}
diff --git a/src/main/java/com/networknt/schema/Format.java b/src/main/java/com/networknt/schema/Format.java
index 6f79b1021..f1632c0f4 100644
--- a/src/main/java/com/networknt/schema/Format.java
+++ b/src/main/java/com/networknt/schema/Format.java
@@ -16,8 +16,6 @@
package com.networknt.schema;
-import java.util.Collections;
-import java.util.Set;
import java.util.function.Supplier;
import com.fasterxml.jackson.databind.JsonNode;
@@ -139,20 +137,17 @@ default boolean matches(ExecutionContext executionContext, ValidationContext val
* @param assertionsEnabled if assertions are enabled
* @param message the message builder
* @param formatValidator the format validator
- * @return the messages
*/
- default Set validate(ExecutionContext executionContext, ValidationContext validationContext,
+ default void validate(ExecutionContext executionContext, ValidationContext validationContext,
JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean assertionsEnabled,
Supplier message,
FormatValidator formatValidator) {
if (assertionsEnabled) {
if (!matches(executionContext, validationContext, node, rootNode, instanceLocation, assertionsEnabled,
formatValidator)) {
- return Collections
- .singleton(message.get()
+ executionContext.addError(message.get()
.arguments(this.getName(), this.getErrorMessageDescription(), node.asText()).build());
}
}
- return Collections.emptySet();
}
}
diff --git a/src/main/java/com/networknt/schema/FormatValidator.java b/src/main/java/com/networknt/schema/FormatValidator.java
index 7177f3f30..4725786f0 100644
--- a/src/main/java/com/networknt/schema/FormatValidator.java
+++ b/src/main/java/com/networknt/schema/FormatValidator.java
@@ -22,8 +22,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Collections;
-import java.util.Set;
import java.util.regex.PatternSyntaxException;
/**
@@ -58,7 +56,7 @@ protected Object getAnnotationValue() {
return this.schemaNode.isTextual() ? schemaNode.textValue() : null;
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
/*
* Annotations must be collected even if the format is unknown according to the specification.
@@ -74,7 +72,7 @@ public Set validate(ExecutionContext executionContext, JsonNo
boolean assertionsEnabled = isAssertionsEnabled(executionContext);
if (this.format != null) {
try {
- return format.validate(executionContext, validationContext, node, rootNode, instanceLocation,
+ format.validate(executionContext, validationContext, node, rootNode, instanceLocation,
assertionsEnabled,
() -> this.message().instanceNode(node).instanceLocation(instanceLocation)
.messageKey(format.getMessageKey())
@@ -85,10 +83,9 @@ public Set validate(ExecutionContext executionContext, JsonNo
// String is considered valid if pattern is invalid
logger.error("Failed to apply pattern on {}: Invalid RE syntax [{}]", instanceLocation,
format.getName(), pse);
- return Collections.emptySet();
}
} else {
- return validateUnknownFormat(executionContext, node, rootNode, instanceLocation);
+ validateUnknownFormat(executionContext, node, rootNode, instanceLocation);
}
}
@@ -99,19 +96,17 @@ public Set validate(ExecutionContext executionContext, JsonNo
* @param node the node
* @param rootNode the root node
* @param instanceLocation the instance location
- * @return the messages
*/
- protected Set validateUnknownFormat(ExecutionContext executionContext,
+ protected void validateUnknownFormat(ExecutionContext executionContext,
JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
/*
* Unknown formats should create an assertion if the vocab is specified
* according to the specification.
*/
if (createUnknownFormatAssertions(executionContext) && this.schemaNode.isTextual()) {
- return Collections.singleton(message().instanceLocation(instanceLocation).instanceNode(node)
+ executionContext.addError(message().instanceLocation(instanceLocation).instanceNode(node)
.messageKey("format.unknown").arguments(schemaNode.textValue()).build());
}
- return Collections.emptySet();
}
/**
diff --git a/src/main/java/com/networknt/schema/IfValidator.java b/src/main/java/com/networknt/schema/IfValidator.java
index 13ed4e855..5a4bfb2e5 100644
--- a/src/main/java/com/networknt/schema/IfValidator.java
+++ b/src/main/java/com/networknt/schema/IfValidator.java
@@ -64,27 +64,31 @@ public IfValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath, J
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
boolean ifConditionPassed = false;
// Save flag as nested schema evaluation shouldn't trigger fail fast
boolean failFast = executionContext.isFailFast();
+ List existingErrors = executionContext.getErrors();
+ List test = new ArrayList<>();
+ executionContext.setErrors(test);
try {
executionContext.setFailFast(false);
- ifConditionPassed = this.ifSchema.validate(executionContext, node, rootNode, instanceLocation).isEmpty();
+ this.ifSchema.validate(executionContext, node, rootNode, instanceLocation);
+ ifConditionPassed = test.isEmpty();
} finally {
// Restore flag
+ executionContext.setErrors(existingErrors);
executionContext.setFailFast(failFast);
}
if (ifConditionPassed && this.thenSchema != null) {
- return this.thenSchema.validate(executionContext, node, rootNode, instanceLocation);
+ this.thenSchema.validate(executionContext, node, rootNode, instanceLocation);
} else if (!ifConditionPassed && this.elseSchema != null) {
- return this.elseSchema.validate(executionContext, node, rootNode, instanceLocation);
+ this.elseSchema.validate(executionContext, node, rootNode, instanceLocation);
}
- return Collections.emptySet();
}
@Override
@@ -101,17 +105,22 @@ public void preloadJsonSchema() {
}
@Override
- public Set walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
+ public void walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
boolean checkCondition = node != null && shouldValidateSchema;
boolean ifConditionPassed = false;
// Save flag as nested schema evaluation shouldn't trigger fail fast
boolean failFast = executionContext.isFailFast();
+ List existingErrors = executionContext.getErrors();
+ List test = new ArrayList<>();
+ executionContext.setErrors(test);
try {
executionContext.setFailFast(false);
- ifConditionPassed = this.ifSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema).isEmpty();
+ this.ifSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema);
+ ifConditionPassed = test.isEmpty();
} finally {
// Restore flag
+ executionContext.setErrors(existingErrors);
executionContext.setFailFast(failFast);
}
if (!checkCondition) {
@@ -123,13 +132,12 @@ public Set walk(ExecutionContext executionContext, JsonNode n
}
} else {
if (this.thenSchema != null && ifConditionPassed) {
- return this.thenSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema);
+ this.thenSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema);
}
else if (this.elseSchema != null && !ifConditionPassed) {
- return this.elseSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema);
+ this.elseSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema);
}
}
- return Collections.emptySet();
}
}
diff --git a/src/main/java/com/networknt/schema/ItemsValidator.java b/src/main/java/com/networknt/schema/ItemsValidator.java
index 26f2813f6..0cf913cd4 100644
--- a/src/main/java/com/networknt/schema/ItemsValidator.java
+++ b/src/main/java/com/networknt/schema/ItemsValidator.java
@@ -20,7 +20,6 @@
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.networknt.schema.annotation.JsonNodeAnnotation;
import com.networknt.schema.utils.JsonSchemaRefs;
-import com.networknt.schema.utils.SetView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -87,12 +86,12 @@ public ItemsValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
if (!node.isArray() && !this.validationContext.getConfig().isTypeLoose()) {
// ignores non-arrays
- return Collections.emptySet();
+ return;
}
boolean collectAnnotations = collectAnnotations();
@@ -125,17 +124,16 @@ public Set validate(ExecutionContext executionContext, JsonNo
}
boolean hasAdditionalItem = false;
- SetView errors = new SetView<>();
if (node.isArray()) {
int i = 0;
for (JsonNode n : node) {
- if (doValidate(executionContext, errors, i, n, rootNode, instanceLocation)) {
+ if (doValidate(executionContext, i, n, rootNode, instanceLocation)) {
hasAdditionalItem = true;
}
i++;
}
} else {
- if (doValidate(executionContext, errors, 0, node, rootNode, instanceLocation)) {
+ if (doValidate(executionContext, 0, node, rootNode, instanceLocation)) {
hasAdditionalItem = true;
}
}
@@ -149,10 +147,9 @@ public Set validate(ExecutionContext executionContext, JsonNo
.keyword("additionalItems").value(true).build());
}
}
- return errors.isEmpty() ? Collections.emptySet() : errors;
}
- private boolean doValidate(ExecutionContext executionContext, SetView errors, int i, JsonNode node,
+ private boolean doValidate(ExecutionContext executionContext, int i, JsonNode node,
JsonNode rootNode, JsonNodePath instanceLocation) {
boolean isAdditionalItem = false;
JsonNodePath path = instanceLocation.append(i);
@@ -160,17 +157,11 @@ private boolean doValidate(ExecutionContext executionContext, SetView results = this.schema.validate(executionContext, node, rootNode, path);
- if (!results.isEmpty()) {
- errors.union(results);
- }
+ this.schema.validate(executionContext, node, rootNode, path);
} else if (this.tupleSchema != null) {
if (i < this.tupleSchema.size()) {
// validate against tuple schema
- Set results = this.tupleSchema.get(i).validate(executionContext, node, rootNode, path);
- if (!results.isEmpty()) {
- errors.union(results);
- }
+ this.tupleSchema.get(i).validate(executionContext, node, rootNode, path);
} else {
if ((this.additionalItems != null && this.additionalItems) || this.additionalSchema != null) {
isAdditionalItem = true;
@@ -178,23 +169,20 @@ private boolean doValidate(ExecutionContext executionContext, SetView results = this.additionalSchema.validate(executionContext, node, rootNode, path);
- if (!results.isEmpty()) {
- errors.union(results);
- }
+ this.additionalSchema.validate(executionContext, node, rootNode, path);
} else if (this.additionalItems != null) {
if (this.additionalItems) {
// evaluatedItems.add(path);
} else {
// no additional item allowed, return error
- errors.union(Collections.singleton(message().instanceNode(rootNode).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(rootNode).instanceLocation(instanceLocation)
.type("additionalItems")
.messageKey("additionalItems")
.evaluationPath(this.additionalItemsEvaluationPath)
.schemaLocation(this.additionalItemsSchemaLocation)
.schemaNode(this.additionalItemsSchemaNode)
.locale(executionContext.getExecutionConfig().getLocale())
- .failFast(executionContext.isFailFast()).arguments(i).build()));
+ .failFast(executionContext.isFailFast()).arguments(i).build());
}
}
}
@@ -203,8 +191,7 @@ private boolean doValidate(ExecutionContext executionContext, SetView walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
- Set validationMessages = new LinkedHashSet<>();
+ public void walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
boolean collectAnnotations = collectAnnotations();
// Add items annotation
@@ -252,10 +239,10 @@ public Set walk(ExecutionContext executionContext, JsonNode n
n = defaultNode;
}
}
- walkSchema(executionContext, this.schema, n, rootNode, instanceLocation.append(i), shouldValidateSchema, validationMessages, ValidatorTypeCode.ITEMS.getValue());
+ walkSchema(executionContext, this.schema, n, rootNode, instanceLocation.append(i), shouldValidateSchema, ValidatorTypeCode.ITEMS.getValue());
}
} else {
- walkSchema(executionContext, this.schema, null, rootNode, instanceLocation.append(0), shouldValidateSchema, validationMessages, ValidatorTypeCode.ITEMS.getValue());
+ walkSchema(executionContext, this.schema, null, rootNode, instanceLocation.append(0), shouldValidateSchema, ValidatorTypeCode.ITEMS.getValue());
}
}
else if (this.tupleSchema != null) {
@@ -276,10 +263,10 @@ else if (this.tupleSchema != null) {
}
}
walkSchema(executionContext, this.tupleSchema.get(i), n, rootNode, instanceLocation.append(i),
- shouldValidateSchema, validationMessages, ValidatorTypeCode.ITEMS.getValue());
+ shouldValidateSchema, ValidatorTypeCode.ITEMS.getValue());
} else {
walkSchema(executionContext, this.tupleSchema.get(i), null, rootNode, instanceLocation.append(i),
- shouldValidateSchema, validationMessages, ValidatorTypeCode.ITEMS.getValue());
+ shouldValidateSchema, ValidatorTypeCode.ITEMS.getValue());
}
}
if (this.additionalSchema != null) {
@@ -303,13 +290,13 @@ else if (this.tupleSchema != null) {
}
}
walkSchema(executionContext, this.additionalSchema, n, rootNode, instanceLocation.append(i),
- shouldValidateSchema, validationMessages, PROPERTY_ADDITIONAL_ITEMS);
+ shouldValidateSchema, PROPERTY_ADDITIONAL_ITEMS);
if (n != null) {
hasAdditionalItem = true;
}
} else {
walkSchema(executionContext, this.additionalSchema, null, rootNode, instanceLocation.append(i),
- shouldValidateSchema, validationMessages, PROPERTY_ADDITIONAL_ITEMS);
+ shouldValidateSchema, PROPERTY_ADDITIONAL_ITEMS);
}
}
@@ -324,7 +311,6 @@ else if (this.tupleSchema != null) {
}
}
}
- return validationMessages;
}
private static JsonNode getDefaultNode(JsonSchema schema) {
@@ -339,14 +325,15 @@ private static JsonNode getDefaultNode(JsonSchema schema) {
}
private void walkSchema(ExecutionContext executionContext, JsonSchema walkSchema, JsonNode node, JsonNode rootNode,
- JsonNodePath instanceLocation, boolean shouldValidateSchema, Set validationMessages, String keyword) {
+ JsonNodePath instanceLocation, boolean shouldValidateSchema, String keyword) {
boolean executeWalk = this.validationContext.getConfig().getItemWalkListenerRunner().runPreWalkListeners(executionContext, keyword,
node, rootNode, instanceLocation, walkSchema, this);
+ int currentErrors = executionContext.getErrors().size();
if (executeWalk) {
- validationMessages.addAll(walkSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema));
+ walkSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema);
}
this.validationContext.getConfig().getItemWalkListenerRunner().runPostWalkListeners(executionContext, keyword, node, rootNode,
- instanceLocation, walkSchema, this, validationMessages);
+ instanceLocation, walkSchema, this, executionContext.getErrors().subList(currentErrors, executionContext.getErrors().size()));
}
diff --git a/src/main/java/com/networknt/schema/ItemsValidator202012.java b/src/main/java/com/networknt/schema/ItemsValidator202012.java
index b37971141..859f7542a 100644
--- a/src/main/java/com/networknt/schema/ItemsValidator202012.java
+++ b/src/main/java/com/networknt/schema/ItemsValidator202012.java
@@ -20,13 +20,10 @@
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.networknt.schema.annotation.JsonNodeAnnotation;
import com.networknt.schema.utils.JsonSchemaRefs;
-import com.networknt.schema.utils.SetView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.*;
-
/**
* {@link JsonValidator} for items from V2012-12.
*/
@@ -63,36 +60,26 @@ public ItemsValidator202012(SchemaLocation schemaLocation, JsonNodePath evaluati
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
// ignores non-arrays
if (node.isArray()) {
- SetView errors = null;
boolean evaluated = false;
for (int i = this.prefixCount; i < node.size(); ++i) {
JsonNodePath path = instanceLocation.append(i);
// validate with item schema (the whole array has the same item schema)
- Set results = null;
if (additionalItems) {
- results = this.schema.validate(executionContext, node.get(i), rootNode, path);
+ this.schema.validate(executionContext, node.get(i), rootNode, path);
} else {
// This handles the case where "items": false as the boolean false schema doesn't
// generate a helpful message
int x = i;
- results = Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(x).build());
}
- if (results.isEmpty()) {
-// evaluatedItems.add(path);
- } else {
- if (errors == null) {
- errors = new SetView<>();
- }
- errors.union(results);
- }
evaluated = true;
}
if (evaluated) {
@@ -104,17 +91,12 @@ public Set validate(ExecutionContext executionContext, JsonNo
.keyword(getKeyword()).value(true).build());
}
}
- return errors == null || errors.isEmpty() ? Collections.emptySet() : errors;
- } else {
- return Collections.emptySet();
}
}
@Override
- public Set walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ public void walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation, boolean shouldValidateSchema) {
- Set validationMessages = new LinkedHashSet<>();
-
if (node instanceof ArrayNode) {
ArrayNode arrayNode = (ArrayNode) node;
JsonNode defaultNode = null;
@@ -130,8 +112,7 @@ public Set walk(ExecutionContext executionContext, JsonNode n
n = defaultNode;
}
// Walk the schema.
- walkSchema(executionContext, this.schema, n, rootNode, instanceLocation.append(i), shouldValidateSchema,
- validationMessages);
+ walkSchema(executionContext, this.schema, n, rootNode, instanceLocation.append(i), shouldValidateSchema);
if (n != null) {
evaluated = true;
}
@@ -149,10 +130,8 @@ public Set walk(ExecutionContext executionContext, JsonNode n
// If the node is not an ArrayNode, e.g. ObjectNode or null then the instance is null.
// The instance location starts at the end of the prefix count.
walkSchema(executionContext, this.schema, null, rootNode, instanceLocation.append(this.prefixCount),
- shouldValidateSchema, validationMessages);
+ shouldValidateSchema);
}
-
- return validationMessages;
}
private static JsonNode getDefaultNode(JsonSchema schema) {
@@ -167,7 +146,7 @@ private static JsonNode getDefaultNode(JsonSchema schema) {
}
private void walkSchema(ExecutionContext executionContext, JsonSchema walkSchema, JsonNode node, JsonNode rootNode,
- JsonNodePath instanceLocation, boolean shouldValidateSchema, Set validationMessages) {
+ JsonNodePath instanceLocation, boolean shouldValidateSchema) {
//@formatter:off
boolean executeWalk = this.validationContext.getConfig().getItemWalkListenerRunner().runPreWalkListeners(
executionContext,
@@ -177,8 +156,9 @@ private void walkSchema(ExecutionContext executionContext, JsonSchema walkSchema
instanceLocation,
walkSchema, this
);
+ int currentErrors = executionContext.getErrors().size();
if (executeWalk) {
- validationMessages.addAll(walkSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema));
+ walkSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema);
}
this.validationContext.getConfig().getItemWalkListenerRunner().runPostWalkListeners(
executionContext,
@@ -187,7 +167,7 @@ private void walkSchema(ExecutionContext executionContext, JsonSchema walkSchema
rootNode,
instanceLocation,
walkSchema,
- this, validationMessages
+ this, executionContext.getErrors().subList(currentErrors, executionContext.getErrors().size())
);
//@formatter:on
}
diff --git a/src/main/java/com/networknt/schema/JsonSchema.java b/src/main/java/com/networknt/schema/JsonSchema.java
index a3627e58f..69626417f 100644
--- a/src/main/java/com/networknt/schema/JsonSchema.java
+++ b/src/main/java/com/networknt/schema/JsonSchema.java
@@ -23,19 +23,16 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
-import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
-import java.util.Set;
import java.util.function.Consumer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.networknt.schema.SpecVersion.VersionFlag;
import com.networknt.schema.utils.JsonNodes;
-import com.networknt.schema.utils.SetView;
/**
* Used for creating a schema with validators for validating inputs. This is
@@ -142,8 +139,8 @@ public static JsonNodePath getInstance() {
}
}
- public Set validate(ExecutionContext executionContext, JsonNode node) {
- return validate(executionContext, node, node, atRoot());
+ public void validate(ExecutionContext executionContext, JsonNode node) {
+ validate(executionContext, node, node, atRoot());
}
/**
@@ -711,7 +708,7 @@ private long activeDialect() {
/************************ START OF VALIDATE METHODS **********************************/
@Override
- public Set validate(ExecutionContext executionContext, JsonNode jsonNode, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode jsonNode, JsonNode rootNode, JsonNodePath instanceLocation) {
if (this.validationContext.getConfig().isDiscriminatorKeywordEnabled()) {
ObjectNode discriminator = (ObjectNode) schemaNode.get("discriminator");
if (null != discriminator && null != executionContext.getCurrentDiscriminatorContext()) {
@@ -719,21 +716,9 @@ public Set validate(ExecutionContext executionContext, JsonNo
discriminator);
}
}
-
- SetView errors = null;
+ int currentErrors = executionContext.getErrors().size();
for (JsonValidator v : getValidators()) {
- Set results = null;
-
- try {
- results = v.validate(executionContext, jsonNode, rootNode, instanceLocation);
- } finally {
- if (results != null && !results.isEmpty()) {
- if (errors == null) {
- errors = new SetView<>();
- }
- errors.union(results);
- }
- }
+ v.validate(executionContext, jsonNode, rootNode, instanceLocation);
}
if (this.validationContext.getConfig().isDiscriminatorKeywordEnabled()) {
@@ -765,12 +750,11 @@ public Set validate(ExecutionContext executionContext, JsonNo
}
}
- if (errors != null && !errors.isEmpty()) {
+ if (executionContext.getErrors().size() > currentErrors) {
// Failed with assertion set result and drop all annotations from this schema
// and all subschemas
executionContext.getResults().setResult(instanceLocation, getSchemaLocation(), getEvaluationPath(), false);
}
- return errors == null ? Collections.emptySet() : errors;
}
/**
@@ -786,7 +770,7 @@ public Set validate(ExecutionContext executionContext, JsonNo
* @return A list of ValidationMessage if there is any validation error, or an
* empty list if there is no error.
*/
- public Set validate(JsonNode rootNode) {
+ public List validate(JsonNode rootNode) {
return validate(rootNode, OutputFormat.DEFAULT);
}
@@ -803,7 +787,7 @@ public Set validate(JsonNode rootNode) {
* @param executionCustomizer the execution customizer
* @return the assertions
*/
- public Set validate(JsonNode rootNode, ExecutionContextCustomizer executionCustomizer) {
+ public List validate(JsonNode rootNode, ExecutionContextCustomizer executionCustomizer) {
return validate(rootNode, OutputFormat.DEFAULT, executionCustomizer);
}
@@ -820,7 +804,7 @@ public Set validate(JsonNode rootNode, ExecutionContextCustom
* @param executionCustomizer the execution customizer
* @return the assertions
*/
- public Set validate(JsonNode rootNode, Consumer executionCustomizer) {
+ public List validate(JsonNode rootNode, Consumer executionCustomizer) {
return validate(rootNode, OutputFormat.DEFAULT, executionCustomizer);
}
@@ -898,7 +882,7 @@ public T validate(JsonNode rootNode, OutputFormat format, Consumer validate(String input, InputFormat inputFormat) {
+ public List validate(String input, InputFormat inputFormat) {
return validate(deserialize(input, inputFormat), OutputFormat.DEFAULT);
}
@@ -917,7 +901,7 @@ public Set validate(String input, InputFormat inputFormat) {
* @param executionCustomizer the execution customizer
* @return the assertions
*/
- public Set validate(String input, InputFormat inputFormat, ExecutionContextCustomizer executionCustomizer) {
+ public List validate(String input, InputFormat inputFormat, ExecutionContextCustomizer executionCustomizer) {
return validate(deserialize(input, inputFormat), OutputFormat.DEFAULT, executionCustomizer);
}
@@ -936,7 +920,7 @@ public Set validate(String input, InputFormat inputFormat, Ex
* @param executionCustomizer the execution customizer
* @return the assertions
*/
- public Set validate(String input, InputFormat inputFormat, Consumer executionCustomizer) {
+ public List validate(String input, InputFormat inputFormat, Consumer executionCustomizer) {
return validate(deserialize(input, inputFormat), OutputFormat.DEFAULT, executionCustomizer);
}
@@ -1031,13 +1015,12 @@ public T validate(ExecutionContext executionContext, JsonNode node, OutputFo
if (executionCustomizer != null) {
executionCustomizer.customize(executionContext, this.validationContext);
}
- Set validationMessages = null;
try {
- validationMessages = validate(executionContext, node);
+ validate(executionContext, node);
} catch (FailFastAssertionException e) {
- validationMessages = e.getValidationMessages();
+ executionContext.setErrors(e.getErrors());
}
- return format.format(this, validationMessages, executionContext, this.validationContext);
+ return format.format(this, executionContext, this.validationContext);
}
/**
@@ -1083,7 +1066,7 @@ public ValidationResult validateAndCollect(ExecutionContext executionContext, Js
@Deprecated
private ValidationResult validateAndCollect(ExecutionContext executionContext, JsonNode jsonNode, JsonNode rootNode, JsonNodePath instanceLocation) {
// Validate.
- Set errors = validate(executionContext, jsonNode, rootNode, instanceLocation);
+ validate(executionContext, jsonNode, rootNode, instanceLocation);
// Get the config.
SchemaValidatorsConfig config = this.validationContext.getConfig();
@@ -1097,7 +1080,7 @@ private ValidationResult validateAndCollect(ExecutionContext executionContext, J
collectorContext.loadCollectors();
}
// Collect errors and collector context into validation result.
- return new ValidationResult(errors, executionContext);
+ return new ValidationResult(executionContext);
}
/**
@@ -1356,7 +1339,7 @@ private T walkAtNodeInternal(ExecutionContext executionContext, JsonNode nod
executionCustomizer.customize(executionContext, this.validationContext);
}
// Walk through the schema.
- Set errors = walk(executionContext, node, rootNode, instanceLocation, validate);
+ walk(executionContext, node, rootNode, instanceLocation, validate);
// Get the config.
SchemaValidatorsConfig config = this.validationContext.getConfig();
@@ -1369,14 +1352,14 @@ private T walkAtNodeInternal(ExecutionContext executionContext, JsonNode nod
// Load all the data from collectors into the context.
collectorContext.loadCollectors();
}
- return format.format(this, errors, executionContext, this.validationContext);
+ return format.format(this, executionContext, this.validationContext);
}
@Override
- public Set walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ public void walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation, boolean shouldValidateSchema) {
- Set errors = new LinkedHashSet<>();
// Walk through all the JSONWalker's.
+ int currentErrors = executionContext.getErrors().size();
for (JsonValidator validator : getValidators()) {
JsonNodePath evaluationPathWithKeyword = validator.getEvaluationPath();
try {
@@ -1385,23 +1368,16 @@ public Set walk(ExecutionContext executionContext, JsonNode n
if (this.validationContext.getConfig().getKeywordWalkListenerRunner().runPreWalkListeners(executionContext,
evaluationPathWithKeyword.getName(-1), node, rootNode, instanceLocation,
this, validator)) {
- Set results = null;
- try {
- results = validator.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema);
- } finally {
- if (results != null && !results.isEmpty()) {
- errors.addAll(results);
- }
- }
+ validator.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema);
}
} finally {
// Call all the post-walk listeners.
this.validationContext.getConfig().getKeywordWalkListenerRunner().runPostWalkListeners(executionContext,
evaluationPathWithKeyword.getName(-1), node, rootNode, instanceLocation,
- this, validator, errors);
+ this, validator,
+ executionContext.getErrors().subList(currentErrors, executionContext.getErrors().size()));
}
}
- return errors;
}
/************************ END OF WALK METHODS **********************************/
diff --git a/src/main/java/com/networknt/schema/JsonSchemaException.java b/src/main/java/com/networknt/schema/JsonSchemaException.java
index d667e8701..1add66f77 100644
--- a/src/main/java/com/networknt/schema/JsonSchemaException.java
+++ b/src/main/java/com/networknt/schema/JsonSchemaException.java
@@ -17,42 +17,42 @@
package com.networknt.schema;
import java.util.Collections;
-import java.util.Set;
+import java.util.List;
/**
* Represents an error when processing the JsonSchema.
*/
public class JsonSchemaException extends RuntimeException {
private static final long serialVersionUID = -7805792737596582110L;
- private final ValidationMessage validationMessage;
+ private final ValidationMessage error;
- public JsonSchemaException(ValidationMessage validationMessage) {
- this.validationMessage = validationMessage;
+ public JsonSchemaException(ValidationMessage error) {
+ this.error = error;
}
public JsonSchemaException(String message) {
super(message);
- this.validationMessage = null;
+ this.error = null;
}
public JsonSchemaException(Throwable throwable) {
super(throwable);
- this.validationMessage = null;
+ this.error = null;
}
@Override
public String getMessage() {
- return this.validationMessage != null ? this.validationMessage.getMessage() : super.getMessage();
+ return this.error != null ? this.error.getMessage() : super.getMessage();
}
- public ValidationMessage getValidationMessage() {
- return this.validationMessage;
+ public ValidationMessage getError() {
+ return this.error;
}
- public Set getValidationMessages() {
- if (validationMessage == null) {
- return Collections.emptySet();
+ public List getErrors() {
+ if (error == null) {
+ return Collections.emptyList();
}
- return Collections.singleton(validationMessage);
+ return Collections.singletonList(error);
}
}
diff --git a/src/main/java/com/networknt/schema/JsonSchemaValidator.java b/src/main/java/com/networknt/schema/JsonSchemaValidator.java
index 3216b1ac0..cb551a1b4 100644
--- a/src/main/java/com/networknt/schema/JsonSchemaValidator.java
+++ b/src/main/java/com/networknt/schema/JsonSchemaValidator.java
@@ -16,9 +16,6 @@
package com.networknt.schema;
-import java.util.Collections;
-import java.util.Set;
-
import com.fasterxml.jackson.databind.JsonNode;
import com.networknt.schema.walk.JsonSchemaWalker;
@@ -33,11 +30,8 @@ public interface JsonSchemaValidator extends JsonSchemaWalker {
* @param node JsonNode
* @param rootNode JsonNode
* @param instanceLocation JsonNodePath
- *
- * @return A list of ValidationMessage if there is any validation error, or an empty
- * list if there is no error.
*/
- Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation);
/**
@@ -45,14 +39,15 @@ Set validate(ExecutionContext executionContext, JsonNode node
* validate method if shouldValidateSchema is enabled.
*/
@Override
- default Set walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ default void walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation, boolean shouldValidateSchema) {
if (node == null) {
// Note that null is not the same as NullNode
- return Collections.emptySet();
+ return;
+ }
+ if (shouldValidateSchema) {
+ validate(executionContext, node, rootNode, instanceLocation);
}
- return shouldValidateSchema ? validate(executionContext, node, rootNode, instanceLocation)
- : Collections.emptySet();
}
/**
diff --git a/src/main/java/com/networknt/schema/MaxItemsValidator.java b/src/main/java/com/networknt/schema/MaxItemsValidator.java
index 1f7748bf7..75a4fbcae 100644
--- a/src/main/java/com/networknt/schema/MaxItemsValidator.java
+++ b/src/main/java/com/networknt/schema/MaxItemsValidator.java
@@ -20,9 +20,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Collections;
-import java.util.Set;
-
/**
* {@link JsonValidator} for maxItems.
*/
@@ -41,24 +38,22 @@ public MaxItemsValidator(SchemaLocation schemaLocation, JsonNodePath evaluationP
}
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
if (node.isArray()) {
if (node.size() > this.max) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(this.max, node.size()).build());
}
} else if (this.validationContext.getConfig().isTypeLoose()) {
if (1 > this.max) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(this.max, 1).build());
}
}
-
- return Collections.emptySet();
}
}
diff --git a/src/main/java/com/networknt/schema/MaxLengthValidator.java b/src/main/java/com/networknt/schema/MaxLengthValidator.java
index ec587fdef..fb8504d49 100644
--- a/src/main/java/com/networknt/schema/MaxLengthValidator.java
+++ b/src/main/java/com/networknt/schema/MaxLengthValidator.java
@@ -20,9 +20,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Collections;
-import java.util.Set;
-
/**
* {@link JsonValidator} for maxLength.
*/
@@ -40,20 +37,19 @@ public MaxLengthValidator(SchemaLocation schemaLocation, JsonNodePath evaluation
}
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
JsonType nodeType = TypeFactory.getValueNodeType(node, this.validationContext.getConfig());
if (nodeType != JsonType.STRING) {
// ignore no-string typs
- return Collections.emptySet();
+ return;
}
if (node.textValue().codePointCount(0, node.textValue().length()) > this.maxLength) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(this.maxLength).build());
}
- return Collections.emptySet();
}
}
diff --git a/src/main/java/com/networknt/schema/MaxPropertiesValidator.java b/src/main/java/com/networknt/schema/MaxPropertiesValidator.java
index f6e58724d..432186140 100644
--- a/src/main/java/com/networknt/schema/MaxPropertiesValidator.java
+++ b/src/main/java/com/networknt/schema/MaxPropertiesValidator.java
@@ -20,9 +20,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Collections;
-import java.util.Set;
-
/**
* {@link JsonValidator}for maxProperties.
*/
@@ -41,18 +38,16 @@ public MaxPropertiesValidator(SchemaLocation schemaLocation, JsonNodePath evalua
}
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
if (node.isObject()) {
if (node.size() > max) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(max).build());
}
}
-
- return Collections.emptySet();
}
}
diff --git a/src/main/java/com/networknt/schema/MaximumValidator.java b/src/main/java/com/networknt/schema/MaximumValidator.java
index 1bbef9e7a..0c6630b94 100644
--- a/src/main/java/com/networknt/schema/MaximumValidator.java
+++ b/src/main/java/com/networknt/schema/MaximumValidator.java
@@ -24,8 +24,6 @@
import java.math.BigDecimal;
import java.math.BigInteger;
-import java.util.Collections;
-import java.util.Set;
/**
* {@link JsonValidator} for maxmimum.
@@ -109,20 +107,19 @@ public String thresholdValue() {
}
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
if (!JsonNodeUtil.isNumber(node, this.validationContext.getConfig())) {
// maximum only applies to numbers
- return Collections.emptySet();
+ return;
}
if (this.typedMaximum.crossesThreshold(node)) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast())
.arguments(this.typedMaximum.thresholdValue()).build());
}
- return Collections.emptySet();
}
}
\ No newline at end of file
diff --git a/src/main/java/com/networknt/schema/MinItemsValidator.java b/src/main/java/com/networknt/schema/MinItemsValidator.java
index 52f927b14..41da79afb 100644
--- a/src/main/java/com/networknt/schema/MinItemsValidator.java
+++ b/src/main/java/com/networknt/schema/MinItemsValidator.java
@@ -20,9 +20,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Collections;
-import java.util.Set;
-
/**
* {@link JsonValidator} for minItems.
*/
@@ -38,25 +35,23 @@ public MinItemsValidator(SchemaLocation schemaLocation, JsonNodePath evaluationP
}
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
if (node.isArray()) {
if (node.size() < min) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(min, node.size())
.build());
}
} else if (this.validationContext.getConfig().isTypeLoose()) {
if (1 < min) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(min, 1).build());
}
}
-
- return Collections.emptySet();
}
}
diff --git a/src/main/java/com/networknt/schema/MinLengthValidator.java b/src/main/java/com/networknt/schema/MinLengthValidator.java
index 1161ba2f5..cce1f97b4 100644
--- a/src/main/java/com/networknt/schema/MinLengthValidator.java
+++ b/src/main/java/com/networknt/schema/MinLengthValidator.java
@@ -20,9 +20,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Collections;
-import java.util.Set;
-
/**
* {@link JsonValidator} for minLength.
*/
@@ -39,21 +36,20 @@ public MinLengthValidator(SchemaLocation schemaLocation, JsonNodePath evaluation
}
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
JsonType nodeType = TypeFactory.getValueNodeType(node, this.validationContext.getConfig());
if (nodeType != JsonType.STRING) {
// ignore non-string types
- return Collections.emptySet();
+ return;
}
if (node.textValue().codePointCount(0, node.textValue().length()) < minLength) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(minLength).build());
}
- return Collections.emptySet();
}
}
diff --git a/src/main/java/com/networknt/schema/MinMaxContainsValidator.java b/src/main/java/com/networknt/schema/MinMaxContainsValidator.java
index 768aba654..3cbcc476e 100644
--- a/src/main/java/com/networknt/schema/MinMaxContainsValidator.java
+++ b/src/main/java/com/networknt/schema/MinMaxContainsValidator.java
@@ -2,10 +2,8 @@
import com.fasterxml.jackson.databind.JsonNode;
-import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
-import java.util.stream.Collectors;
/**
* {@link JsonValidator} for {@literal maxContains} and {@literal minContains} in a schema.
@@ -59,16 +57,18 @@ public MinMaxContainsValidator(SchemaLocation schemaLocation, JsonNodePath evalu
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation) {
- return this.analysis != null ? this.analysis.stream()
- .map(analysis -> message().instanceNode(node)
- .instanceLocation(instanceLocation)
- .messageKey(analysis.getMessageKey()).locale(executionContext.getExecutionConfig().getLocale())
- .failFast(executionContext.isFailFast())
- .type(analysis.getMessageKey())
- .arguments(parentSchema.getSchemaNode().toString()).build())
- .collect(Collectors.toCollection(LinkedHashSet::new)) : Collections.emptySet();
+ if (this.analysis != null) {
+ this.analysis.stream()
+ .map(analysis -> message().instanceNode(node)
+ .instanceLocation(instanceLocation)
+ .messageKey(analysis.getMessageKey()).locale(executionContext.getExecutionConfig().getLocale())
+ .failFast(executionContext.isFailFast())
+ .type(analysis.getMessageKey())
+ .arguments(parentSchema.getSchemaNode().toString()).build())
+ .forEach(executionContext::addError);
+ }
}
public static class Analysis {
diff --git a/src/main/java/com/networknt/schema/MinPropertiesValidator.java b/src/main/java/com/networknt/schema/MinPropertiesValidator.java
index 2867a0832..36584c162 100644
--- a/src/main/java/com/networknt/schema/MinPropertiesValidator.java
+++ b/src/main/java/com/networknt/schema/MinPropertiesValidator.java
@@ -20,9 +20,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Collections;
-import java.util.Set;
-
/**
* {@link JsonValidator} for minProperties.
*/
@@ -41,18 +38,16 @@ public MinPropertiesValidator(SchemaLocation schemaLocation, JsonNodePath evalua
}
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
if (node.isObject()) {
if (node.size() < min) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(min).build());
}
}
-
- return Collections.emptySet();
}
}
diff --git a/src/main/java/com/networknt/schema/MinimumValidator.java b/src/main/java/com/networknt/schema/MinimumValidator.java
index dc557a185..877518732 100644
--- a/src/main/java/com/networknt/schema/MinimumValidator.java
+++ b/src/main/java/com/networknt/schema/MinimumValidator.java
@@ -24,8 +24,6 @@
import java.math.BigDecimal;
import java.math.BigInteger;
-import java.util.Collections;
-import java.util.Set;
/**
* {@link JsonValidator} for minimum.
@@ -116,21 +114,20 @@ public String thresholdValue() {
}
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
if (!JsonNodeUtil.isNumber(node, this.validationContext.getConfig())) {
// minimum only applies to numbers
- return Collections.emptySet();
+ return;
}
if (this.typedMinimum.crossesThreshold(node)) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast())
.arguments(this.typedMinimum.thresholdValue()).build());
}
- return Collections.emptySet();
}
}
diff --git a/src/main/java/com/networknt/schema/MultipleOfValidator.java b/src/main/java/com/networknt/schema/MultipleOfValidator.java
index bcd29d2db..e3089cdea 100644
--- a/src/main/java/com/networknt/schema/MultipleOfValidator.java
+++ b/src/main/java/com/networknt/schema/MultipleOfValidator.java
@@ -23,8 +23,6 @@
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
-import java.util.Collections;
-import java.util.Set;
/**
* {@link JsonValidator} for multipleOf.
@@ -40,21 +38,20 @@ public MultipleOfValidator(SchemaLocation schemaLocation, JsonNodePath evaluatio
this.divisor = getDivisor(schemaNode);
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
if (this.divisor != null) {
BigDecimal dividend = getDividend(node);
if (dividend != null) {
if (dividend.divideAndRemainder(this.divisor)[1].abs().compareTo(BigDecimal.ZERO) > 0) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(this.divisor)
.build());
}
}
}
- return Collections.emptySet();
}
/**
diff --git a/src/main/java/com/networknt/schema/NonValidationKeyword.java b/src/main/java/com/networknt/schema/NonValidationKeyword.java
index a5f2c15fb..2b2cde777 100644
--- a/src/main/java/com/networknt/schema/NonValidationKeyword.java
+++ b/src/main/java/com/networknt/schema/NonValidationKeyword.java
@@ -18,10 +18,8 @@
import com.fasterxml.jackson.databind.JsonNode;
-import java.util.Collections;
import java.util.Iterator;
import java.util.Map.Entry;
-import java.util.Set;
/**
* Used for Keywords that have no validation aspect, but are part of the metaschema.
@@ -51,8 +49,8 @@ public Validator(SchemaLocation schemaLocation, JsonNodePath evaluationPath, Jso
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
- return Collections.emptySet();
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ // Do nothing
}
}
diff --git a/src/main/java/com/networknt/schema/NotAllowedValidator.java b/src/main/java/com/networknt/schema/NotAllowedValidator.java
index 448bd978b..78f6c0c84 100644
--- a/src/main/java/com/networknt/schema/NotAllowedValidator.java
+++ b/src/main/java/com/networknt/schema/NotAllowedValidator.java
@@ -43,26 +43,19 @@ public NotAllowedValidator(SchemaLocation schemaLocation, JsonNodePath evaluatio
}
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
- Set errors = null;
-
for (String fieldName : fieldNames) {
JsonNode propertyNode = node.get(fieldName);
if (propertyNode != null) {
- if (errors == null) {
- errors = new LinkedHashSet<>();
- }
- errors.add(message().property(fieldName).instanceNode(node)
+ executionContext.addError(message().property(fieldName).instanceNode(node)
.instanceLocation(instanceLocation.append(fieldName))
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(fieldName).build());
}
}
-
- return errors == null ? Collections.emptySet() : Collections.unmodifiableSet(errors);
}
}
diff --git a/src/main/java/com/networknt/schema/NotValidator.java b/src/main/java/com/networknt/schema/NotValidator.java
index c63ae34ac..67c607994 100644
--- a/src/main/java/com/networknt/schema/NotValidator.java
+++ b/src/main/java/com/networknt/schema/NotValidator.java
@@ -37,42 +37,49 @@ public NotValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath,
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation) {
- return validate(executionContext, node, rootNode, instanceLocation, false);
+ validate(executionContext, node, rootNode, instanceLocation, false);
}
- protected Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ protected void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation, boolean walk) {
- Set errors = null;
+
debug(logger, executionContext, node, rootNode, instanceLocation);
// Save flag as nested schema evaluation shouldn't trigger fail fast
boolean failFast = executionContext.isFailFast();
+ List existingErrors = executionContext.getErrors();
+ List test = new ArrayList<>();
+ executionContext.setErrors(test);
try {
executionContext.setFailFast(false);
- errors = !walk ? this.schema.validate(executionContext, node, rootNode, instanceLocation)
- : this.schema.walk(executionContext, node, rootNode, instanceLocation, true);
+ if (!walk) {
+ this.schema.validate(executionContext, node, rootNode, instanceLocation);
+ } else {
+ this.schema.walk(executionContext, node, rootNode, instanceLocation, true);
+ }
} finally {
// Restore flag
executionContext.setFailFast(failFast);
+ executionContext.setErrors(existingErrors);
}
- if (errors.isEmpty()) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ if (test.isEmpty()) {
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(this.schema.toString())
.build());
}
- return Collections.emptySet();
}
@Override
- public Set walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
+ public void walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
if (shouldValidateSchema && node != null) {
- return validate(executionContext, node, rootNode, instanceLocation, true);
+ validate(executionContext, node, rootNode, instanceLocation, true);
+ return;
}
- return this.schema.walk(executionContext, node, rootNode, instanceLocation, false);
+ this.schema.walk(executionContext, node, rootNode, instanceLocation, false);
}
@Override
diff --git a/src/main/java/com/networknt/schema/OneOfValidator.java b/src/main/java/com/networknt/schema/OneOfValidator.java
index caca84353..0ad80e99c 100644
--- a/src/main/java/com/networknt/schema/OneOfValidator.java
+++ b/src/main/java/com/networknt/schema/OneOfValidator.java
@@ -17,18 +17,13 @@
package com.networknt.schema;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
import java.util.List;
-import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.networknt.schema.utils.SetView;
/**
* {@link JsonValidator} for oneOf.
@@ -59,23 +54,24 @@ public OneOfValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation) {
- return validate(executionContext, node, rootNode, instanceLocation, false);
+ validate(executionContext, node, rootNode, instanceLocation, false);
}
- protected Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ protected void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation, boolean walk) {
- Set errors = null;
-
debug(logger, executionContext, node, rootNode, instanceLocation);
int numberOfValidSchema = 0;
int index = 0;
- SetView childErrors = null;
List indexes = null;
-
+ List existingErrors = executionContext.getErrors();
+ List childErrors = null;
+ List schemaErrors = new ArrayList<>();
+ executionContext.setErrors(schemaErrors);
// Save flag as nested schema evaluation shouldn't trigger fail fast
boolean failFast = executionContext.isFailFast();
+ boolean addMessages = true;
try {
DiscriminatorValidator discriminator = null;
if (this.validationContext.getConfig().isDiscriminatorKeywordEnabled()) {
@@ -93,16 +89,15 @@ protected Set validate(ExecutionContext executionContext, Jso
}
executionContext.setFailFast(false);
for (JsonSchema schema : this.schemas) {
- Set schemaErrors = Collections.emptySet();
+ schemaErrors.clear();
if (!walk) {
- schemaErrors = schema.validate(executionContext, node, rootNode, instanceLocation);
+ schema.validate(executionContext, node, rootNode, instanceLocation);
} else {
- schemaErrors = schema.walk(executionContext, node, rootNode, instanceLocation,
- true);
+ schema.walk(executionContext, node, rootNode, instanceLocation, true);
}
// check if any validation errors have occurred
- if (schemaErrors.isEmpty()) {
+ if (schemaErrors.isEmpty()) { // No new errors
numberOfValidSchema++;
if (indexes == null) {
indexes = new ArrayList<>();
@@ -144,22 +139,22 @@ protected Set validate(ExecutionContext executionContext, Jso
if (currentDiscriminatorContext.isDiscriminatorMatchFound() && childErrors == null) {
// Note that the match is set if found and not reset so checking if childErrors
// found is null triggers on the correct schema
- childErrors = new SetView<>();
- childErrors.union(schemaErrors);
+ childErrors = new ArrayList<>();
+ childErrors.addAll(schemaErrors);
} else if (currentDiscriminatorContext.isDiscriminatorIgnore()
|| !currentDiscriminatorContext.isActive()) {
// This is the normal handling when discriminators aren't enabled
if (childErrors == null) {
- childErrors = new SetView<>();
+ childErrors = new ArrayList<>();
}
- childErrors.union(schemaErrors);
+ childErrors.addAll(schemaErrors);
}
} else if (!schemaErrors.isEmpty() && reportChildErrors(executionContext)) {
// This is the normal handling when discriminators aren't enabled
if (childErrors == null) {
- childErrors = new SetView<>();
+ childErrors = new ArrayList<>();
}
- childErrors.union(schemaErrors);
+ childErrors.addAll(schemaErrors);
}
index++;
}
@@ -168,7 +163,8 @@ protected Set validate(ExecutionContext executionContext, Jso
&& (discriminator != null || executionContext.getCurrentDiscriminatorContext().isActive())
&& !executionContext.getCurrentDiscriminatorContext().isDiscriminatorMatchFound()
&& !executionContext.getCurrentDiscriminatorContext().isDiscriminatorIgnore()) {
- errors = Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ addMessages = false;
+ existingErrors.add(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.arguments(
"based on the provided discriminator. No alternative could be chosen based on the discriminator property")
@@ -186,19 +182,19 @@ protected Set validate(ExecutionContext executionContext, Jso
// ensure there is always an "OneOf" error reported if number of valid schemas
// is not equal to 1.
// errors will only not be null in the discriminator case where no match is found
- if (numberOfValidSchema != 1 && errors == null) {
+ if (numberOfValidSchema != 1 && addMessages) {
ValidationMessage message = message().instanceNode(node).instanceLocation(instanceLocation)
.messageKey(numberOfValidSchema > 1 ? "oneOf.indexes" : "oneOf")
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast())
.arguments(Integer.toString(numberOfValidSchema), numberOfValidSchema > 1 ? String.join(", ", indexes) : "").build();
+ existingErrors.add(message);
if (childErrors != null) {
- errors = new SetView().union(Collections.singleton(message)).union(childErrors);
- } else {
- errors = Collections.singleton(message);
+ existingErrors.addAll(childErrors);
}
}
- return errors != null ? errors : Collections.emptySet();
+ executionContext.setErrors(existingErrors);
+ return;
}
/**
@@ -228,16 +224,14 @@ protected boolean canShortCircuit() {
}
@Override
- public Set walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
- HashSet validationMessages = new LinkedHashSet<>();
+ public void walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
if (shouldValidateSchema && node != null) {
- validationMessages.addAll(validate(executionContext, node, rootNode, instanceLocation, true));
+ validate(executionContext, node, rootNode, instanceLocation, true);
} else {
for (JsonSchema schema : this.schemas) {
schema.walk(executionContext, node, rootNode, instanceLocation, false);
}
}
- return validationMessages;
}
@Override
diff --git a/src/main/java/com/networknt/schema/OutputFormat.java b/src/main/java/com/networknt/schema/OutputFormat.java
index 61e0c904d..93d1da44e 100644
--- a/src/main/java/com/networknt/schema/OutputFormat.java
+++ b/src/main/java/com/networknt/schema/OutputFormat.java
@@ -15,7 +15,6 @@
*/
package com.networknt.schema;
-import java.util.Set;
import java.util.function.Function;
import com.networknt.schema.output.HierarchicalOutputUnitFormatter;
@@ -45,13 +44,12 @@ default void customize(ExecutionContext executionContext, ValidationContext vali
* Formats the validation results.
*
* @param jsonSchema the schema
- * @param validationMessages the validation messages
* @param executionContext the execution context
* @param validationContext the validation context
*
* @return the result
*/
- T format(JsonSchema jsonSchema, Set validationMessages,
+ T format(JsonSchema jsonSchema,
ExecutionContext executionContext, ValidationContext validationContext);
/**
@@ -90,16 +88,16 @@ T format(JsonSchema jsonSchema, Set validationMessages,
/**
* The Default output format.
*/
- class Default implements OutputFormat> {
+ class Default implements OutputFormat> {
@Override
public void customize(ExecutionContext executionContext, ValidationContext validationContext) {
executionContext.getExecutionConfig().setAnnotationCollectionEnabled(false);
}
@Override
- public Set format(JsonSchema jsonSchema,
- Set validationMessages, ExecutionContext executionContext, ValidationContext validationContext) {
- return validationMessages;
+ public java.util.List format(JsonSchema jsonSchema,
+ ExecutionContext executionContext, ValidationContext validationContext) {
+ return executionContext.getErrors();
}
}
@@ -114,9 +112,9 @@ public void customize(ExecutionContext executionContext, ValidationContext valid
}
@Override
- public OutputFlag format(JsonSchema jsonSchema, Set validationMessages,
+ public OutputFlag format(JsonSchema jsonSchema,
ExecutionContext executionContext, ValidationContext validationContext) {
- return new OutputFlag(validationMessages.isEmpty());
+ return new OutputFlag(executionContext.getErrors().isEmpty());
}
}
@@ -131,9 +129,9 @@ public void customize(ExecutionContext executionContext, ValidationContext valid
}
@Override
- public java.lang.Boolean format(JsonSchema jsonSchema, Set validationMessages,
+ public java.lang.Boolean format(JsonSchema jsonSchema,
ExecutionContext executionContext, ValidationContext validationContext) {
- return validationMessages.isEmpty();
+ return executionContext.getErrors().isEmpty();
}
}
@@ -161,9 +159,9 @@ public void customize(ExecutionContext executionContext, ValidationContext valid
}
@Override
- public OutputUnit format(JsonSchema jsonSchema, Set validationMessages,
+ public OutputUnit format(JsonSchema jsonSchema,
ExecutionContext executionContext, ValidationContext validationContext) {
- return ListOutputUnitFormatter.format(validationMessages, executionContext, validationContext,
+ return ListOutputUnitFormatter.format(executionContext.getErrors(), executionContext, validationContext,
this.assertionMapper);
}
}
@@ -192,9 +190,9 @@ public void customize(ExecutionContext executionContext, ValidationContext valid
}
@Override
- public OutputUnit format(JsonSchema jsonSchema, Set validationMessages,
+ public OutputUnit format(JsonSchema jsonSchema,
ExecutionContext executionContext, ValidationContext validationContext) {
- return HierarchicalOutputUnitFormatter.format(jsonSchema, validationMessages, executionContext,
+ return HierarchicalOutputUnitFormatter.format(jsonSchema, executionContext.getErrors(), executionContext,
validationContext, this.assertionMapper);
}
}
@@ -210,9 +208,8 @@ public void customize(ExecutionContext executionContext, ValidationContext valid
}
@Override
- public ValidationResult format(JsonSchema jsonSchema,
- Set validationMessages, ExecutionContext executionContext, ValidationContext validationContext) {
- return new ValidationResult(validationMessages, executionContext);
+ public ValidationResult format(JsonSchema jsonSchema,ExecutionContext executionContext, ValidationContext validationContext) {
+ return new ValidationResult(executionContext);
}
}
}
diff --git a/src/main/java/com/networknt/schema/PatternPropertiesValidator.java b/src/main/java/com/networknt/schema/PatternPropertiesValidator.java
index 94cb16cd1..95403ad0d 100644
--- a/src/main/java/com/networknt/schema/PatternPropertiesValidator.java
+++ b/src/main/java/com/networknt/schema/PatternPropertiesValidator.java
@@ -49,13 +49,12 @@ public PatternPropertiesValidator(SchemaLocation schemaLocation, JsonNodePath ev
}
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
if (!node.isObject()) {
- return Collections.emptySet();
+ return;
}
- Set errors = null;
Set matchedInstancePropertyNames = null;
Iterator names = node.fieldNames();
boolean collectAnnotations = collectAnnotations() || collectAnnotations(executionContext);
@@ -65,19 +64,15 @@ public Set validate(ExecutionContext executionContext, JsonNo
for (Map.Entry entry : schemas.entrySet()) {
if (entry.getKey().matches(name)) {
JsonNodePath path = instanceLocation.append(name);
- Set results = entry.getValue().validate(executionContext, n, rootNode, path);
- if (results.isEmpty()) {
+ int currentErrors = executionContext.getErrors().size();
+ entry.getValue().validate(executionContext, n, rootNode, path);
+ if (currentErrors == executionContext.getErrors().size()) { // No new errors
if (collectAnnotations) {
if (matchedInstancePropertyNames == null) {
matchedInstancePropertyNames = new LinkedHashSet<>();
}
matchedInstancePropertyNames.add(name);
}
- } else {
- if (errors == null) {
- errors = new LinkedHashSet<>();
- }
- errors.addAll(results);
}
}
}
@@ -91,7 +86,6 @@ public Set validate(ExecutionContext executionContext, JsonNo
: Collections.emptySet())
.build());
}
- return errors == null ? Collections.emptySet() : Collections.unmodifiableSet(errors);
}
private boolean collectAnnotations() {
diff --git a/src/main/java/com/networknt/schema/PatternValidator.java b/src/main/java/com/networknt/schema/PatternValidator.java
index 166c553a4..b4b29e733 100644
--- a/src/main/java/com/networknt/schema/PatternValidator.java
+++ b/src/main/java/com/networknt/schema/PatternValidator.java
@@ -21,9 +21,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Collections;
import java.util.Optional;
-import java.util.Set;
public class PatternValidator extends BaseJsonValidator {
private static final Logger logger = LoggerFactory.getLogger(PatternValidator.class);
@@ -48,19 +46,20 @@ private boolean matches(String value) {
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
JsonType nodeType = TypeFactory.getValueNodeType(node, this.validationContext.getConfig());
if (nodeType != JsonType.STRING) {
- return Collections.emptySet();
+ return;
}
try {
if (!matches(node.asText())) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(this.pattern).build());
+ return;
}
} catch (JsonSchemaException | FailFastAssertionException e) {
throw e;
@@ -68,7 +67,5 @@ public Set validate(ExecutionContext executionContext, JsonNo
logger.error("Failed to apply pattern '{}' at {}: {}", this.pattern, instanceLocation, e.getMessage());
throw e;
}
-
- return Collections.emptySet();
}
}
diff --git a/src/main/java/com/networknt/schema/PrefixItemsValidator.java b/src/main/java/com/networknt/schema/PrefixItemsValidator.java
index c390a5af9..9abaa1848 100644
--- a/src/main/java/com/networknt/schema/PrefixItemsValidator.java
+++ b/src/main/java/com/networknt/schema/PrefixItemsValidator.java
@@ -20,16 +20,12 @@
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.networknt.schema.annotation.JsonNodeAnnotation;
import com.networknt.schema.utils.JsonSchemaRefs;
-import com.networknt.schema.utils.SetView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.LinkedHashSet;
import java.util.List;
-import java.util.Set;
/**
* {@link JsonValidator} for prefixItems.
@@ -58,21 +54,14 @@ public PrefixItemsValidator(SchemaLocation schemaLocation, JsonNodePath evaluati
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
// ignores non-arrays
if (node.isArray()) {
- SetView errors = null;
int count = Math.min(node.size(), this.tupleSchema.size());
for (int i = 0; i < count; ++i) {
JsonNodePath path = instanceLocation.append(i);
- Set results = this.tupleSchema.get(i).validate(executionContext, node.get(i), rootNode, path);
- if (!results.isEmpty()) {
- if (errors == null) {
- errors = new SetView<>();
- }
- errors.union(results);
- }
+ this.tupleSchema.get(i).validate(executionContext, node.get(i), rootNode, path);
}
// Add annotation
@@ -94,15 +83,11 @@ public Set validate(ExecutionContext executionContext, JsonNo
.keyword(getKeyword()).value(true).build());
}
}
- return errors == null || errors.isEmpty() ? Collections.emptySet() : errors;
- } else {
- return Collections.emptySet();
}
}
@Override
- public Set walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
- Set validationMessages = new LinkedHashSet<>();
+ public void walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
if (node instanceof ArrayNode) {
ArrayNode array = (ArrayNode) node;
int count = this.tupleSchema.size();
@@ -118,7 +103,7 @@ public Set walk(ExecutionContext executionContext, JsonNode n
}
}
}
- doWalk(executionContext, validationMessages, i, n, rootNode, instanceLocation, shouldValidateSchema);
+ doWalk(executionContext, i, n, rootNode, instanceLocation, shouldValidateSchema);
}
// Add annotation
@@ -143,10 +128,9 @@ public Set walk(ExecutionContext executionContext, JsonNode n
} else {
int count = this.tupleSchema.size();
for (int i = 0; i < count; ++i) {
- doWalk(executionContext, validationMessages, i, null, rootNode, instanceLocation, shouldValidateSchema);
+ doWalk(executionContext, i, null, rootNode, instanceLocation, shouldValidateSchema);
}
}
- return validationMessages;
}
private static JsonNode getDefaultNode(JsonSchema schema) {
@@ -160,14 +144,14 @@ private static JsonNode getDefaultNode(JsonSchema schema) {
return result;
}
- private void doWalk(ExecutionContext executionContext, Set validationMessages, int i,
+ private void doWalk(ExecutionContext executionContext, int i,
JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
walkSchema(executionContext, this.tupleSchema.get(i), node, rootNode, instanceLocation.append(i),
- shouldValidateSchema, validationMessages);
+ shouldValidateSchema);
}
private void walkSchema(ExecutionContext executionContext, JsonSchema walkSchema, JsonNode node, JsonNode rootNode,
- JsonNodePath instanceLocation, boolean shouldValidateSchema, Set validationMessages) {
+ JsonNodePath instanceLocation, boolean shouldValidateSchema) {
//@formatter:off
boolean executeWalk = this.validationContext.getConfig().getItemWalkListenerRunner().runPreWalkListeners(
executionContext,
@@ -177,8 +161,9 @@ private void walkSchema(ExecutionContext executionContext, JsonSchema walkSchema
instanceLocation,
walkSchema, this
);
+ int currentErrors = executionContext.getErrors().size();
if (executeWalk) {
- validationMessages.addAll(walkSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema));
+ walkSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema);
}
this.validationContext.getConfig().getItemWalkListenerRunner().runPostWalkListeners(
executionContext,
@@ -187,7 +172,7 @@ private void walkSchema(ExecutionContext executionContext, JsonSchema walkSchema
rootNode,
instanceLocation,
walkSchema,
- this, validationMessages
+ this, executionContext.getErrors().subList(currentErrors, executionContext.getErrors().size())
);
//@formatter:on
}
diff --git a/src/main/java/com/networknt/schema/PropertiesValidator.java b/src/main/java/com/networknt/schema/PropertiesValidator.java
index 36bcab846..c64e767ef 100644
--- a/src/main/java/com/networknt/schema/PropertiesValidator.java
+++ b/src/main/java/com/networknt/schema/PropertiesValidator.java
@@ -22,7 +22,6 @@
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.networknt.schema.annotation.JsonNodeAnnotation;
import com.networknt.schema.utils.JsonSchemaRefs;
-import com.networknt.schema.utils.SetView;
import com.networknt.schema.walk.WalkListenerRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,17 +55,15 @@ public PropertiesValidator(SchemaLocation schemaLocation, JsonNodePath evaluatio
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation) {
- return validate(executionContext, node, rootNode, instanceLocation, false);
+ validate(executionContext, node, rootNode, instanceLocation, false);
}
- protected Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
+ protected void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation, boolean walk) {
debug(logger, executionContext, node, rootNode, instanceLocation);
- SetView errors = null;
-
Set matchedInstancePropertyNames = null;
boolean collectAnnotations = collectAnnotations() || collectAnnotations(executionContext);
for (Entry entry : this.schemas.entrySet()) {
@@ -81,20 +78,10 @@ protected Set validate(ExecutionContext executionContext, Jso
}
if (!walk) {
//validate the child element(s)
- Set result = entry.getValue().validate(executionContext, propertyNode, rootNode,
- path);
- if (!result.isEmpty()) {
- if (errors == null) {
- errors = new SetView<>();
- }
- errors.union(result);
- }
+ entry.getValue().validate(executionContext, propertyNode, rootNode, path);
} else {
// check if walker is enabled. If it is enabled it is upto the walker implementation to decide about the validation.
- if (errors == null) {
- errors = new SetView<>();
- }
- walkSchema(executionContext, entry, node, rootNode, instanceLocation, true, errors, this.validationContext.getConfig().getPropertyWalkListenerRunner());
+ walkSchema(executionContext, entry, node, rootNode, instanceLocation, true, this.validationContext.getConfig().getPropertyWalkListenerRunner());
}
} else {
if (walk) {
@@ -103,10 +90,7 @@ protected Set validate(ExecutionContext executionContext, Jso
// null.
// The actual walk needs to be skipped as the validators assume that node is not
// null.
- if (errors == null) {
- errors = new SetView<>();
- }
- walkSchema(executionContext, entry, node, rootNode, instanceLocation, true, errors, this.validationContext.getConfig().getPropertyWalkListenerRunner());
+ walkSchema(executionContext, entry, node, rootNode, instanceLocation, true, this.validationContext.getConfig().getPropertyWalkListenerRunner());
}
}
}
@@ -118,27 +102,23 @@ protected Set validate(ExecutionContext executionContext, Jso
: matchedInstancePropertyNames)
.build());
}
-
- return errors == null || errors.isEmpty() ? Collections.emptySet() : errors;
}
@Override
- public Set walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
- SetView validationMessages = new SetView<>();
+ public void walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
if (this.validationContext.getConfig().getApplyDefaultsStrategy().shouldApplyPropertyDefaults() && null != node
&& node.getNodeType() == JsonNodeType.OBJECT) {
applyPropertyDefaults((ObjectNode) node);
}
if (shouldValidateSchema) {
- validationMessages.union(validate(executionContext, node == null ? MissingNode.getInstance() : node, rootNode,
- instanceLocation, true));
+ validate(executionContext, node == null ? MissingNode.getInstance() : node, rootNode,
+ instanceLocation, true);
} else {
WalkListenerRunner propertyWalkListenerRunner = this.validationContext.getConfig().getPropertyWalkListenerRunner();
for (Map.Entry entry : this.schemas.entrySet()) {
- walkSchema(executionContext, entry, node, rootNode, instanceLocation, shouldValidateSchema, validationMessages, propertyWalkListenerRunner);
+ walkSchema(executionContext, entry, node, rootNode, instanceLocation, shouldValidateSchema, propertyWalkListenerRunner);
}
}
- return validationMessages;
}
private boolean collectAnnotations() {
@@ -180,8 +160,7 @@ private static JsonNode getDefaultNode(JsonSchema schema) {
}
private void walkSchema(ExecutionContext executionContext, Map.Entry entry, JsonNode node,
- JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema,
- SetView validationMessages, WalkListenerRunner propertyWalkListenerRunner) {
+ JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema, WalkListenerRunner propertyWalkListenerRunner) {
JsonSchema propertySchema = entry.getValue();
JsonNode propertyNode = (node == null ? null : node.get(entry.getKey()));
JsonNodePath path = instanceLocation.append(entry.getKey());
@@ -192,20 +171,19 @@ private void walkSchema(ExecutionContext executionContext, Map.Entry getSchemas() {
return this.schemas;
}
-
@Override
public void preloadJsonSchema() {
preloadJsonSchemas(this.schemas.values());
diff --git a/src/main/java/com/networknt/schema/PropertyNamesValidator.java b/src/main/java/com/networknt/schema/PropertyNamesValidator.java
index 3d895f031..0fa90bed5 100644
--- a/src/main/java/com/networknt/schema/PropertyNamesValidator.java
+++ b/src/main/java/com/networknt/schema/PropertyNamesValidator.java
@@ -15,10 +15,9 @@
*/
package com.networknt.schema;
-import java.util.Collections;
+import java.util.ArrayList;
import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.Set;
+import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -34,30 +33,30 @@ public PropertyNamesValidator(SchemaLocation schemaLocation, JsonNodePath evalua
innerSchema = validationContext.newSchema(schemaLocation, evaluationPath, schemaNode, parentSchema);
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
- Set errors = null;
+ List existingErrors = executionContext.getErrors();
+ List schemaErrors = new ArrayList<>();
+ executionContext.setErrors(schemaErrors);
for (Iterator it = node.fieldNames(); it.hasNext(); ) {
final String pname = it.next();
final TextNode pnameText = TextNode.valueOf(pname);
- final Set schemaErrors = innerSchema.validate(executionContext, pnameText, node, instanceLocation.append(pname));
+ innerSchema.validate(executionContext, pnameText, node, instanceLocation.append(pname));
for (final ValidationMessage schemaError : schemaErrors) {
final String path = schemaError.getInstanceLocation().toString();
String msg = schemaError.getMessage();
if (msg.startsWith(path)) {
msg = msg.substring(path.length()).replaceFirst("^:\\s*", "");
}
- if (errors == null) {
- errors = new LinkedHashSet<>();
- }
- errors.add(
+ existingErrors.add(
message().property(pname).instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(pname, msg).build());
}
+ schemaErrors.clear();
}
- return errors == null || errors.isEmpty() ? Collections.emptySet() : Collections.unmodifiableSet(errors);
+ executionContext.setErrors(existingErrors);
}
diff --git a/src/main/java/com/networknt/schema/ReadOnlyValidator.java b/src/main/java/com/networknt/schema/ReadOnlyValidator.java
index c7b0b9a2d..f9416fe07 100644
--- a/src/main/java/com/networknt/schema/ReadOnlyValidator.java
+++ b/src/main/java/com/networknt/schema/ReadOnlyValidator.java
@@ -16,9 +16,6 @@
package com.networknt.schema;
-import java.util.Collections;
-import java.util.Set;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,14 +37,14 @@ public ReadOnlyValidator(SchemaLocation schemaLocation, JsonNodePath evaluationP
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
if (this.readOnly) {
- return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
+ executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).build());
}
- return Collections.emptySet();
+ return;
}
}
\ No newline at end of file
diff --git a/src/main/java/com/networknt/schema/RecursiveRefValidator.java b/src/main/java/com/networknt/schema/RecursiveRefValidator.java
index 711fe932d..31688aa2f 100644
--- a/src/main/java/com/networknt/schema/RecursiveRefValidator.java
+++ b/src/main/java/com/networknt/schema/RecursiveRefValidator.java
@@ -20,8 +20,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Collections;
-import java.util.Set;
import java.util.function.Supplier;
/**
@@ -87,7 +85,7 @@ static JsonSchema getSchema(JsonSchema parentSchema, ValidationContext validatio
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
JsonSchema refSchema = this.schema.getSchema();
if (refSchema == null) {
@@ -97,11 +95,11 @@ public Set validate(ExecutionContext executionContext, JsonNo
.arguments(schemaNode.asText()).build();
throw new InvalidSchemaRefException(validationMessage);
}
- return refSchema.validate(executionContext, node, rootNode, instanceLocation);
+ refSchema.validate(executionContext, node, rootNode, instanceLocation);
}
@Override
- public Set walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
+ public void walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
debug(logger, executionContext, node, rootNode, instanceLocation);
// This is important because if we use same JsonSchemaFactory for creating multiple JSONSchema instances,
// these schemas will be cached along with config. We have to replace the config for cached $ref references
@@ -127,10 +125,10 @@ public Set walk(ExecutionContext executionContext, JsonNode n
}
}
if (circularDependency) {
- return Collections.emptySet();
+ return;
}
}
- return refSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema);
+ refSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema);
}
public JsonSchemaRef getSchemaRef() {
diff --git a/src/main/java/com/networknt/schema/RefValidator.java b/src/main/java/com/networknt/schema/RefValidator.java
index 823e43c78..c173f8140 100644
--- a/src/main/java/com/networknt/schema/RefValidator.java
+++ b/src/main/java/com/networknt/schema/RefValidator.java
@@ -20,8 +20,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Collections;
-import java.util.Set;
import java.util.function.Supplier;
/**
@@ -176,7 +174,7 @@ private static JsonSchema getJsonSchema(JsonSchema parent,
}
@Override
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
JsonSchema refSchema = this.schema.getSchema();
if (refSchema == null) {
@@ -186,11 +184,11 @@ public Set validate(ExecutionContext executionContext, JsonNo
.arguments(schemaNode.asText()).build();
throw new InvalidSchemaRefException(validationMessage);
}
- return refSchema.validate(executionContext, node, rootNode, instanceLocation);
+ refSchema.validate(executionContext, node, rootNode, instanceLocation);
}
@Override
- public Set walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
+ public void walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
debug(logger, executionContext, node, rootNode, instanceLocation);
// This is important because if we use same JsonSchemaFactory for creating multiple JSONSchema instances,
// these schemas will be cached along with config. We have to replace the config for cached $ref references
@@ -216,10 +214,10 @@ public Set walk(ExecutionContext executionContext, JsonNode n
}
}
if (circularDependency) {
- return Collections.emptySet();
+ return;
}
}
- return refSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema);
+ refSchema.walk(executionContext, node, rootNode, instanceLocation, shouldValidateSchema);
}
public JsonSchemaRef getSchemaRef() {
diff --git a/src/main/java/com/networknt/schema/RequiredValidator.java b/src/main/java/com/networknt/schema/RequiredValidator.java
index 7084b6b92..41bfa3c5b 100644
--- a/src/main/java/com/networknt/schema/RequiredValidator.java
+++ b/src/main/java/com/networknt/schema/RequiredValidator.java
@@ -42,15 +42,13 @@ public RequiredValidator(SchemaLocation schemaLocation, JsonNodePath evaluationP
}
}
- public Set validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
+ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, executionContext, node, rootNode, instanceLocation);
if (!node.isObject()) {
- return Collections.emptySet();
+ return;
}
- Set