Skip to content

Commit 2879ca3

Browse files
authored
Fix validation messages (#969)
* Generate translations and ensure encoded in ISO-8859-1 for Java 8 * Make how schema errors are reported consistent * Refactor oneOf * Make id error message clearer * Make messages more consistent * Fix * Fix * Fix * Fix
1 parent 7cda40e commit 2879ca3

File tree

76 files changed

+2275
-1476
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+2275
-1476
lines changed

src/main/java/com/networknt/schema/ConstValidator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
4141
if (schemaNode.decimalValue().compareTo(node.decimalValue()) != 0) {
4242
return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
4343
.locale(executionContext.getExecutionConfig().getLocale())
44-
.failFast(executionContext.isFailFast()).arguments(schemaNode.asText())
44+
.failFast(executionContext.isFailFast()).arguments(schemaNode.asText(), node.asText())
4545
.build());
4646
}
4747
} else if (!schemaNode.equals(node)) {

src/main/java/com/networknt/schema/JsonSchema.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ private static SchemaLocation resolve(SchemaLocation schemaLocation, JsonNode sc
8181
ValidationMessage validationMessage = ValidationMessage.builder()
8282
.code(ValidatorTypeCode.ID.getValue()).type(ValidatorTypeCode.ID.getValue())
8383
.instanceLocation(idSchemaLocation.getFragment())
84-
.arguments(schemaLocation.toString(), id)
84+
.arguments(id, validationContext.getMetaSchema().getIdKeyword(), idSchemaLocation)
8585
.schemaLocation(idSchemaLocation)
8686
.schemaNode(schemaNode)
8787
.messageFormatter(args -> validationContext.getConfig().getMessageSource().getMessage(

src/main/java/com/networknt/schema/MaxItemsValidator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
4646
if (node.size() > max) {
4747
return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
4848
.locale(executionContext.getExecutionConfig().getLocale())
49-
.failFast(executionContext.isFailFast()).arguments(max).build());
49+
.failFast(executionContext.isFailFast()).arguments(max, node.size()).build());
5050
}
5151
} else if (this.validationContext.getConfig().isTypeLoose()) {
5252
if (1 > max) {
5353
return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
5454
.locale(executionContext.getExecutionConfig().getLocale())
55-
.failFast(executionContext.isFailFast()).arguments(max).build());
55+
.failFast(executionContext.isFailFast()).arguments(max, 1).build());
5656
}
5757
}
5858

src/main/java/com/networknt/schema/OneOfValidator.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
5555
state.setComplexValidator(true);
5656

5757
int numberOfValidSchema = 0;
58+
int index = 0;
5859
SetView<ValidationMessage> childErrors = null;
60+
List<String> indexes = null;
5961

6062
// Save flag as nested schema evaluation shouldn't trigger fail fast
6163
boolean failFast = executionContext.isFailFast();
@@ -82,10 +84,15 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
8284
continue;
8385
}
8486
numberOfValidSchema++;
87+
if (indexes == null) {
88+
indexes = new ArrayList<>();
89+
}
90+
indexes.add(Integer.toString(index));
8591
}
86-
92+
8793
if (numberOfValidSchema > 1 && canShortCircuit()) {
8894
// short-circuit
95+
// note that the short circuit means that only 2 valid schemas are reported even if could be more
8996
break;
9097
}
9198

@@ -95,6 +102,7 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
95102
}
96103
childErrors.union(schemaErrors);
97104
}
105+
index++;
98106
}
99107
} finally {
100108
// Restore flag
@@ -105,9 +113,10 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
105113
// is not equal to 1.
106114
if (numberOfValidSchema != 1) {
107115
ValidationMessage message = message().instanceNode(node).instanceLocation(instanceLocation)
116+
.messageKey(numberOfValidSchema > 1 ? "oneOf.indexes" : "oneOf")
108117
.locale(executionContext.getExecutionConfig().getLocale())
109118
.failFast(executionContext.isFailFast())
110-
.arguments(Integer.toString(numberOfValidSchema)).build();
119+
.arguments(Integer.toString(numberOfValidSchema), numberOfValidSchema > 1 ? String.join(", ", indexes) : "").build();
111120
if (childErrors != null) {
112121
errors = new SetView<ValidationMessage>().union(Collections.singleton(message)).union(childErrors);
113122
} else {

src/main/java/com/networknt/schema/UnevaluatedItemsValidator.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -176,22 +176,22 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
176176
for (int x = validCount; x < node.size(); x++) {
177177
// The schema is either "false" or an object schema
178178
if (!containsEvaluated.contains(x)) {
179-
messages.addAll(
180-
this.schema.validate(executionContext, node.get(x), node, instanceLocation.append(x)));
179+
if (this.schemaNode.isBoolean() && this.schemaNode.booleanValue() == false) {
180+
// All fails as "unevaluatedItems: false"
181+
messages.add(message().instanceNode(node).instanceLocation(instanceLocation).arguments(x)
182+
.locale(executionContext.getExecutionConfig().getLocale())
183+
.failFast(executionContext.isFailFast()).build());
184+
} else {
185+
// Schema errors will be reported as is
186+
messages.addAll(this.schema.validate(executionContext, node.get(x), node,
187+
instanceLocation.append(x)));
188+
}
181189
evaluated = true;
182190
}
183191
}
184192
}
185193
if (messages.isEmpty()) {
186194
valid = true;
187-
} else {
188-
// Report these as unevaluated paths or not matching the unevaluatedItems schema
189-
messages = messages.stream()
190-
.map(m -> message().instanceNode(node).instanceLocation(instanceLocation)
191-
.locale(executionContext.getExecutionConfig().getLocale())
192-
.arguments(m.getInstanceLocation().getName(-1))
193-
.failFast(executionContext.isFailFast()).build())
194-
.collect(Collectors.toCollection(LinkedHashSet::new));
195195
}
196196
}
197197
// If the "unevaluatedItems" subschema is applied to any positions within the

src/main/java/com/networknt/schema/UnevaluatedPropertiesValidator.java

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,11 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
119119
evaluatedProperties.add(fieldName);
120120
if (this.schemaNode.isBoolean() && this.schemaNode.booleanValue() == false) {
121121
// All fails as "unevaluatedProperties: false"
122-
messages.add(message().instanceNode(node).instanceLocation(instanceLocation.append(fieldName))
123-
.locale(executionContext.getExecutionConfig().getLocale())
122+
messages.add(message().instanceNode(node).instanceLocation(instanceLocation).property(fieldName)
123+
.arguments(fieldName).locale(executionContext.getExecutionConfig().getLocale())
124124
.failFast(executionContext.isFailFast()).build());
125125
} else {
126+
// Schema errors will be reported as is
126127
messages.addAll(this.schema.validate(executionContext, node.get(fieldName), node,
127128
instanceLocation.append(fieldName)));
128129
}
@@ -131,17 +132,6 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
131132
} finally {
132133
executionContext.setFailFast(failFast); // restore flag
133134
}
134-
if (!messages.isEmpty()) {
135-
// Report these as unevaluated paths or not matching the unevaluatedProperties
136-
// schema
137-
messages = messages.stream()
138-
.map(m -> message().instanceNode(node).instanceLocation(instanceLocation)
139-
.locale(executionContext.getExecutionConfig().getLocale())
140-
.arguments(m.getInstanceLocation().getName(-1))
141-
.property(m.getInstanceLocation().getName(-1))
142-
.failFast(executionContext.isFailFast()).build())
143-
.collect(Collectors.toCollection(LinkedHashSet::new));
144-
}
145135
executionContext.getAnnotations()
146136
.put(JsonNodeAnnotation.builder().instanceLocation(instanceLocation).evaluationPath(this.evaluationPath)
147137
.schemaLocation(this.schemaLocation).keyword(getKeyword()).value(evaluatedProperties).build());

src/main/java/com/networknt/schema/ValidatorTypeCode.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ enum VersionCode {
4444
private final EnumSet<VersionFlag> versions;
4545

4646
VersionCode(SpecVersion.VersionFlag[] versionFlags) {
47-
this.versions = EnumSet.noneOf(VersionFlag.class);
47+
this.versions = EnumSet.noneOf(VersionFlag.class);
4848
for (VersionFlag flag: versionFlags) {
49-
this.versions.add(flag);
49+
this.versions.add(flag);
5050
}
5151
}
5252

@@ -63,12 +63,10 @@ public enum ValidatorTypeCode implements Keyword, ErrorMessageType {
6363
CONTAINS("contains", "1043", ContainsValidator::new, VersionCode.MinV6),
6464
CONTENT_ENCODING("contentEncoding", "1052", ContentEncodingValidator::new, VersionCode.V7),
6565
CONTENT_MEDIA_TYPE("contentMediaType", "1053", ContentMediaTypeValidator::new, VersionCode.V7),
66-
CROSS_EDITS("crossEdits", "1004", null, VersionCode.AllVersions),
6766
DEPENDENCIES("dependencies", "1007", DependenciesValidator::new, VersionCode.AllVersions),
6867
DEPENDENT_REQUIRED("dependentRequired", "1045", DependentRequired::new, VersionCode.MinV201909),
6968
DEPENDENT_SCHEMAS("dependentSchemas", "1046", DependentSchemas::new, VersionCode.MinV201909),
7069
DYNAMIC_REF("$dynamicRef", "1051", DynamicRefValidator::new, VersionCode.MinV202012),
71-
EDITS("edits", "1005", null, VersionCode.AllVersions),
7270
ENUM("enum", "1008", EnumValidator::new, VersionCode.AllVersions),
7371
EXCLUSIVE_MAXIMUM("exclusiveMaximum", "1038", ExclusiveMaximumValidator::new, VersionCode.MinV6),
7472
EXCLUSIVE_MINIMUM("exclusiveMinimum", "1039", ExclusiveMinimumValidator::new, VersionCode.MinV6),
@@ -111,7 +109,6 @@ public enum ValidatorTypeCode implements Keyword, ErrorMessageType {
111109
UNEVALUATED_PROPERTIES("unevaluatedProperties","1047",UnevaluatedPropertiesValidator::new,VersionCode.MinV201909),
112110
UNION_TYPE("unionType", "1030", UnionTypeValidator::new, VersionCode.AllVersions),
113111
UNIQUE_ITEMS("uniqueItems", "1031", UniqueItemsValidator::new, VersionCode.AllVersions),
114-
UUID("uuid", "1035", null, VersionCode.AllVersions),
115112
WRITE_ONLY("writeOnly", "1027", WriteOnlyValidator::new, VersionCode.MinV7),
116113
;
117114

src/main/java/com/networknt/schema/i18n/Locales.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ public class Locales {
3030
/**
3131
* The list of locale resource bundles.
3232
*/
33-
public static final String[] SUPPORTED_LANGUAGE_TAGS = new String[] { "ar-EG", "cs-CZ", "da-DK", "de", "fa-IR",
34-
"fi-FI", "fr-CA", "fr", "he-IL", "hr-HR", "hu-HU", "it", "ja-JP", "ko-KR", "nb-NO", "nl-NL", "pl-PL",
35-
"pt-BR", "ro-RO", "ru-RU", "sk-SK", "sv-SE", "th-TH", "tr-TR", "uk-UA", "vi-VN", "zh-CN", "zh-TW" };
33+
public static final String[] SUPPORTED_LANGUAGE_TAGS = new String[] { "ar", "cs", "da", "de", "fa", "fi", "fr",
34+
"iw", "he", "hr", "hu", "it", "ja", "ko", "nb", "nl", "pl", "pt", "ro", "ru", "sk", "sv", "th", "tr", "uk",
35+
"vi", "zh-CN", "zh-TW" };
3636

3737
/**
3838
* The supported locales.

src/main/resources/jsv-messages.properties

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@ additionalItems = {0}: index ''{1}'' is not defined in the schema and the schema
33
additionalProperties = {0}: property ''{1}'' is not defined in the schema and the schema does not allow additional properties
44
allOf = {0}: must be valid to all the schemas {1}
55
anyOf = {0}: must be valid to any of the schemas {1}
6-
const = {0}: must be the constant value {1}
6+
const = {0}: must be the constant value ''{1}''
77
contains = {0}: does not contain an element that passes these validations: {2}
8-
contains.max = {0}: must contain fewer than {1} element(s) that passes these validations: {2}
8+
contains.max = {0}: must contain at most {1} element(s) that passes these validations: {2}
99
contains.min = {0}: must contain at least {1} element(s) that passes these validations: {2}
10-
crossEdits = {0}: has an error with ''cross edits''
1110
dependencies = {0}: has an error with dependencies {1}
12-
dependentRequired = {0}: has a missing property "{1}" which is dependent required because "{2}" is present
11+
dependentRequired = {0}: has a missing property ''{1}'' which is dependent required because ''{2}'' is present
1312
dependentSchemas = {0}: has an error with dependentSchemas {1}
14-
edits = {0}: has an error with ''edits''
1513
enum = {0}: does not have a value in the enumeration {1}
1614
exclusiveMaximum = {0}: must have an exclusive maximum value of {1}
1715
exclusiveMinimum = {0}: must have an exclusive minimum value of {1}
@@ -37,23 +35,24 @@ format.hostname = {0}: does not match the {1} pattern must be a valid RFC 1123 h
3735
format.json-pointer = {0}: does not match the {1} pattern must be a valid RFC 6901 JSON Pointer
3836
format.relative-json-pointer = {0}: does not match the {1} pattern must be a valid IETF Relative JSON Pointer
3937
format.unknown = {0}: has an unknown format ''{1}''
40-
id = {0}: {1} is an invalid segment for URI {2}
38+
id = {0}: ''{1}'' is not a valid {2}
4139
items = {0}: index ''{1}'' is not defined in the schema and the schema does not allow additional items
4240
maxContains = {0}: must be a non-negative integer in {1}
43-
maxItems = {0}: must have a maximum of {1} items in the array
41+
maxItems = {0}: must have at most {1} items but found {2}
4442
maxLength = {0}: must be at most {1} characters long
45-
maxProperties = {0}: must only have a maximum of {1} properties
43+
maxProperties = {0}: must have at most {1} properties
4644
maximum = {0}: must have a maximum value of {1}
4745
minContains = {0}: must be a non-negative integer in {1}
4846
minContainsVsMaxContains = {0}: minContains must less than or equal to maxContains in {1}
49-
minItems = {0}: expected at least {1} items but found {2}
47+
minItems = {0}: must have at least {1} items but found {2}
5048
minLength = {0}: must be at least {1} characters long
51-
minProperties = {0}: must have a minimum of {1} properties
49+
minProperties = {0}: must have at least {1} properties
5250
minimum = {0}: must have a minimum value of {1}
5351
multipleOf = {0}: must be multiple of {1}
5452
not = {0}: must not be valid to the schema {1}
5553
notAllowed = {0}: property ''{1}'' is not allowed but it is in the data
5654
oneOf = {0}: must be valid to one and only one schema, but {1} are valid
55+
oneOf.indexes = {0}: must be valid to one and only one schema, but {1} are valid with indexes ''{2}''
5756
pattern = {0}: does not match the regex pattern {1}
5857
patternProperties = {0}: has some error with ''pattern properties''
5958
prefixItems = {0}: no validator found at this index
@@ -62,11 +61,10 @@ propertyNames = {0}: property ''{1}'' name is not valid: {2}
6261
readOnly = {0}: is a readonly field, it cannot be changed
6362
required = {0}: required property ''{1}'' not found
6463
type = {0}: {1} found, {2} expected
65-
unevaluatedItems = {0}: index ''{1}'' must not be unevaluated or must match unevaluated items schema
66-
unevaluatedProperties = {0}: property ''{1}'' must not be unevaluated
67-
unionType = {0}: {1} found, but {2} is required
68-
uniqueItems = {0}: the items in the array must be unique
69-
uuid = {0}: {1} is an invalid {2}
64+
unevaluatedItems = {0}: index ''{1}'' is not evaluated and the schema does not allow unevaluated items
65+
unevaluatedProperties = {0}: property ''{1}'' is not evaluated and the schema does not allow unevaluated properties
66+
unionType = {0}: {1} found, {2} expected
67+
uniqueItems = {0}: must have only unique items in the array
7068
writeOnly = {0}: is a write-only field, it cannot appear in the data
7169
contentEncoding = {0}: does not match content encoding {1}
72-
contentMediaType = {0}: is not a content media type
70+
contentMediaType = {0}: is not a content media type

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy