From e9669af662ad6065a5f3a4eccc17807a52ac41cf Mon Sep 17 00:00:00 2001
From: Justin Tay <49700559+justin-tay@users.noreply.github.com>
Date: Sun, 21 Sep 2025 10:04:03 +0800
Subject: [PATCH 01/74] Refactor to remove ErrorMessageType
---
.../networknt/schema/BaseJsonValidator.java | 21 +---
.../networknt/schema/ContainsValidator.java | 2 +-
.../schema/CustomErrorMessageType.java | 35 ------
.../networknt/schema/DynamicRefValidator.java | 8 +-
.../networknt/schema/ErrorMessageType.java | 38 ------
.../com/networknt/schema/FormatKeyword.java | 10 +-
.../com/networknt/schema/FormatValidator.java | 9 +-
.../com/networknt/schema/ItemsValidator.java | 2 +-
.../java/com/networknt/schema/JsonSchema.java | 17 +--
.../MessageSourceValidationMessage.java | 4 +-
.../schema/MinMaxContainsValidator.java | 2 +-
.../schema/RecursiveRefValidator.java | 10 +-
.../com/networknt/schema/RefValidator.java | 8 +-
.../networknt/schema/UnionTypeValidator.java | 2 +-
.../networknt/schema/ValidationMessage.java | 89 ++++++-------
.../networknt/schema/ValidatorTypeCode.java | 118 ++++++++----------
.../format/BaseFormatJsonValidator.java | 5 +-
.../schema/output/OutputUnitData.java | 6 +-
.../schema/AbstractJsonSchemaTest.java | 10 +-
.../schema/CustomMetaSchemaTest.java | 4 +-
.../schema/DiscriminatorValidatorTest.java | 20 +--
.../schema/ExclusiveMinimumValidatorTest.java | 2 +-
.../com/networknt/schema/Issue426Test.java | 2 +-
.../com/networknt/schema/MessageTest.java | 4 +-
.../schema/MultipleOfValidatorTest.java | 10 +-
.../networknt/schema/OneOfValidatorTest.java | 10 +-
.../networknt/schema/TypeValidatorTest.java | 4 +-
.../schema/UnevaluatedItemsValidatorTest.java | 8 +-
.../UnevaluatedPropertiesValidatorTest.java | 8 +-
.../com/networknt/schema/VocabularyTest.java | 4 +-
.../networknt/schema/oas/OpenApi30Test.java | 4 +-
.../networknt/schema/oas/OpenApi31Test.java | 14 +--
.../networknt/schema/utils/JsonNodesTest.java | 8 +-
33 files changed, 186 insertions(+), 312 deletions(-)
delete mode 100644 src/main/java/com/networknt/schema/CustomErrorMessageType.java
delete mode 100644 src/main/java/com/networknt/schema/ErrorMessageType.java
diff --git a/src/main/java/com/networknt/schema/BaseJsonValidator.java b/src/main/java/com/networknt/schema/BaseJsonValidator.java
index c1313ff44..88a5d536b 100644
--- a/src/main/java/com/networknt/schema/BaseJsonValidator.java
+++ b/src/main/java/com/networknt/schema/BaseJsonValidator.java
@@ -41,16 +41,8 @@ public abstract class BaseJsonValidator implements JsonValidator {
protected final JsonNodePath evaluationPath;
protected final JsonSchema evaluationParentSchema;
- // Pending removal
- protected final ErrorMessageType errorMessageType;
-
public BaseJsonValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath, JsonNode schemaNode,
- JsonSchema parentSchema, ValidatorTypeCode validatorType, ValidationContext validationContext) {
- this(schemaLocation, evaluationPath, schemaNode, parentSchema, validatorType, validatorType, validationContext);
- }
-
- public BaseJsonValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath, JsonNode schemaNode,
- JsonSchema parentSchema, ErrorMessageType errorMessageType, Keyword keyword,
+ JsonSchema parentSchema, Keyword keyword,
ValidationContext validationContext) {
this.validationContext = validationContext;
this.schemaNode = schemaNode;
@@ -64,8 +56,6 @@ public BaseJsonValidator(SchemaLocation schemaLocation, JsonNodePath evaluationP
} else {
this.errorMessage = null;
}
-
- this.errorMessageType = errorMessageType;
this.evaluationPath = evaluationPath;
this.evaluationParentSchema = null;
}
@@ -75,7 +65,6 @@ public BaseJsonValidator(SchemaLocation schemaLocation, JsonNodePath evaluationP
*
* @param schemaNode the schema node
* @param validationContext the validation context
- * @param errorMessageType the error message type
* @param keyword the keyword
* @param parentSchema the parent schema
* @param schemaLocation the schema location
@@ -88,7 +77,6 @@ protected BaseJsonValidator(
JsonNode schemaNode,
ValidationContext validationContext,
/* Below from ValidationMessageHandler */
- ErrorMessageType errorMessageType,
Keyword keyword,
JsonSchema parentSchema,
SchemaLocation schemaLocation,
@@ -103,7 +91,6 @@ protected BaseJsonValidator(
this.schemaLocation = schemaLocation;
this.errorMessage = errorMessage;
- this.errorMessageType = errorMessageType;
this.evaluationPath = evaluationPath;
this.evaluationParentSchema = evaluationParentSchema;
}
@@ -233,9 +220,9 @@ protected MessageSourceValidationMessage.Builder message() {
if (failFast) {
throw new FailFastAssertionException(message);
}
- }).code(this.errorMessageType.getErrorCode()).schemaNode(this.schemaNode).schemaLocation(this.schemaLocation)
- .evaluationPath(this.evaluationPath).type(this.keyword != null ? this.keyword.getValue() : null)
- .messageKey(this.errorMessageType.getErrorCodeValue());
+ }).schemaNode(this.schemaNode).schemaLocation(this.schemaLocation)
+ .evaluationPath(this.evaluationPath).keyword(this.keyword != null ? this.keyword.getValue() : null)
+ .messageKey(this.getKeyword());
}
/**
diff --git a/src/main/java/com/networknt/schema/ContainsValidator.java b/src/main/java/com/networknt/schema/ContainsValidator.java
index a5f971454..af0183849 100644
--- a/src/main/java/com/networknt/schema/ContainsValidator.java
+++ b/src/main/java/com/networknt/schema/ContainsValidator.java
@@ -194,7 +194,7 @@ private void boundsViolated(ExecutionContext executionContext, ValidatorTypeCode
}
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());
+ .keyword(validatorTypeCode.getValue()).build());
}
/**
diff --git a/src/main/java/com/networknt/schema/CustomErrorMessageType.java b/src/main/java/com/networknt/schema/CustomErrorMessageType.java
deleted file mode 100644
index ef08734ec..000000000
--- a/src/main/java/com/networknt/schema/CustomErrorMessageType.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2016 Network New Technologies Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.networknt.schema;
-
-public class CustomErrorMessageType implements ErrorMessageType {
- private final String errorCode;
-
- private CustomErrorMessageType(String errorCode) {
- this.errorCode = errorCode;
- }
-
- public static ErrorMessageType of(String errorCode) {
- return new CustomErrorMessageType(errorCode);
- }
-
- @Override
- public String getErrorCode() {
- return errorCode;
- }
-
-}
\ No newline at end of file
diff --git a/src/main/java/com/networknt/schema/DynamicRefValidator.java b/src/main/java/com/networknt/schema/DynamicRefValidator.java
index 1cf2d0632..1517df949 100644
--- a/src/main/java/com/networknt/schema/DynamicRefValidator.java
+++ b/src/main/java/com/networknt/schema/DynamicRefValidator.java
@@ -94,8 +94,8 @@ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode
debug(logger, executionContext, node, rootNode, instanceLocation);
JsonSchema refSchema = this.schema.getSchema();
if (refSchema == null) {
- ValidationMessage validationMessage = message().type(ValidatorTypeCode.DYNAMIC_REF.getValue())
- .code("internal.unresolvedRef").message("{0}: Reference {1} cannot be resolved")
+ ValidationMessage validationMessage = message().keyword(ValidatorTypeCode.DYNAMIC_REF.getValue())
+ .messageKey("internal.unresolvedRef").message("{0}: Reference {1} cannot be resolved")
.instanceLocation(instanceLocation).evaluationPath(getEvaluationPath())
.arguments(schemaNode.asText()).build();
throw new InvalidSchemaRefException(validationMessage);
@@ -111,8 +111,8 @@ public void walk(ExecutionContext executionContext, JsonNode node, JsonNode root
// with the latest config. Reset the config.
JsonSchema refSchema = this.schema.getSchema();
if (refSchema == null) {
- ValidationMessage validationMessage = message().type(ValidatorTypeCode.DYNAMIC_REF.getValue())
- .code("internal.unresolvedRef").message("{0}: Reference {1} cannot be resolved")
+ ValidationMessage validationMessage = message().keyword(ValidatorTypeCode.DYNAMIC_REF.getValue())
+ .messageKey("internal.unresolvedRef").message("{0}: Reference {1} cannot be resolved")
.instanceLocation(instanceLocation).evaluationPath(getEvaluationPath())
.arguments(schemaNode.asText()).build();
throw new InvalidSchemaRefException(validationMessage);
diff --git a/src/main/java/com/networknt/schema/ErrorMessageType.java b/src/main/java/com/networknt/schema/ErrorMessageType.java
deleted file mode 100644
index 72b0acbd0..000000000
--- a/src/main/java/com/networknt/schema/ErrorMessageType.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2016 Network New Technologies Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.networknt.schema;
-
-public interface ErrorMessageType {
- /**
- * Your error code. Please ensure global uniqueness. Builtin error codes are sequential numbers.
- *
- * Customer error codes could have a prefix to denote the namespace of your custom keywords and errors.
- *
- * @return error code
- */
- String getErrorCode();
-
- /**
- * Get the text representation of the error code.
- *
- * @return The error code value.
- */
- default String getErrorCodeValue() {
- return getErrorCode();
- }
-
-}
diff --git a/src/main/java/com/networknt/schema/FormatKeyword.java b/src/main/java/com/networknt/schema/FormatKeyword.java
index cb2031ffb..44d780526 100644
--- a/src/main/java/com/networknt/schema/FormatKeyword.java
+++ b/src/main/java/com/networknt/schema/FormatKeyword.java
@@ -27,21 +27,19 @@
*/
public class FormatKeyword implements Keyword {
private final String value;
- private final ErrorMessageType errorMessageType;
private final Map formats;
public FormatKeyword(Map formats) {
this(ValidatorTypeCode.FORMAT, formats);
}
- public FormatKeyword(ValidatorTypeCode type, Map formats) {
- this(type.getValue(), type, formats);
+ public FormatKeyword(Keyword type, Map formats) {
+ this(type.getValue(), formats);
}
- public FormatKeyword(String value, ErrorMessageType errorMessageType, Map formats) {
+ public FormatKeyword(String value, Map formats) {
this.value = value;
this.formats = formats;
- this.errorMessageType = errorMessageType;
}
Collection getFormats() {
@@ -56,7 +54,7 @@ public JsonValidator newValidator(SchemaLocation schemaLocation, JsonNodePath ev
format = this.formats.get(formatName);
}
return new FormatValidator(schemaLocation, evaluationPath, schemaNode, parentSchema, validationContext, format,
- errorMessageType, this);
+ this);
}
@Override
diff --git a/src/main/java/com/networknt/schema/FormatValidator.java b/src/main/java/com/networknt/schema/FormatValidator.java
index 4725786f0..a71b5072b 100644
--- a/src/main/java/com/networknt/schema/FormatValidator.java
+++ b/src/main/java/com/networknt/schema/FormatValidator.java
@@ -34,16 +34,11 @@ public class FormatValidator extends BaseFormatJsonValidator implements JsonVali
public FormatValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath, JsonNode schemaNode,
JsonSchema parentSchema, ValidationContext validationContext, Format format,
- ErrorMessageType errorMessageType, Keyword keyword) {
- super(schemaLocation, evaluationPath, schemaNode, parentSchema, errorMessageType, keyword, validationContext);
+ Keyword keyword) {
+ super(schemaLocation, evaluationPath, schemaNode, parentSchema, keyword, validationContext);
this.format = format;
}
- public FormatValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath, JsonNode schemaNode,
- JsonSchema parentSchema, ValidationContext validationContext, Format format, ValidatorTypeCode type) {
- this(schemaLocation, evaluationPath, schemaNode, parentSchema, validationContext, format, type, type);
- }
-
/**
* Gets the annotation value.
*
diff --git a/src/main/java/com/networknt/schema/ItemsValidator.java b/src/main/java/com/networknt/schema/ItemsValidator.java
index 0cf913cd4..1099a354f 100644
--- a/src/main/java/com/networknt/schema/ItemsValidator.java
+++ b/src/main/java/com/networknt/schema/ItemsValidator.java
@@ -176,7 +176,7 @@ private boolean doValidate(ExecutionContext executionContext, int i, JsonNode no
} else {
// no additional item allowed, return error
executionContext.addError(message().instanceNode(rootNode).instanceLocation(instanceLocation)
- .type("additionalItems")
+ .keyword("additionalItems")
.messageKey("additionalItems")
.evaluationPath(this.additionalItemsEvaluationPath)
.schemaLocation(this.additionalItemsSchemaLocation)
diff --git a/src/main/java/com/networknt/schema/JsonSchema.java b/src/main/java/com/networknt/schema/JsonSchema.java
index 69626417f..c10556f87 100644
--- a/src/main/java/com/networknt/schema/JsonSchema.java
+++ b/src/main/java/com/networknt/schema/JsonSchema.java
@@ -185,7 +185,7 @@ private static SchemaLocation resolve(SchemaLocation schemaLocation, JsonNode sc
if (!validator.validate(id, rootSchema, schemaLocation, result, validationContext)) {
SchemaLocation idSchemaLocation = schemaLocation.append(validationContext.getMetaSchema().getIdKeyword());
ValidationMessage validationMessage = ValidationMessage.builder()
- .code(ValidatorTypeCode.ID.getValue()).type(ValidatorTypeCode.ID.getValue())
+ .messageKey(ValidatorTypeCode.ID.getValue()).keyword(ValidatorTypeCode.ID.getValue())
.instanceLocation(idSchemaLocation.getFragment())
.arguments(id, validationContext.getMetaSchema().getIdKeyword(), idSchemaLocation)
.schemaLocation(idSchemaLocation)
@@ -269,8 +269,6 @@ private JsonSchema(ValidationContext validationContext, SchemaLocation schemaLoc
* @param suppressSubSchemaRetrieval to suppress sub schema retrieval
* @param schemaNode the schema node
* @param validationContext the validation context
- * @param errorMessageType the error message type
- * @param keyword the keyword
* @param parentSchema the parent schema
* @param schemaLocation the schema location
* @param evaluationPath the evaluation path
@@ -289,8 +287,6 @@ protected JsonSchema(
JsonNode schemaNode,
ValidationContext validationContext,
/* Below from ValidationMessageHandler */
- ErrorMessageType errorMessageType,
- Keyword keyword,
JsonSchema parentSchema,
SchemaLocation schemaLocation,
JsonNodePath evaluationPath,
@@ -350,8 +346,7 @@ public JsonSchema fromRef(JsonSchema refEvaluationParentSchema, JsonNodePath ref
schemaNode,
validationContext,
/* Below from ValidationMessageHandler */
- /*errorMessageType*/ null,
- /*keyword*/ null, parentSchema, schemaLocation, evaluationPath,
+ parentSchema, schemaLocation, evaluationPath,
evaluationParentSchema, /* errorMessage */ null);
}
@@ -384,8 +379,6 @@ public JsonSchema withConfig(SchemaValidatorsConfig config) {
schemaNode,
validationContext,
/* Below from ValidationMessageHandler */
- /* errorMessageType */ null,
- /* keyword */ null,
parentSchema,
schemaLocation,
evaluationPath,
@@ -516,7 +509,7 @@ public JsonSchema getSubSchema(JsonNodePath fragment) {
}
if (found == null) {
ValidationMessage validationMessage = ValidationMessage.builder()
- .type(ValidatorTypeCode.REF.getValue()).code("internal.unresolvedRef")
+ .keyword(ValidatorTypeCode.REF.getValue()).messageKey("internal.unresolvedRef")
.message("{0}: Reference {1} cannot be resolved")
.instanceLocation(schemaLocation.getFragment())
.schemaLocation(schemaLocation)
@@ -634,8 +627,8 @@ private List read(JsonNode schemaNode) {
if ("$recursiveAnchor".equals(pname)) {
if (!nodeToUse.isBoolean()) {
- ValidationMessage validationMessage = ValidationMessage.builder().type("$recursiveAnchor")
- .code("internal.invalidRecursiveAnchor")
+ ValidationMessage validationMessage = ValidationMessage.builder().keyword("$recursiveAnchor")
+ .messageKey("internal.invalidRecursiveAnchor")
.message(
"{0}: The value of a $recursiveAnchor must be a Boolean literal but is {1}")
.instanceLocation(path)
diff --git a/src/main/java/com/networknt/schema/MessageSourceValidationMessage.java b/src/main/java/com/networknt/schema/MessageSourceValidationMessage.java
index 1871236a2..880ed6877 100644
--- a/src/main/java/com/networknt/schema/MessageSourceValidationMessage.java
+++ b/src/main/java/com/networknt/schema/MessageSourceValidationMessage.java
@@ -63,8 +63,8 @@ public ValidationMessage build() {
String messagePattern = null;
if (this.errorMessage != null) {
messagePattern = this.errorMessage.get("");
- if (this.property != null) {
- String specificMessagePattern = this.errorMessage.get(this.property);
+ if (this.details != null && this.details.get("property") != null) {
+ String specificMessagePattern = this.errorMessage.get(this.details.get("property"));
if (specificMessagePattern != null) {
messagePattern = specificMessagePattern;
}
diff --git a/src/main/java/com/networknt/schema/MinMaxContainsValidator.java b/src/main/java/com/networknt/schema/MinMaxContainsValidator.java
index 3cbcc476e..3985b57de 100644
--- a/src/main/java/com/networknt/schema/MinMaxContainsValidator.java
+++ b/src/main/java/com/networknt/schema/MinMaxContainsValidator.java
@@ -65,7 +65,7 @@ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode
.instanceLocation(instanceLocation)
.messageKey(analysis.getMessageKey()).locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast())
- .type(analysis.getMessageKey())
+ .keyword(analysis.getMessageKey())
.arguments(parentSchema.getSchemaNode().toString()).build())
.forEach(executionContext::addError);
}
diff --git a/src/main/java/com/networknt/schema/RecursiveRefValidator.java b/src/main/java/com/networknt/schema/RecursiveRefValidator.java
index 31688aa2f..87cd5f21e 100644
--- a/src/main/java/com/networknt/schema/RecursiveRefValidator.java
+++ b/src/main/java/com/networknt/schema/RecursiveRefValidator.java
@@ -36,7 +36,7 @@ public RecursiveRefValidator(SchemaLocation schemaLocation, JsonNodePath evaluat
String refValue = schemaNode.asText();
if (!"#".equals(refValue)) {
ValidationMessage validationMessage = message()
- .type(ValidatorTypeCode.RECURSIVE_REF.getValue()).code("internal.invalidRecursiveRef")
+ .keyword(ValidatorTypeCode.RECURSIVE_REF.getValue()).messageKey("internal.invalidRecursiveRef")
.message("{0}: The value of a $recursiveRef must be '#' but is '{1}'").instanceLocation(schemaLocation.getFragment())
.instanceNode(this.schemaNode)
.evaluationPath(evaluationPath).arguments(refValue).build();
@@ -89,8 +89,8 @@ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode
debug(logger, executionContext, node, rootNode, instanceLocation);
JsonSchema refSchema = this.schema.getSchema();
if (refSchema == null) {
- ValidationMessage validationMessage = message().type(ValidatorTypeCode.RECURSIVE_REF.getValue())
- .code("internal.unresolvedRef").message("{0}: Reference {1} cannot be resolved")
+ ValidationMessage validationMessage = message().keyword(ValidatorTypeCode.RECURSIVE_REF.getValue())
+ .messageKey("internal.unresolvedRef").message("{0}: Reference {1} cannot be resolved")
.instanceLocation(instanceLocation).evaluationPath(getEvaluationPath())
.arguments(schemaNode.asText()).build();
throw new InvalidSchemaRefException(validationMessage);
@@ -106,8 +106,8 @@ public void walk(ExecutionContext executionContext, JsonNode node, JsonNode root
// with the latest config. Reset the config.
JsonSchema refSchema = this.schema.getSchema();
if (refSchema == null) {
- ValidationMessage validationMessage = message().type(ValidatorTypeCode.RECURSIVE_REF.getValue())
- .code("internal.unresolvedRef").message("{0}: Reference {1} cannot be resolved")
+ ValidationMessage validationMessage = message().keyword(ValidatorTypeCode.RECURSIVE_REF.getValue())
+ .messageKey("internal.unresolvedRef").message("{0}: Reference {1} cannot be resolved")
.instanceLocation(instanceLocation).evaluationPath(getEvaluationPath())
.arguments(schemaNode.asText()).build();
throw new InvalidSchemaRefException(validationMessage);
diff --git a/src/main/java/com/networknt/schema/RefValidator.java b/src/main/java/com/networknt/schema/RefValidator.java
index c173f8140..8530de4d1 100644
--- a/src/main/java/com/networknt/schema/RefValidator.java
+++ b/src/main/java/com/networknt/schema/RefValidator.java
@@ -178,8 +178,8 @@ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode
debug(logger, executionContext, node, rootNode, instanceLocation);
JsonSchema refSchema = this.schema.getSchema();
if (refSchema == null) {
- ValidationMessage validationMessage = message().type(ValidatorTypeCode.REF.getValue())
- .code("internal.unresolvedRef").message("{0}: Reference {1} cannot be resolved")
+ ValidationMessage validationMessage = message().keyword(ValidatorTypeCode.REF.getValue())
+ .messageKey("internal.unresolvedRef").message("{0}: Reference {1} cannot be resolved")
.instanceLocation(instanceLocation).evaluationPath(getEvaluationPath())
.arguments(schemaNode.asText()).build();
throw new InvalidSchemaRefException(validationMessage);
@@ -195,8 +195,8 @@ public void walk(ExecutionContext executionContext, JsonNode node, JsonNode root
// with the latest config. Reset the config.
JsonSchema refSchema = this.schema.getSchema();
if (refSchema == null) {
- ValidationMessage validationMessage = message().type(ValidatorTypeCode.REF.getValue())
- .code("internal.unresolvedRef").message("{0}: Reference {1} cannot be resolved")
+ ValidationMessage validationMessage = message().keyword(ValidatorTypeCode.REF.getValue())
+ .messageKey("internal.unresolvedRef").message("{0}: Reference {1} cannot be resolved")
.instanceLocation(instanceLocation).evaluationPath(getEvaluationPath())
.arguments(schemaNode.asText()).build();
throw new InvalidSchemaRefException(validationMessage);
diff --git a/src/main/java/com/networknt/schema/UnionTypeValidator.java b/src/main/java/com/networknt/schema/UnionTypeValidator.java
index 2a271b258..4a02268c1 100644
--- a/src/main/java/com/networknt/schema/UnionTypeValidator.java
+++ b/src/main/java/com/networknt/schema/UnionTypeValidator.java
@@ -96,7 +96,7 @@ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode
if (!valid) {
executionContext.addError(message().instanceNode(node).instanceLocation(instanceLocation)
- .type("type")
+ .keyword("type")
.locale(executionContext.getExecutionConfig().getLocale())
.failFast(executionContext.isFailFast()).arguments(nodeType.toString(), error)
.build());
diff --git a/src/main/java/com/networknt/schema/ValidationMessage.java b/src/main/java/com/networknt/schema/ValidationMessage.java
index 013d8e257..454570db3 100644
--- a/src/main/java/com/networknt/schema/ValidationMessage.java
+++ b/src/main/java/com/networknt/schema/ValidationMessage.java
@@ -29,6 +29,7 @@
import java.text.MessageFormat;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;
@@ -44,15 +45,13 @@
"messageKey", "arguments", "details" })
@JsonInclude(Include.NON_NULL)
public class ValidationMessage {
- private final String type;
- private final String code;
+ private final String keyword;
@JsonSerialize(using = ToStringSerializer.class)
private final JsonNodePath evaluationPath;
@JsonSerialize(using = ToStringSerializer.class)
private final SchemaLocation schemaLocation;
@JsonSerialize(using = ToStringSerializer.class)
private final JsonNodePath instanceLocation;
- private final String property;
private final Object[] arguments;
private final String messageKey;
private final Supplier messageSupplier;
@@ -60,16 +59,14 @@ public class ValidationMessage {
private final JsonNode instanceNode;
private final JsonNode schemaNode;
- ValidationMessage(String type, String code, JsonNodePath evaluationPath, SchemaLocation schemaLocation,
- JsonNodePath instanceLocation, String property, Object[] arguments, Map details,
+ ValidationMessage(String keyword, JsonNodePath evaluationPath, SchemaLocation schemaLocation,
+ JsonNodePath instanceLocation, Object[] arguments, Map details,
String messageKey, Supplier messageSupplier, JsonNode instanceNode, JsonNode schemaNode) {
super();
- this.type = type;
- this.code = code;
+ this.keyword = keyword;
this.instanceLocation = instanceLocation;
this.schemaLocation = schemaLocation;
this.evaluationPath = evaluationPath;
- this.property = property;
this.arguments = arguments;
this.details = details;
this.messageKey = messageKey;
@@ -78,10 +75,6 @@ public class ValidationMessage {
this.schemaNode = schemaNode;
}
- public String getCode() {
- return code;
- }
-
/**
* The instance location is the location of the JSON value within the root
* instance being validated.
@@ -147,7 +140,17 @@ public JsonNode getSchemaNode() {
* @return the property name
*/
public String getProperty() {
- return property;
+ if (details == null) {
+ return null;
+ }
+ return (String) getDetails().get("property");
+ }
+
+ public Integer getIndex() {
+ if (details == null) {
+ return null;
+ }
+ return (Integer) getDetails().get("index");
}
public Object[] getArguments() {
@@ -209,8 +212,7 @@ public boolean equals(Object o) {
ValidationMessage that = (ValidationMessage) o;
- if (type != null ? !type.equals(that.type) : that.type != null) return false;
- if (code != null ? !code.equals(that.code) : that.code != null) return false;
+ if (keyword != null ? !keyword.equals(that.keyword) : that.keyword != null) return false;
if (instanceLocation != null ? !instanceLocation.equals(that.instanceLocation) : that.instanceLocation != null) return false;
if (evaluationPath != null ? !evaluationPath.equals(that.evaluationPath) : that.evaluationPath != null) return false;
if (details != null ? !details.equals(that.details) : that.details != null) return false;
@@ -220,8 +222,7 @@ public boolean equals(Object o) {
@Override
public int hashCode() {
- int result = type != null ? type.hashCode() : 0;
- result = 31 * result + (code != null ? code.hashCode() : 0);
+ int result = keyword != null ? keyword.hashCode() : 0;
result = 31 * result + (instanceLocation != null ? instanceLocation.hashCode() : 0);
result = 31 * result + (evaluationPath != null ? evaluationPath.hashCode() : 0);
result = 31 * result + (details != null ? details.hashCode() : 0);
@@ -230,8 +231,8 @@ public int hashCode() {
return result;
}
- public String getType() {
- return type;
+ public String getKeyword() {
+ return keyword;
}
public static Builder builder() {
@@ -248,12 +249,10 @@ public Builder self() {
public static abstract class BuilderSupport {
public abstract S self();
- protected String type;
- protected String code;
+ protected String keyword;
protected JsonNodePath evaluationPath;
protected SchemaLocation schemaLocation;
protected JsonNodePath instanceLocation;
- protected String property;
protected Object[] arguments;
protected Map details;
protected MessageFormat format;
@@ -264,16 +263,28 @@ public static abstract class BuilderSupport {
protected JsonNode instanceNode;
protected JsonNode schemaNode;
- public S type(String type) {
- this.type = type;
+ public S keyword(String keyword) {
+ this.keyword = keyword;
return self();
}
- public S code(String code) {
- this.code = code;
+ public S property(String properties) {
+ if (this.details == null) {
+ this.details = new HashMap<>();
+ }
+ this.details.put("property", properties);
+ return self();
+ }
+
+ public S index(Integer index) {
+ if (this.details == null) {
+ this.details = new HashMap<>();
+ }
+ this.details.put("index", index);
return self();
}
+
/**
* The instance location is the location of the JSON value within the root
* instance being validated.
@@ -313,11 +324,6 @@ public S evaluationPath(JsonNodePath evaluationPath) {
return self();
}
- public S property(String property) {
- this.property = property;
- return self();
- }
-
public S arguments(Object... arguments) {
this.arguments = arguments;
return self();
@@ -333,11 +339,6 @@ public S format(MessageFormat format) {
return self();
}
- @Deprecated
- public S customMessage(String message) {
- return message(message);
- }
-
/**
* Explicitly sets the message pattern to be used.
*
@@ -396,8 +397,8 @@ public ValidationMessage build() {
return formatter.format(getMessageArguments());
});
}
- return new ValidationMessage(type, code, evaluationPath, schemaLocation, instanceLocation,
- property, arguments, details, messageKey, messageSupplier, this.instanceNode, this.schemaNode);
+ return new ValidationMessage(keyword, evaluationPath, schemaLocation, instanceLocation,
+ arguments, details, messageKey, messageSupplier, this.instanceNode, this.schemaNode);
}
protected Object[] getMessageArguments() {
@@ -409,12 +410,8 @@ protected Object[] getMessageArguments() {
return objs;
}
- protected String getType() {
- return type;
- }
-
- protected String getCode() {
- return code;
+ protected String getKeyword() {
+ return keyword;
}
protected JsonNodePath getEvaluationPath() {
@@ -429,10 +426,6 @@ protected JsonNodePath getInstanceLocation() {
return instanceLocation;
}
- protected String getProperty() {
- return property;
- }
-
protected Object[] getArguments() {
return arguments;
}
diff --git a/src/main/java/com/networknt/schema/ValidatorTypeCode.java b/src/main/java/com/networknt/schema/ValidatorTypeCode.java
index 458efc762..691f0fc9b 100644
--- a/src/main/java/com/networknt/schema/ValidatorTypeCode.java
+++ b/src/main/java/com/networknt/schema/ValidatorTypeCode.java
@@ -57,62 +57,62 @@ EnumSet getVersions() {
}
}
-public enum ValidatorTypeCode implements Keyword, ErrorMessageType {
- ADDITIONAL_PROPERTIES("additionalProperties", "1001", AdditionalPropertiesValidator::new, VersionCode.MaxV7),
- ALL_OF("allOf", "1002", AllOfValidator::new, VersionCode.MaxV7),
- ANY_OF("anyOf", "1003", AnyOfValidator::new, VersionCode.MaxV7),
- CONST("const", "1042", ConstValidator::new, VersionCode.MinV6MaxV7),
- CONTAINS("contains", "1043", ContainsValidator::new, VersionCode.MinV6MaxV7),
- CONTENT_ENCODING("contentEncoding", "1052", ContentEncodingValidator::new, VersionCode.V7),
- CONTENT_MEDIA_TYPE("contentMediaType", "1053", ContentMediaTypeValidator::new, VersionCode.V7),
- DEPENDENCIES("dependencies", "1007", DependenciesValidator::new, VersionCode.AllVersions),
- DEPENDENT_REQUIRED("dependentRequired", "1045", DependentRequired::new, VersionCode.None),
- DEPENDENT_SCHEMAS("dependentSchemas", "1046", DependentSchemas::new, VersionCode.None),
- DISCRIMINATOR("discriminator", "2001", DiscriminatorValidator::new, VersionCode.None),
- DYNAMIC_REF("$dynamicRef", "1051", DynamicRefValidator::new, VersionCode.None),
- ENUM("enum", "1008", EnumValidator::new, VersionCode.MaxV7),
- EXCLUSIVE_MAXIMUM("exclusiveMaximum", "1038", ExclusiveMaximumValidator::new, VersionCode.MinV6MaxV7),
- EXCLUSIVE_MINIMUM("exclusiveMinimum", "1039", ExclusiveMinimumValidator::new, VersionCode.MinV6MaxV7),
- FALSE("false", "1041", FalseValidator::new, VersionCode.MinV6),
- FORMAT("format", "1009", null, VersionCode.MaxV7) {
+public enum ValidatorTypeCode implements Keyword {
+ ADDITIONAL_PROPERTIES("additionalProperties", AdditionalPropertiesValidator::new, VersionCode.MaxV7),
+ ALL_OF("allOf", AllOfValidator::new, VersionCode.MaxV7),
+ ANY_OF("anyOf", AnyOfValidator::new, VersionCode.MaxV7),
+ CONST("const", ConstValidator::new, VersionCode.MinV6MaxV7),
+ CONTAINS("contains", ContainsValidator::new, VersionCode.MinV6MaxV7),
+ CONTENT_ENCODING("contentEncoding", ContentEncodingValidator::new, VersionCode.V7),
+ CONTENT_MEDIA_TYPE("contentMediaType", ContentMediaTypeValidator::new, VersionCode.V7),
+ DEPENDENCIES("dependencies", DependenciesValidator::new, VersionCode.AllVersions),
+ DEPENDENT_REQUIRED("dependentRequired", DependentRequired::new, VersionCode.None),
+ DEPENDENT_SCHEMAS("dependentSchemas", DependentSchemas::new, VersionCode.None),
+ DISCRIMINATOR("discriminator", DiscriminatorValidator::new, VersionCode.None),
+ DYNAMIC_REF("$dynamicRef", DynamicRefValidator::new, VersionCode.None),
+ ENUM("enum", EnumValidator::new, VersionCode.MaxV7),
+ EXCLUSIVE_MAXIMUM("exclusiveMaximum", ExclusiveMaximumValidator::new, VersionCode.MinV6MaxV7),
+ EXCLUSIVE_MINIMUM("exclusiveMinimum", ExclusiveMinimumValidator::new, VersionCode.MinV6MaxV7),
+ FALSE("false", FalseValidator::new, VersionCode.MinV6),
+ FORMAT("format", null, VersionCode.MaxV7) {
@Override public JsonValidator newValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) {
throw new UnsupportedOperationException("Use FormatKeyword instead");
}
},
- ID("id", "1036", null, VersionCode.AllVersions),
- IF_THEN_ELSE("if", "1037", IfValidator::new, VersionCode.V7),
- ITEMS_202012("items", "1010", ItemsValidator202012::new, VersionCode.None),
- ITEMS("items", "1010", ItemsValidator::new, VersionCode.MaxV7),
- MAX_CONTAINS("maxContains", "1006", MinMaxContainsValidator::new, VersionCode.None),
- MAX_ITEMS("maxItems", "1012", MaxItemsValidator::new, VersionCode.MaxV7),
- MAX_LENGTH("maxLength", "1013", MaxLengthValidator::new, VersionCode.MaxV7),
- MAX_PROPERTIES("maxProperties", "1014", MaxPropertiesValidator::new, VersionCode.MaxV7),
- MAXIMUM("maximum", "1011", MaximumValidator::new, VersionCode.MaxV7),
- MIN_CONTAINS("minContains", "1049", MinMaxContainsValidator::new, VersionCode.None),
- MIN_ITEMS("minItems", "1016", MinItemsValidator::new, VersionCode.MaxV7),
- MIN_LENGTH("minLength", "1017", MinLengthValidator::new, VersionCode.MaxV7),
- MIN_PROPERTIES("minProperties", "1018", MinPropertiesValidator::new, VersionCode.MaxV7),
- MINIMUM("minimum", "1015", MinimumValidator::new, VersionCode.MaxV7),
- MULTIPLE_OF("multipleOf", "1019", MultipleOfValidator::new, VersionCode.MaxV7),
- NOT_ALLOWED("notAllowed", "1033", NotAllowedValidator::new, VersionCode.AllVersions),
- NOT("not", "1020", NotValidator::new, VersionCode.MaxV7),
- ONE_OF("oneOf", "1022", OneOfValidator::new, VersionCode.MaxV7),
- PATTERN_PROPERTIES("patternProperties", "1024", PatternPropertiesValidator::new, VersionCode.MaxV7),
- PATTERN("pattern", "1023", PatternValidator::new, VersionCode.MaxV7),
- PREFIX_ITEMS("prefixItems", "1048", PrefixItemsValidator::new, VersionCode.None),
- PROPERTIES("properties", "1025", PropertiesValidator::new, VersionCode.MaxV7),
- PROPERTYNAMES("propertyNames", "1044", PropertyNamesValidator::new, VersionCode.MinV6MaxV7),
- READ_ONLY("readOnly", "1032", ReadOnlyValidator::new, VersionCode.V7),
- RECURSIVE_REF("$recursiveRef", "1050", RecursiveRefValidator::new, VersionCode.None),
- REF("$ref", "1026", RefValidator::new, VersionCode.MaxV7),
- REQUIRED("required", "1028", RequiredValidator::new, VersionCode.MaxV7),
- TRUE("true", "1040", TrueValidator::new, VersionCode.MinV6),
- TYPE("type", "1029", TypeValidator::new, VersionCode.MaxV7),
- UNEVALUATED_ITEMS("unevaluatedItems", "1021", UnevaluatedItemsValidator::new, VersionCode.None),
- UNEVALUATED_PROPERTIES("unevaluatedProperties","1047",UnevaluatedPropertiesValidator::new,VersionCode.None),
- UNION_TYPE("unionType", "1030", UnionTypeValidator::new, VersionCode.None),
- UNIQUE_ITEMS("uniqueItems", "1031", UniqueItemsValidator::new, VersionCode.MaxV7),
- WRITE_ONLY("writeOnly", "1027", WriteOnlyValidator::new, VersionCode.V7),
+ ID("id", null, VersionCode.AllVersions),
+ IF_THEN_ELSE("if", IfValidator::new, VersionCode.V7),
+ ITEMS_202012("items", ItemsValidator202012::new, VersionCode.None),
+ ITEMS("items", ItemsValidator::new, VersionCode.MaxV7),
+ MAX_CONTAINS("maxContains",MinMaxContainsValidator::new, VersionCode.None),
+ MAX_ITEMS("maxItems", MaxItemsValidator::new, VersionCode.MaxV7),
+ MAX_LENGTH("maxLength", MaxLengthValidator::new, VersionCode.MaxV7),
+ MAX_PROPERTIES("maxProperties", MaxPropertiesValidator::new, VersionCode.MaxV7),
+ MAXIMUM("maximum", MaximumValidator::new, VersionCode.MaxV7),
+ MIN_CONTAINS("minContains", MinMaxContainsValidator::new, VersionCode.None),
+ MIN_ITEMS("minItems", MinItemsValidator::new, VersionCode.MaxV7),
+ MIN_LENGTH("minLength", MinLengthValidator::new, VersionCode.MaxV7),
+ MIN_PROPERTIES("minProperties", MinPropertiesValidator::new, VersionCode.MaxV7),
+ MINIMUM("minimum", MinimumValidator::new, VersionCode.MaxV7),
+ MULTIPLE_OF("multipleOf", MultipleOfValidator::new, VersionCode.MaxV7),
+ NOT_ALLOWED("notAllowed", NotAllowedValidator::new, VersionCode.AllVersions),
+ NOT("not", NotValidator::new, VersionCode.MaxV7),
+ ONE_OF("oneOf", OneOfValidator::new, VersionCode.MaxV7),
+ PATTERN_PROPERTIES("patternProperties", PatternPropertiesValidator::new, VersionCode.MaxV7),
+ PATTERN("pattern", PatternValidator::new, VersionCode.MaxV7),
+ PREFIX_ITEMS("prefixItems", PrefixItemsValidator::new, VersionCode.None),
+ PROPERTIES("properties", PropertiesValidator::new, VersionCode.MaxV7),
+ PROPERTYNAMES("propertyNames", PropertyNamesValidator::new, VersionCode.MinV6MaxV7),
+ READ_ONLY("readOnly", ReadOnlyValidator::new, VersionCode.V7),
+ RECURSIVE_REF("$recursiveRef", RecursiveRefValidator::new, VersionCode.None),
+ REF("$ref", RefValidator::new, VersionCode.MaxV7),
+ REQUIRED("required", RequiredValidator::new, VersionCode.MaxV7),
+ TRUE("true", TrueValidator::new, VersionCode.MinV6),
+ TYPE("type", TypeValidator::new, VersionCode.MaxV7),
+ UNEVALUATED_ITEMS("unevaluatedItems", UnevaluatedItemsValidator::new, VersionCode.None),
+ UNEVALUATED_PROPERTIES("unevaluatedProperties",UnevaluatedPropertiesValidator::new,VersionCode.None),
+ UNION_TYPE("unionType", UnionTypeValidator::new, VersionCode.None),
+ UNIQUE_ITEMS("uniqueItems", UniqueItemsValidator::new, VersionCode.MaxV7),
+ WRITE_ONLY("writeOnly", WriteOnlyValidator::new, VersionCode.V7),
;
private static final Map CONSTANTS = new HashMap<>();
@@ -124,13 +124,11 @@ public enum ValidatorTypeCode implements Keyword, ErrorMessageType {
}
private final String value;
- private final String errorCode;
private final ValidatorFactory validatorFactory;
private final VersionCode versionCode;
- ValidatorTypeCode(String value, String errorCode, ValidatorFactory validatorFactory, VersionCode versionCode) {
+ ValidatorTypeCode(String value, ValidatorFactory validatorFactory, VersionCode versionCode) {
this.value = value;
- this.errorCode = errorCode;
this.validatorFactory = validatorFactory;
this.versionCode = versionCode;
}
@@ -173,17 +171,7 @@ public String getValue() {
return this.value;
}
- @Override
- public String getErrorCode() {
- return this.errorCode;
- }
-
public VersionCode getVersionCode() {
return this.versionCode;
}
-
- @Override
- public String getErrorCodeValue() {
- return getValue();
- }
}
diff --git a/src/main/java/com/networknt/schema/format/BaseFormatJsonValidator.java b/src/main/java/com/networknt/schema/format/BaseFormatJsonValidator.java
index cda3a3be7..94813221a 100644
--- a/src/main/java/com/networknt/schema/format/BaseFormatJsonValidator.java
+++ b/src/main/java/com/networknt/schema/format/BaseFormatJsonValidator.java
@@ -4,7 +4,6 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.networknt.schema.BaseJsonValidator;
-import com.networknt.schema.ErrorMessageType;
import com.networknt.schema.ExecutionContext;
import com.networknt.schema.JsonNodePath;
import com.networknt.schema.JsonSchema;
@@ -17,9 +16,9 @@ public abstract class BaseFormatJsonValidator extends BaseJsonValidator {
protected final boolean assertionsEnabled;
public BaseFormatJsonValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath, JsonNode schemaNode,
- JsonSchema parentSchema, ErrorMessageType errorMessageType, Keyword keyword,
+ JsonSchema parentSchema, Keyword keyword,
ValidationContext validationContext) {
- super(schemaLocation, evaluationPath, schemaNode, parentSchema, errorMessageType, keyword, validationContext);
+ super(schemaLocation, evaluationPath, schemaNode, parentSchema, keyword, validationContext);
VersionFlag dialect = this.validationContext.getMetaSchema().getSpecification();
if (dialect == null || dialect.getVersionFlagValue() < VersionFlag.V201909.getVersionFlagValue()) {
assertionsEnabled = true;
diff --git a/src/main/java/com/networknt/schema/output/OutputUnitData.java b/src/main/java/com/networknt/schema/output/OutputUnitData.java
index 0f195f6e6..9398d4f53 100644
--- a/src/main/java/com/networknt/schema/output/OutputUnitData.java
+++ b/src/main/java/com/networknt/schema/output/OutputUnitData.java
@@ -88,9 +88,9 @@ public static OutputUnitData from(List validationMessages, Ex
assertionSchemaLocation, assertion.getInstanceLocation());
valid.put(key, false);
Map errorMap = errors.computeIfAbsent(key, k -> new LinkedHashMap<>());
- Object value = errorMap.get(assertion.getType());
+ Object value = errorMap.get(assertion.getKeyword());
if (value == null) {
- errorMap.put(assertion.getType(), assertionMapper.apply(assertion));
+ errorMap.put(assertion.getKeyword(), assertionMapper.apply(assertion));
} else {
// Existing error, make it into a list
if (value instanceof List) {
@@ -99,7 +99,7 @@ public static OutputUnitData from(List validationMessages, Ex
List