Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,9 @@ public AdditionalPropertiesValidator(String schemaPath, JsonNode schemaNode, Jso
parseErrorCode(getValidatorType().getErrorCodeKey());
}

private void addToEvaluatedProperties(String propertyPath) {
CollectorContext.getInstance().getEvaluatedProperties().add(propertyPath);
}

public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
debug(logger, node, rootNode, at);
CollectorContext collectorContext = CollectorContext.getInstance();

Set<ValidationMessage> errors = new LinkedHashSet<ValidationMessage>();
if (!node.isObject()) {
Expand All @@ -80,7 +77,7 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
// if allowAdditionalProperties is true, add all the properties as evaluated.
if (allowAdditionalProperties) {
for (Iterator<String> it = node.fieldNames(); it.hasNext(); ) {
addToEvaluatedProperties(atPath(at, it.next()));
collectorContext.getEvaluatedProperties().add(atPath(at, it.next()));
}
}

Expand All @@ -104,7 +101,7 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
errors.add(buildValidationMessage(at, pname));
} else {
if (additionalPropertiesSchema != null) {
ValidatorState state = (ValidatorState) CollectorContext.getInstance().get(ValidatorState.VALIDATOR_STATE_KEY);
ValidatorState state = (ValidatorState) collectorContext.get(ValidatorState.VALIDATOR_STATE_KEY);
if (state != null && state.isWalkEnabled()) {
errors.addAll(additionalPropertiesSchema.walk(node.get(pname), rootNode, atPath(at, pname), state.isValidationEnabled()));
} else {
Expand Down
17 changes: 9 additions & 8 deletions src/main/java/com/networknt/schema/AllOfValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,24 @@ public AllOfValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentS

public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
debug(logger, node, rootNode, at);
CollectorContext collectorContext = CollectorContext.getInstance();

// get the Validator state object storing validation data
ValidatorState state = (ValidatorState) CollectorContext.getInstance().get(ValidatorState.VALIDATOR_STATE_KEY);
ValidatorState state = (ValidatorState) collectorContext.get(ValidatorState.VALIDATOR_STATE_KEY);

Set<ValidationMessage> childSchemaErrors = new LinkedHashSet<ValidationMessage>();

Set<String> newEvaluatedProperties = Collections.emptySet();
Collection<String> newEvaluatedProperties = Collections.emptyList();

for (JsonSchema schema : schemas) {
// As AllOf might contain multiple schemas take a backup of evaluatedProperties.
Set<String> backupEvaluatedProperties = CollectorContext.getInstance().copyEvaluatedProperties();
Collection<String> backupEvaluatedProperties = collectorContext.getEvaluatedProperties();

Set<ValidationMessage> localErrors = new HashSet<>();

try {
// Make the evaluatedProperties list empty.
CollectorContext.getInstance().getEvaluatedProperties().clear();
collectorContext.resetEvaluatedProperties();

if (!state.isWalkEnabled()) {
localErrors = schema.validate(node, rootNode, at);
Expand All @@ -71,7 +72,7 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String

// Keep Collecting total evaluated properties.
if (localErrors.isEmpty()) {
newEvaluatedProperties = CollectorContext.getInstance().copyEvaluatedProperties();
newEvaluatedProperties = collectorContext.getEvaluatedProperties();
}

if (this.validationContext.getConfig().isOpenAPI3StyleDiscriminators()) {
Expand Down Expand Up @@ -106,11 +107,11 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
}
}
} finally {
CollectorContext.getInstance().replaceEvaluatedProperties(backupEvaluatedProperties);
collectorContext.setEvaluatedProperties(backupEvaluatedProperties);
if (localErrors.isEmpty()) {
CollectorContext.getInstance().getEvaluatedProperties().addAll(newEvaluatedProperties);
collectorContext.getEvaluatedProperties().addAll(newEvaluatedProperties);
}
newEvaluatedProperties = Collections.emptySet();
newEvaluatedProperties = Collections.emptyList();
}
}

Expand Down
11 changes: 6 additions & 5 deletions src/main/java/com/networknt/schema/AnyOfValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ public AnyOfValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentS

public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
debug(logger, node, rootNode, at);
CollectorContext collectorContext = CollectorContext.getInstance();

// get the Validator state object storing validation data
ValidatorState state = (ValidatorState) CollectorContext.getInstance().get(ValidatorState.VALIDATOR_STATE_KEY);
ValidatorState state = (ValidatorState) collectorContext.get(ValidatorState.VALIDATOR_STATE_KEY);

if (this.validationContext.getConfig().isOpenAPI3StyleDiscriminators()) {
validationContext.enterDiscriminatorContext(this.discriminatorContext, at);
Expand All @@ -64,10 +65,10 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
Set<ValidationMessage> allErrors = new LinkedHashSet<>();

// As anyOf might contain multiple schemas take a backup of evaluatedProperties.
Set<String> backupEvaluatedProperties = CollectorContext.getInstance().copyEvaluatedProperties();
Collection<String> backupEvaluatedProperties = collectorContext.getEvaluatedProperties();

// Make the evaluatedProperties list empty.
CollectorContext.getInstance().getEvaluatedProperties().clear();
collectorContext.resetEvaluatedProperties();

try {
int numberOfValidSubSchemas = 0;
Expand Down Expand Up @@ -141,9 +142,9 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
if (allErrors.isEmpty()) {
state.setMatchedNode(true);
} else {
CollectorContext.getInstance().getEvaluatedProperties().clear();
collectorContext.getEvaluatedProperties().clear();
}
CollectorContext.getInstance().getEvaluatedProperties().addAll(backupEvaluatedProperties);
collectorContext.getEvaluatedProperties().addAll(backupEvaluatedProperties);
}
return Collections.unmodifiableSet(allErrors);
}
Expand Down
25 changes: 10 additions & 15 deletions src/main/java/com/networknt/schema/CollectorContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
*/
package com.networknt.schema;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
Expand Down Expand Up @@ -50,35 +50,30 @@ public static CollectorContext getInstance() {
/**
* Used to track which properties have been evaluated.
*/
private final Set<String> evaluatedProperties = new LinkedHashSet<>();
private Collection<String> evaluatedProperties = new ArrayList<>();

/**
* Identifies which properties have been evaluated.
*
* @return the set of evaluated properties (never null)
*/
public Set<String> getEvaluatedProperties() {
public Collection<String> getEvaluatedProperties() {
return evaluatedProperties;
}

/**
* Clones the properties that have been evaluated.
*
* @return the set of evaluated properties (never null)
* Set the properties that have been evaluated.
* @param paths the set of evaluated properties (may be null)
*/
public Set<String> copyEvaluatedProperties() {
return new LinkedHashSet<>(evaluatedProperties);
public void setEvaluatedProperties(Collection<String> paths) {
this.evaluatedProperties = null != paths ? paths : new ArrayList<>();
}

/**
* Replaces the properties that have been evaluated.
* @param paths the set of evaluated properties (may be null)
* Replaces the properties that have been evaluated with an empty collection.
*/
public void replaceEvaluatedProperties(Collection<String> paths) {
this.evaluatedProperties.clear();
if (null != paths) {
this.evaluatedProperties.addAll(paths);
}
public void resetEvaluatedProperties() {
this.evaluatedProperties = new ArrayList<>();
}

/**
Expand Down
29 changes: 15 additions & 14 deletions src/main/java/com/networknt/schema/IfValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,19 @@ public IfValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSche

public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
debug(logger, node, rootNode, at);
CollectorContext collectorContext = CollectorContext.getInstance();

// As if-then-else might contain multiple schemas take a backup of evaluatedProperties.
Set<String> backupEvaluatedProperties = CollectorContext.getInstance().copyEvaluatedProperties();
Collection<String> backupEvaluatedProperties = collectorContext.getEvaluatedProperties();

Set<String> ifEvaluatedProperties = Collections.emptySet();
Collection<String> ifEvaluatedProperties = Collections.emptyList();

Set<String> thenEvaluatedProperties = Collections.emptySet();
Collection<String> thenEvaluatedProperties = Collections.emptyList();

Set<String> elseEvaluatedProperties = Collections.emptySet();
Collection<String> elseEvaluatedProperties = Collections.emptyList();

// Make the evaluatedProperties list empty.
CollectorContext.getInstance().getEvaluatedProperties().clear();
collectorContext.resetEvaluatedProperties();

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

Expand All @@ -82,38 +83,38 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
ifConditionPassed = false;
}
// Evaluated Properties from if.
ifEvaluatedProperties = CollectorContext.getInstance().copyEvaluatedProperties();
ifEvaluatedProperties = collectorContext.getEvaluatedProperties();

if (ifConditionPassed && thenSchema != null) {

// Make the evaluatedProperties list empty.
CollectorContext.getInstance().getEvaluatedProperties().clear();
collectorContext.resetEvaluatedProperties();

errors.addAll(thenSchema.validate(node, rootNode, at));

// Collect the then evaluated properties.
thenEvaluatedProperties = CollectorContext.getInstance().copyEvaluatedProperties();
thenEvaluatedProperties = collectorContext.getEvaluatedProperties();

} else if (!ifConditionPassed && elseSchema != null) {

// Make the evaluatedProperties list empty.
CollectorContext.getInstance().getEvaluatedProperties().clear();
collectorContext.resetEvaluatedProperties();

errors.addAll(elseSchema.validate(node, rootNode, at));

// Collect the else evaluated properties.
elseEvaluatedProperties = CollectorContext.getInstance().copyEvaluatedProperties();
elseEvaluatedProperties = collectorContext.getEvaluatedProperties();
}

} finally {
CollectorContext.getInstance().replaceEvaluatedProperties(backupEvaluatedProperties);
collectorContext.setEvaluatedProperties(backupEvaluatedProperties);
if (errors.isEmpty()) {
// If the "if" keyword condition is passed then only add if properties as evaluated.
if (ifConditionPassed) {
CollectorContext.getInstance().getEvaluatedProperties().addAll(ifEvaluatedProperties);
collectorContext.getEvaluatedProperties().addAll(ifEvaluatedProperties);
}
CollectorContext.getInstance().getEvaluatedProperties().addAll(thenEvaluatedProperties);
CollectorContext.getInstance().getEvaluatedProperties().addAll(elseEvaluatedProperties);
collectorContext.getEvaluatedProperties().addAll(thenEvaluatedProperties);
collectorContext.getEvaluatedProperties().addAll(elseEvaluatedProperties);
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/main/java/com/networknt/schema/JsonSchema.java
Original file line number Diff line number Diff line change
Expand Up @@ -467,14 +467,16 @@ public Set<ValidationMessage> walk(JsonNode node, JsonNode rootNode, String at,
/************************ END OF WALK METHODS **********************************/

private void setValidatorState(boolean isWalkEnabled, boolean shouldValidateSchema) {
CollectorContext collectorContext = CollectorContext.getInstance();

// Get the Validator state object storing validation data
Object stateObj = CollectorContext.getInstance().get(ValidatorState.VALIDATOR_STATE_KEY);
Object stateObj = collectorContext.get(ValidatorState.VALIDATOR_STATE_KEY);
// if one has not been created, instantiate one
if (stateObj == null) {
ValidatorState state = new ValidatorState();
state.setWalkEnabled(isWalkEnabled);
state.setValidationEnabled(shouldValidateSchema);
CollectorContext.getInstance().add(ValidatorState.VALIDATOR_STATE_KEY, state);
collectorContext.add(ValidatorState.VALIDATOR_STATE_KEY, state);
}
}

Expand Down
9 changes: 5 additions & 4 deletions src/main/java/com/networknt/schema/NotValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ public NotValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSch
}

public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
CollectorContext collectorContext = CollectorContext.getInstance();
Set<ValidationMessage> errors = new HashSet<>();

//As not will contain a schema take a backup of evaluatedProperties.
Set<String> backupEvaluatedProperties = CollectorContext.getInstance().copyEvaluatedProperties();
Collection<String> backupEvaluatedProperties = collectorContext.getEvaluatedProperties();

// Make the evaluatedProperties list empty.
CollectorContext.getInstance().getEvaluatedProperties().clear();
collectorContext.resetEvaluatedProperties();

try {
debug(logger, node, rootNode, at);
Expand All @@ -52,9 +53,9 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
return Collections.emptySet();
} finally {
if (errors.isEmpty()) {
CollectorContext.getInstance().getEvaluatedProperties().addAll(backupEvaluatedProperties);
collectorContext.getEvaluatedProperties().addAll(backupEvaluatedProperties);
} else {
CollectorContext.getInstance().replaceEvaluatedProperties(backupEvaluatedProperties);
collectorContext.setEvaluatedProperties(backupEvaluatedProperties);
}
}
}
Expand Down
13 changes: 7 additions & 6 deletions src/main/java/com/networknt/schema/OneOfValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,18 @@ public OneOfValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentS

public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
Set<ValidationMessage> errors = new LinkedHashSet<>();
CollectorContext collectorContext = CollectorContext.getInstance();

// As oneOf might contain multiple schemas take a backup of evaluatedProperties.
Set<String> backupEvaluatedProperties = CollectorContext.getInstance().copyEvaluatedProperties();
Collection<String> backupEvaluatedProperties = collectorContext.getEvaluatedProperties();

// Make the evaluatedProperties list empty.
CollectorContext.getInstance().getEvaluatedProperties().clear();
collectorContext.resetEvaluatedProperties();

try {
debug(logger, node, rootNode, at);

ValidatorState state = (ValidatorState) CollectorContext.getInstance().get(ValidatorState.VALIDATOR_STATE_KEY);
ValidatorState state = (ValidatorState) collectorContext.get(ValidatorState.VALIDATOR_STATE_KEY);

// this is a complex validator, we set the flag to true
state.setComplexValidator(true);
Expand Down Expand Up @@ -79,7 +80,7 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String

// If the number of valid schema is greater than one, just reset the evaluated properties and break.
if (numberOfValidSchema > 1) {
CollectorContext.getInstance().getEvaluatedProperties().clear();
collectorContext.resetEvaluatedProperties();
break;
}

Expand All @@ -106,9 +107,9 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
return Collections.unmodifiableSet(errors);
} finally {
if (errors.isEmpty()) {
CollectorContext.getInstance().getEvaluatedProperties().addAll(backupEvaluatedProperties);
collectorContext.getEvaluatedProperties().addAll(backupEvaluatedProperties);
} else {
CollectorContext.getInstance().replaceEvaluatedProperties(backupEvaluatedProperties);
collectorContext.setEvaluatedProperties(backupEvaluatedProperties);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
for (Map.Entry<Pattern, JsonSchema> entry : schemas.entrySet()) {
Matcher m = entry.getKey().matcher(name);
if (m.find()) {
addToEvaluatedProperties(atPath(at, name));
CollectorContext.getInstance().getEvaluatedProperties().add(atPath(at, name));
errors.addAll(entry.getValue().validate(n, rootNode, atPath(at, name)));
}
}
Expand All @@ -70,8 +70,4 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
public void preloadJsonSchema() {
preloadJsonSchemas(schemas.values());
}

private void addToEvaluatedProperties(String propertyPath) {
CollectorContext.getInstance().getEvaluatedProperties().add(propertyPath);
}
}
Loading