Skip to content

Commit 6a2255f

Browse files
$ref caching issue (networknt#443)
* Fixing walk issues for properties * Correcting walk changes for few validators * adding item walk listener * walk listener changes * walk listener changes * merging changes from networknt * Fixing issues with ValidatorState * changing the method name to getCollectorContext * correcting the variable names and ValidatorState logic * correcting the documentation logic * Fixing compilation issues in TypeFactoryTest * Fixing the minor brace issue * Fixing the issue of propogating walk-listeners to child 's from parent schema * Adding tests for changing listeners Co-authored-by: Prashanth Josyula <prashanth.chaitanya@salesforce.com>
1 parent 8f9189b commit 6a2255f

29 files changed

+192
-83
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
5555
for (JsonSchema schema : schemas) {
5656
errors.addAll(schema.validate(node, rootNode, at));
5757

58-
if (config.isOpenAPI3StyleDiscriminators()) {
58+
if (this.validationContext.getConfig().isOpenAPI3StyleDiscriminators()) {
5959
final Iterator<JsonNode> arrayElements = schemaNode.elements();
6060
while (arrayElements.hasNext()) {
6161
final ObjectNode allOfEntry = (ObjectNode) arrayElements.next();

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ public AnyOfValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentS
3737
int size = schemaNode.size();
3838
for (int i = 0; i < size; i++) {
3939
schemas.add(new JsonSchema(validationContext,
40-
getValidatorType().getValue(),
41-
parentSchema.getCurrentUri(),
42-
schemaNode.get(i),
43-
parentSchema));
40+
getValidatorType().getValue(),
41+
parentSchema.getCurrentUri(),
42+
schemaNode.get(i),
43+
parentSchema));
4444
}
4545

46-
if (config.isOpenAPI3StyleDiscriminators()) {
46+
if (this.validationContext.getConfig().isOpenAPI3StyleDiscriminators()) {
4747
this.discriminatorContext = new ValidationContext.DiscriminatorContext();
4848
} else {
4949
this.discriminatorContext = null;
@@ -53,7 +53,7 @@ public AnyOfValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentS
5353
public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
5454
debug(logger, node, rootNode, at);
5555

56-
if (config.isOpenAPI3StyleDiscriminators()) {
56+
if (this.validationContext.getConfig().isOpenAPI3StyleDiscriminators()) {
5757
validationContext.enterDiscriminatorContext(this.discriminatorContext, at);
5858
}
5959

@@ -72,9 +72,9 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
7272
}
7373
}
7474
Set<ValidationMessage> errors = schema.validate(node, rootNode, at);
75-
if (errors.isEmpty() && !config.isOpenAPI3StyleDiscriminators()) {
75+
if (errors.isEmpty() && (!this.validationContext.getConfig().isOpenAPI3StyleDiscriminators())) {
7676
return errors;
77-
} else if (config.isOpenAPI3StyleDiscriminators()) {
77+
} else if (this.validationContext.getConfig().isOpenAPI3StyleDiscriminators()) {
7878
if (discriminatorContext.isDiscriminatorMatchFound()) {
7979
if (!errors.isEmpty()) {
8080
errors.add(buildValidationMessage(at, DISCRIMINATOR_REMARK));
@@ -85,13 +85,13 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
8585
allErrors.addAll(errors);
8686
}
8787

88-
if (config.isOpenAPI3StyleDiscriminators() && discriminatorContext.isActive()) {
89-
final Set<ValidationMessage> errors = new HashSet<ValidationMessage>();
90-
errors.add(buildValidationMessage(at, "based on the provided discriminator. No alternative could be chosen based on the discriminator property"));
91-
return Collections.unmodifiableSet(errors);
88+
if (this.validationContext.getConfig().isOpenAPI3StyleDiscriminators() && discriminatorContext.isActive()) {
89+
final Set<ValidationMessage> errors = new HashSet<ValidationMessage>();
90+
errors.add(buildValidationMessage(at, "based on the provided discriminator. No alternative could be chosen based on the discriminator property"));
91+
return Collections.unmodifiableSet(errors);
9292
}
9393
} finally {
94-
if (config.isOpenAPI3StyleDiscriminators()) {
94+
if (this.validationContext.getConfig().isOpenAPI3StyleDiscriminators()) {
9595
validationContext.leaveDiscriminatorContextImmediately(at);
9696
}
9797
}

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,13 @@ public abstract class BaseJsonValidator implements JsonValidator {
3636
private boolean suppressSubSchemaRetrieval;
3737
private ValidatorTypeCode validatorType;
3838
private ErrorMessageType errorMessageType;
39-
/**
40-
* SchemaValidatorsConfig can only get and set in validationContext
41-
*/
42-
protected SchemaValidatorsConfig config;
39+
4340
protected final boolean failFast;
4441

4542
public BaseJsonValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema,
4643
ValidatorTypeCode validatorType, ValidationContext validationContext) {
4744
this(schemaPath, schemaNode, parentSchema, validatorType, false,
4845
validationContext.getConfig() != null && validationContext.getConfig().isFailFast());
49-
this.config = validationContext.getConfig() == null ? new SchemaValidatorsConfig() : validationContext.getConfig();
5046
}
5147

5248
public BaseJsonValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema,

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
public class DateTimeValidator extends BaseJsonValidator implements JsonValidator {
3333
private static final Logger logger = LoggerFactory.getLogger(DateTimeValidator.class);
3434

35+
private final ValidationContext validationContext;
36+
3537
private final String formatName;
3638
private final String DATE = "date";
3739
private final String DATETIME = "date-time";
@@ -44,6 +46,7 @@ public class DateTimeValidator extends BaseJsonValidator implements JsonValidato
4446
public DateTimeValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext, String formatName) {
4547
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.DATETIME, validationContext);
4648
this.formatName = formatName;
49+
this.validationContext = validationContext;
4750
parseErrorCode(getValidatorType().getErrorCodeKey());
4851
}
4952

@@ -52,7 +55,7 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
5255

5356
Set<ValidationMessage> errors = new LinkedHashSet<ValidationMessage>();
5457

55-
JsonType nodeType = TypeFactory.getValueNodeType(node, super.config);
58+
JsonType nodeType = TypeFactory.getValueNodeType(node, this.validationContext.getConfig());
5659
if (nodeType != JsonType.STRING) {
5760
return errors;
5861
}

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@ public class EnumValidator extends BaseJsonValidator implements JsonValidator {
3232

3333
private final Set<JsonNode> nodes;
3434
private final String error;
35+
private final ValidationContext validationContext;
3536

3637
public EnumValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) {
3738
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.ENUM, validationContext);
38-
39+
this.validationContext = validationContext;
3940
if (schemaNode != null && schemaNode.isArray()) {
4041
nodes = new HashSet<JsonNode>();
4142
StringBuilder sb = new StringBuilder();
@@ -57,7 +58,7 @@ public EnumValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSc
5758
}
5859

5960
// check if the parent schema declares the fields as nullable
60-
if (config.isHandleNullableField()) {
61+
if (validationContext.getConfig().isHandleNullableField()) {
6162
JsonNode nullable = parentSchema.getSchemaNode().get("nullable");
6263
if (nullable != null && nullable.asBoolean()) {
6364
nodes.add(NullNode.getInstance());
@@ -83,7 +84,7 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
8384

8485
Set<ValidationMessage> errors = new LinkedHashSet<ValidationMessage>();
8586
if (node.isNumber()) node = DecimalNode.valueOf(node.decimalValue());
86-
if (!nodes.contains(node) && !(config.isTypeLoose() && isTypeLooseContainsInEnum(node))) {
87+
if (!nodes.contains(node) && !( this.validationContext.getConfig().isTypeLoose() && isTypeLooseContainsInEnum(node))) {
8788
errors.add(buildValidationMessage(at, error));
8889
}
8990

@@ -96,7 +97,7 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
9697
* @param node JsonNode to check
9798
*/
9899
private boolean isTypeLooseContainsInEnum(JsonNode node) {
99-
if (TypeFactory.getValueNodeType(node, super.config) == JsonType.STRING) {
100+
if (TypeFactory.getValueNodeType(node, this.validationContext.getConfig()) == JsonType.STRING) {
100101
String nodeText = node.textValue();
101102
for (JsonNode n : nodes) {
102103
String value = n.asText();

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ public class ExclusiveMaximumValidator extends BaseJsonValidator implements Json
3030

3131
private final ThresholdMixin typedMaximum;
3232

33+
private final ValidationContext validationContext;
34+
3335
public ExclusiveMaximumValidator(String schemaPath, final JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) {
3436
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.EXCLUSIVE_MAXIMUM, validationContext);
35-
37+
this.validationContext = validationContext;
3638
if (!schemaNode.isNumber()) {
3739
throw new JsonSchemaException("exclusiveMaximum value is not a number");
3840
}
@@ -99,7 +101,7 @@ public String thresholdValue() {
99101
public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
100102
debug(logger, node, rootNode, at);
101103

102-
if (!TypeValidator.isNumber(node, super.config)) {
104+
if (!TypeValidator.isNumber(node, validationContext.getConfig())) {
103105
// maximum only applies to numbers
104106
return Collections.emptySet();
105107
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@ public class ExclusiveMinimumValidator extends BaseJsonValidator implements Json
3434
*/
3535
private final ThresholdMixin typedMinimum;
3636

37+
private final ValidationContext validationContext;
38+
3739
public ExclusiveMinimumValidator(String schemaPath, final JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) {
3840
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.EXCLUSIVE_MINIMUM, validationContext);
39-
41+
this.validationContext = validationContext;
4042
if (!schemaNode.isNumber()) {
4143
throw new JsonSchemaException("exclusiveMinimum value is not a number");
4244
}
@@ -106,7 +108,7 @@ public String thresholdValue() {
106108
public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
107109
debug(logger, node, rootNode, at);
108110

109-
if (!TypeValidator.isNumber(node, super.config)) {
111+
if (!TypeValidator.isNumber(node, this.validationContext.getConfig())) {
110112
// minimum only applies to numbers
111113
return Collections.emptySet();
112114
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@ public class FormatValidator extends BaseJsonValidator implements JsonValidator
2929
private static final Logger logger = LoggerFactory.getLogger(FormatValidator.class);
3030

3131
private final Format format;
32+
private final ValidationContext validationContext;
3233

3334
public FormatValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext, Format format) {
3435
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.FORMAT, validationContext);
3536
this.format = format;
37+
this.validationContext = validationContext;
3638
parseErrorCode(getValidatorType().getErrorCodeKey());
3739
}
3840

@@ -41,7 +43,7 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
4143

4244
Set<ValidationMessage> errors = new LinkedHashSet<ValidationMessage>();
4345

44-
JsonType nodeType = TypeFactory.getValueNodeType(node, super.config);
46+
JsonType nodeType = TypeFactory.getValueNodeType(node, this.validationContext.getConfig());
4547
if (nodeType != JsonType.STRING) {
4648
return errors;
4749
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public class ItemsValidator extends BaseJsonValidator implements JsonValidator {
3333
private final List<JsonSchema> tupleSchema;
3434
private boolean additionalItems = true;
3535
private final JsonSchema additionalSchema;
36-
private final WalkListenerRunner arrayItemWalkListenerRunner;
36+
private WalkListenerRunner arrayItemWalkListenerRunner;
3737
private final ValidationContext validationContext;
3838

3939
public ItemsValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema,
@@ -61,7 +61,7 @@ public ItemsValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentS
6161
}
6262
}
6363
}
64-
arrayItemWalkListenerRunner = new DefaultItemWalkListenerRunner(config.getArrayItemWalkListeners());
64+
arrayItemWalkListenerRunner = new DefaultItemWalkListenerRunner(validationContext.getConfig().getArrayItemWalkListeners());
6565

6666
this.validationContext = validationContext;
6767

@@ -76,7 +76,7 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
7676

7777
Set<ValidationMessage> errors = new LinkedHashSet<ValidationMessage>();
7878

79-
if (!node.isArray() && !config.isTypeLoose()) {
79+
if (!node.isArray() && !this.validationContext.getConfig().isTypeLoose()) {
8080
// ignores non-arrays
8181
return errors;
8282
}

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

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.io.UnsupportedEncodingException;
2020
import java.net.URI;
2121
import java.net.URLDecoder;
22+
import java.sql.Ref;
2223
import java.util.Collections;
2324
import java.util.HashMap;
2425
import java.util.Iterator;
@@ -36,6 +37,8 @@
3637
import com.networknt.schema.walk.JsonSchemaWalker;
3738
import com.networknt.schema.walk.WalkListenerRunner;
3839

40+
import javax.xml.validation.Schema;
41+
3942
/**
4043
* This is the core of json constraint implementation. It parses json constraint
4144
* file and generates JsonValidators. The class is thread safe, once it is
@@ -46,7 +49,6 @@ public class JsonSchema extends BaseJsonValidator {
4649
private Map<String, JsonValidator> validators;
4750
private final String idKeyword;
4851
private final ValidationContext validationContext;
49-
private WalkListenerRunner keywordWalkListenerRunner;
5052
private boolean validatorsLoaded = false;
5153

5254
/**
@@ -80,13 +82,10 @@ private JsonSchema(ValidationContext validationContext, String schemaPath, URI c
8082
super(schemaPath, schemaNode, parent, null, suppressSubSchemaRetrieval,
8183
validationContext.getConfig() != null && validationContext.getConfig().isFailFast());
8284
this.validationContext = validationContext;
83-
this.config = validationContext.getConfig();
8485
this.idKeyword = validationContext.getMetaSchema().getIdKeyword();
8586
this.currentUri = this.combineCurrentUriWithIds(currentUri, schemaNode);
86-
if (config != null) {
87-
this.keywordWalkListenerRunner = new DefaultKeywordWalkListenerRunner(config.getKeywordWalkListenersMap());
88-
89-
if (config.isOpenAPI3StyleDiscriminators()) {
87+
if (validationContext.getConfig() != null) {
88+
if (validationContext.getConfig().isOpenAPI3StyleDiscriminators()) {
9089
ObjectNode discriminator = (ObjectNode) schemaNode.get("discriminator");
9190
if (null != discriminator && null != validationContext.getCurrentDiscriminatorContext()) {
9291
validationContext.getCurrentDiscriminatorContext().registerDiscriminator(schemaPath, discriminator);
@@ -95,6 +94,10 @@ private JsonSchema(ValidationContext validationContext, String schemaPath, URI c
9594
}
9695
}
9796

97+
ValidationContext getValidationContext() {
98+
return this.validationContext;
99+
}
100+
98101
private URI combineCurrentUriWithIds(URI currentUri, JsonNode schemaNode) {
99102
final String id = validationContext.resolveSchemaId(schemaNode);
100103
if (id == null) {
@@ -257,6 +260,7 @@ private JsonNode getMessageNode(JsonNode schemaNode, JsonSchema parentSchema) {
257260
/************************ START OF VALIDATE METHODS **********************************/
258261

259262
public Set<ValidationMessage> validate(JsonNode jsonNode, JsonNode rootNode, String at) {
263+
SchemaValidatorsConfig config = validationContext.getConfig();
260264
Set<ValidationMessage> errors = new LinkedHashSet<ValidationMessage>();
261265
// Get the collector context.
262266
getCollectorContext();
@@ -353,6 +357,7 @@ public ValidationResult walk(JsonNode node, boolean shouldValidateSchema) {
353357
@Override
354358
public Set<ValidationMessage> walk(JsonNode node, JsonNode rootNode, String at, boolean shouldValidateSchema) {
355359
Set<ValidationMessage> validationMessages = new LinkedHashSet<ValidationMessage>();
360+
WalkListenerRunner keywordWalkListenerRunner = new DefaultKeywordWalkListenerRunner(this.validationContext.getConfig().getKeywordWalkListenersMap());
356361
// Walk through all the JSONWalker's.
357362
for (Entry<String, JsonValidator> entry : getValidators().entrySet()) {
358363
JsonSchemaWalker jsonWalker = entry.getValue();
@@ -401,11 +406,12 @@ private void setValidatorState(boolean isWalkEnabled, boolean shouldValidateSche
401406
}
402407

403408
public CollectorContext getCollectorContext() {
409+
SchemaValidatorsConfig config = validationContext.getConfig();
404410
CollectorContext collectorContext = (CollectorContext) ThreadInfo
405411
.get(CollectorContext.COLLECTOR_CONTEXT_THREAD_LOCAL_KEY);
406412
if (collectorContext == null) {
407-
if (this.config != null && this.config.getCollectorContext() != null) {
408-
collectorContext = this.config.getCollectorContext();
413+
if (config != null && config.getCollectorContext() != null) {
414+
collectorContext = config.getCollectorContext();
409415
} else {
410416
collectorContext = new CollectorContext();
411417
}

0 commit comments

Comments
 (0)