Skip to content

Commit c5d21a4

Browse files
fduttonFaron Dutton
andauthored
Ignores fail-fast when evaluating a member of an applicator (see https://json-schema.org/draft/2020-12/json-schema-core.html#name-applicators). (#816)
Resolves #209 Co-authored-by: Faron Dutton <[email protected]>
1 parent ad3ff30 commit c5d21a4

File tree

1 file changed

+58
-34
lines changed

1 file changed

+58
-34
lines changed

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

Lines changed: 58 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -69,57 +69,61 @@ public BaseJsonValidator(String schemaPath,
6969
}
7070

7171
public String getSchemaPath() {
72-
return schemaPath;
72+
return this.schemaPath;
7373
}
7474

7575
public JsonNode getSchemaNode() {
76-
return schemaNode;
76+
return this.schemaNode;
7777
}
7878

7979
public JsonSchema getParentSchema() {
80-
return parentSchema;
80+
return this.parentSchema;
8181
}
8282

8383
protected JsonSchema fetchSubSchemaNode(ValidationContext validationContext) {
84-
return suppressSubSchemaRetrieval ? null : obtainSubSchemaNode(schemaNode, validationContext);
84+
return this.suppressSubSchemaRetrieval ? null : obtainSubSchemaNode(this.schemaNode, validationContext);
8585
}
8686

8787
private static JsonSchema obtainSubSchemaNode(final JsonNode schemaNode, final ValidationContext validationContext) {
8888
final JsonNode node = schemaNode.get("id");
89+
8990
if (node == null) {
9091
return null;
9192
}
93+
9294
if (node.equals(schemaNode.get("$schema"))) {
9395
return null;
9496
}
9597

9698
final String text = node.textValue();
9799
if (text == null) {
98100
return null;
99-
} else {
100-
final URI uri;
101-
try {
102-
uri = validationContext.getURIFactory().create(node.textValue());
103-
} catch (IllegalArgumentException e) {
104-
return null;
105-
}
106-
return validationContext.getJsonSchemaFactory().getSchema(uri, validationContext.getConfig());
107101
}
102+
103+
final URI uri;
104+
try {
105+
uri = validationContext.getURIFactory().create(node.textValue());
106+
} catch (IllegalArgumentException e) {
107+
return null;
108+
}
109+
110+
return validationContext.getJsonSchemaFactory().getSchema(uri, validationContext.getConfig());
108111
}
109112

113+
@Override
110114
public Set<ValidationMessage> validate(JsonNode node) {
111115
return validate(node, node, atRoot());
112116
}
113117

114-
protected boolean equals(double n1, double n2) {
118+
protected static boolean equals(double n1, double n2) {
115119
return Math.abs(n1 - n2) < 1e-12;
116120
}
117121

118-
protected boolean greaterThan(double n1, double n2) {
122+
protected static boolean greaterThan(double n1, double n2) {
119123
return n1 - n2 > 1e-12;
120124
}
121125

122-
protected boolean lessThan(double n1, double n2) {
126+
protected static boolean lessThan(double n1, double n2) {
123127
return n1 - n2 < -1e-12;
124128
}
125129

@@ -128,52 +132,52 @@ protected void parseErrorCode(String errorCodeKey) {
128132
if (errorCodeNode != null && errorCodeNode.isTextual()) {
129133
String errorCodeText = errorCodeNode.asText();
130134
if (StringUtils.isNotBlank(errorCodeText)) {
131-
errorMessageType = CustomErrorMessageType.of(errorCodeText);
135+
this.errorMessageType = CustomErrorMessageType.of(errorCodeText);
132136
}
133137
}
134138
}
135139

136140
protected ValidationMessage buildValidationMessage(String at, String... arguments) {
137-
MessageFormat messageFormat = new MessageFormat(resourceBundle.getString(getErrorMessageType().getErrorCodeValue()));
138-
final ValidationMessage message = ValidationMessage.ofWithCustom(getValidatorType().getValue(), getErrorMessageType(), messageFormat, customMessage, at, schemaPath, arguments);
139-
if (failFast && !isPartOfOneOfMultipleType()) {
141+
MessageFormat messageFormat = new MessageFormat(this.resourceBundle.getString(getErrorMessageType().getErrorCodeValue()));
142+
final ValidationMessage message = ValidationMessage.ofWithCustom(getValidatorType().getValue(), getErrorMessageType(), messageFormat, this.customMessage, at, this.schemaPath, arguments);
143+
if (this.failFast && !isApplicator()) {
140144
throw new JsonSchemaException(message);
141145
}
142146
return message;
143147
}
144148

145149
protected ValidationMessage constructValidationMessage(String messageKey, String at, String... arguments) {
146-
MessageFormat messageFormat = new MessageFormat(resourceBundle.getString(messageKey));
150+
MessageFormat messageFormat = new MessageFormat(this.resourceBundle.getString(messageKey));
147151
final ValidationMessage message = new ValidationMessage.Builder()
148152
.code(getErrorMessageType().getErrorCode())
149153
.path(at)
150-
.schemaPath(schemaPath)
154+
.schemaPath(this.schemaPath)
151155
.arguments(arguments)
152156
.format(messageFormat)
153157
.type(getValidatorType().getValue())
154-
.customMessage(customMessage)
158+
.customMessage(this.customMessage)
155159
.build();
156-
if (failFast && !isPartOfOneOfMultipleType()) {
160+
if (this.failFast && !isApplicator()) {
157161
throw new JsonSchemaException(message);
158162
}
159163
return message;
160164
}
161165

162-
protected void debug(Logger logger, JsonNode node, JsonNode rootNode, String at) {
166+
protected static void debug(Logger logger, JsonNode node, JsonNode rootNode, String at) {
163167
logger.debug("validate( {}, {}, {})", node, rootNode, at);
164168
}
165169

166170
protected ValidatorTypeCode getValidatorType() {
167-
return validatorType;
171+
return this.validatorType;
168172
}
169173

170174
protected ErrorMessageType getErrorMessageType() {
171-
return errorMessageType;
175+
return this.errorMessageType;
172176
}
173177

174178
protected void updateValidatorType(ValidatorTypeCode validatorTypeCode) {
175-
validatorType = validatorTypeCode;
176-
errorMessageType = validatorTypeCode;
179+
this.validatorType = validatorTypeCode;
180+
this.errorMessageType = validatorTypeCode;
177181
parseErrorCode(validatorTypeCode.getErrorCodeKey());
178182
}
179183

@@ -191,7 +195,7 @@ protected String getNodeFieldType() {
191195
*/
192196
@Override
193197
public Set<ValidationMessage> walk(JsonNode node, JsonNode rootNode, String at, boolean shouldValidateSchema) {
194-
Set<ValidationMessage> validationMessages = new LinkedHashSet<ValidationMessage>();
198+
Set<ValidationMessage> validationMessages = new LinkedHashSet<>();
195199
if (shouldValidateSchema) {
196200
validationMessages = validate(node, rootNode, at);
197201
}
@@ -204,12 +208,32 @@ protected void preloadJsonSchemas(final Collection<JsonSchema> schemas) {
204208
}
205209
}
206210

211+
private boolean isApplicator() {
212+
return false
213+
|| isPartOfAnyOfMultipleType()
214+
|| isPartOfIfMultipleType()
215+
|| isPartOfNotMultipleType()
216+
|| isPartOfOneOfMultipleType();
217+
}
218+
219+
private boolean isPartOfAnyOfMultipleType() {
220+
return this.parentSchema.schemaPath.contains("/" + ValidatorTypeCode.ANY_OF.getValue() + "/");
221+
}
222+
223+
private boolean isPartOfIfMultipleType() {
224+
return this.parentSchema.schemaPath.contains("/" + ValidatorTypeCode.IF_THEN_ELSE.getValue() + "/");
225+
}
226+
227+
private boolean isPartOfNotMultipleType() {
228+
return this.parentSchema.schemaPath.contains("/" + ValidatorTypeCode.NOT.getValue() + "/");
229+
}
230+
207231
protected boolean isPartOfOneOfMultipleType() {
208-
return parentSchema.schemaPath.contains("/" + ValidatorTypeCode.ONE_OF.getValue() + "/");
232+
return this.parentSchema.schemaPath.contains("/" + ValidatorTypeCode.ONE_OF.getValue() + "/");
209233
}
210234

211235
protected PathType getPathType() {
212-
return pathType;
236+
return this.pathType;
213237
}
214238

215239
/**
@@ -218,7 +242,7 @@ protected PathType getPathType() {
218242
* @return The path.
219243
*/
220244
protected String atRoot() {
221-
return pathType.getRoot();
245+
return this.pathType.getRoot();
222246
}
223247

224248
/**
@@ -229,7 +253,7 @@ protected String atRoot() {
229253
* @return The complete path.
230254
*/
231255
protected String atPath(String currentPath, String token) {
232-
return pathType.append(currentPath, token);
256+
return this.pathType.append(currentPath, token);
233257
}
234258

235259
/**
@@ -240,7 +264,7 @@ protected String atPath(String currentPath, String token) {
240264
* @return The complete path.
241265
*/
242266
protected String atPath(String currentPath, int index) {
243-
return pathType.append(currentPath, index);
267+
return this.pathType.append(currentPath, index);
244268
}
245269

246270
/* ********************** START OF OpenAPI 3.0.x DISCRIMINATOR METHODS ********************************* */

0 commit comments

Comments
 (0)