Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Unevaluated properties keyword. #534

Merged
merged 40 commits into from
Mar 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
3222389
Merge pull request #5 from networknt/master
prashanthjos Oct 21, 2020
1f92471
Merge pull request #6 from networknt/master
prashanthjos Dec 22, 2020
00a643d
Fixing walk issues for properties
prashanth-chaitanya Dec 22, 2020
161f59c
Correcting walk changes for few validators
prashanth-chaitanya Dec 24, 2020
32e8ab8
adding item walk listener
prashanth-chaitanya Dec 28, 2020
3e2e7cd
walk listener changes
prashanth-chaitanya Jan 13, 2021
51e45ba
walk listener changes
prashanth-chaitanya Jan 13, 2021
49f3300
Merging latest changes from networknt
prashanth-chaitanya Jan 15, 2021
67d36bf
Merge branch 'networknt-master'
prashanth-chaitanya Jan 15, 2021
9fdb3d0
merging changes from networknt
prashanth-chaitanya Feb 26, 2021
c27e1c9
merging changes from networknt
prashanth-chaitanya Feb 26, 2021
040d752
merging changes from networknt
prashanth-chaitanya Feb 26, 2021
4486cc4
Fixing issues with ValidatorState
prashanth-chaitanya Mar 12, 2021
cfbdf1c
changing the method name to getCollectorContext
prashanth-chaitanya Mar 15, 2021
d125abd
correcting the variable names and ValidatorState logic
prashanth-chaitanya Mar 15, 2021
abd45a8
correcting the documentation logic
prashanth-chaitanya Mar 15, 2021
2457a57
Merge branch 'master' of https://github.com/networknt/json-schema-val…
prashanth-chaitanya Mar 15, 2021
f0ca7d4
latest changes from networknt
prashanth-chaitanya Mar 15, 2021
34b8cf7
Fixing compilation issues in TypeFactoryTest
prashanth-chaitanya Mar 15, 2021
633c49b
Merge branch 'master' into master
prashanthjos Mar 17, 2021
beb6569
Fixing the minor brace issue
prashanth-chaitanya Mar 17, 2021
33d0deb
Merge pull request #10 from networknt/master
prashanthjos Mar 18, 2021
3a25c0b
Merge branch 'master' of https://github.com/networknt/json-schema-val…
prashanth-chaitanya Mar 18, 2021
895152c
Merge branch 'master' into networknt-master
prashanth-chaitanya Mar 18, 2021
bc374e5
Merge branch 'networknt-master'
prashanth-chaitanya Mar 18, 2021
a2f39a7
Merge branch 'networknt:master' into master
prashanthjos Aug 27, 2021
6a80389
Merge branch 'master' of https://github.com/prashanthjos/json-schema-…
prashanth-chaitanya Aug 27, 2021
5b59c56
Fixing the issue of propogating walk-listeners to child 's from paren…
prashanth-chaitanya Sep 2, 2021
d87b8ac
Adding tests for changing listeners
prashanth-chaitanya Sep 2, 2021
8b174df
Merge branch 'networknt:master' into master
prashanthjos Sep 27, 2021
833ffcd
Correcting the ref listeners config in walk event
prashanth-chaitanya Oct 4, 2021
1f37f0d
Correcting the ref listeners config in walk event
prashanth-chaitanya Oct 4, 2021
f92f3fc
Merge branch 'networknt:master' into master
prashanthjos Oct 26, 2021
88bbae2
Merge branch 'networknt:master' into master
prashanthjos Feb 22, 2022
110df9e
Adding unevaluated properties
prashanth-chaitanya Mar 8, 2022
556717e
Merge branch 'networknt:master' into master
prashanthjos Mar 8, 2022
15502f8
Fixing unevaluated properties
prashanth-chaitanya Mar 10, 2022
49cc72e
Fixing unevaluated properties
prashanth-chaitanya Mar 10, 2022
19bad7d
Fixing unevaluatedProperties issues
prashanth-chaitanya Mar 15, 2022
68f811a
Merge branch 'networknt:master' into master
prashanthjos Mar 17, 2022
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
72 changes: 44 additions & 28 deletions src/main/java/com/networknt/schema/AllOfValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,39 +52,55 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String

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

// As AllOf might contain multiple schemas take a backup of evaluatedProperties.
Object backupEvaluatedProperties = CollectorContext.getInstance().get(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES);

// Make the evaluatedProperties list empty.
CollectorContext.getInstance().add(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES, new ArrayList<>());

for (JsonSchema schema : schemas) {
errors.addAll(schema.validate(node, rootNode, at));

if (this.validationContext.getConfig().isOpenAPI3StyleDiscriminators()) {
final Iterator<JsonNode> arrayElements = schemaNode.elements();
while (arrayElements.hasNext()) {
final ObjectNode allOfEntry = (ObjectNode) arrayElements.next();
final JsonNode $ref = allOfEntry.get("$ref");
if (null != $ref) {
final ValidationContext.DiscriminatorContext currentDiscriminatorContext = validationContext
.getCurrentDiscriminatorContext();
if (null != currentDiscriminatorContext) {
final ObjectNode discriminator = currentDiscriminatorContext
.getDiscriminatorForPath(allOfEntry.get("$ref").asText());
if (null != discriminator) {
registerAndMergeDiscriminator(currentDiscriminatorContext, discriminator, parentSchema, at);
// now we have to check whether we have hit the right target
final String discriminatorPropertyName = discriminator.get("propertyName").asText();
final JsonNode discriminatorNode = node.get(discriminatorPropertyName);
final String discriminatorPropertyValue = discriminatorNode == null
? null
: discriminatorNode.textValue();

final JsonSchema jsonSchema = parentSchema;
checkDiscriminatorMatch(
currentDiscriminatorContext,
discriminator,
discriminatorPropertyValue,
jsonSchema);
try {
errors.addAll(schema.validate(node, rootNode, at));

if (this.validationContext.getConfig().isOpenAPI3StyleDiscriminators()) {
final Iterator<JsonNode> arrayElements = schemaNode.elements();
while (arrayElements.hasNext()) {
final ObjectNode allOfEntry = (ObjectNode) arrayElements.next();
final JsonNode $ref = allOfEntry.get("$ref");
if (null != $ref) {
final ValidationContext.DiscriminatorContext currentDiscriminatorContext = validationContext
.getCurrentDiscriminatorContext();
if (null != currentDiscriminatorContext) {
final ObjectNode discriminator = currentDiscriminatorContext
.getDiscriminatorForPath(allOfEntry.get("$ref").asText());
if (null != discriminator) {
registerAndMergeDiscriminator(currentDiscriminatorContext, discriminator, parentSchema, at);
// now we have to check whether we have hit the right target
final String discriminatorPropertyName = discriminator.get("propertyName").asText();
final JsonNode discriminatorNode = node.get(discriminatorPropertyName);
final String discriminatorPropertyValue = discriminatorNode == null
? null
: discriminatorNode.textValue();

final JsonSchema jsonSchema = parentSchema;
checkDiscriminatorMatch(
currentDiscriminatorContext,
discriminator,
discriminatorPropertyValue,
jsonSchema);
}
}
}
}
}
} finally {
if (errors.isEmpty()) {
List<String> backupEvaluatedPropertiesList = (backupEvaluatedProperties == null ? new ArrayList<>() : (List<String>) backupEvaluatedProperties);
backupEvaluatedPropertiesList.addAll((List<String>) CollectorContext.getInstance().get(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES));
CollectorContext.getInstance().add(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES, backupEvaluatedPropertiesList);
} else {
CollectorContext.getInstance().add(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES, backupEvaluatedProperties);
}
}
}

Expand Down
25 changes: 25 additions & 0 deletions src/main/java/com/networknt/schema/AnyOfValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
Set<ValidationMessage> allErrors = new LinkedHashSet<ValidationMessage>();
String typeValidatorName = "anyOf/type";

// As anyOf might contain multiple schemas take a backup of evaluatedProperties.
Object backupEvaluatedProperties = CollectorContext.getInstance().get(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES);

// Make the evaluatedProperties list empty.
CollectorContext.getInstance().add(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES, new ArrayList<>());

try {
for (JsonSchema schema : schemas) {
if (schema.getValidators().containsKey(typeValidatorName)) {
Expand All @@ -74,11 +80,18 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
}
Set<ValidationMessage> errors = schema.validate(node, rootNode, at);
if (errors.isEmpty() && (!this.validationContext.getConfig().isOpenAPI3StyleDiscriminators())) {
// Clear all errors.
allErrors.clear();
// return empty errors.
return errors;
} else if (this.validationContext.getConfig().isOpenAPI3StyleDiscriminators()) {
if (discriminatorContext.isDiscriminatorMatchFound()) {
if (!errors.isEmpty()) {
errors.add(buildValidationMessage(at, DISCRIMINATOR_REMARK));
allErrors.addAll(errors);
} else {
// Clear all errors.
allErrors.clear();
}
return errors;
}
Expand All @@ -95,10 +108,22 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
if (this.validationContext.getConfig().isOpenAPI3StyleDiscriminators()) {
validationContext.leaveDiscriminatorContextImmediately(at);
}
if (allErrors.isEmpty()) {
addEvaluatedProperties(backupEvaluatedProperties);
} else {
CollectorContext.getInstance().add(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES, backupEvaluatedProperties);
}
}
return Collections.unmodifiableSet(allErrors);
}

private void addEvaluatedProperties(Object backupEvaluatedProperties) {
// Add all the evaluated properties.
List<String> backupEvaluatedPropertiesList = (backupEvaluatedProperties == null ? new ArrayList<>() : (List<String>) backupEvaluatedProperties);
backupEvaluatedPropertiesList.addAll((List<String>) CollectorContext.getInstance().get(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES));
CollectorContext.getInstance().add(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES, backupEvaluatedPropertiesList);
}

@Override
public Set<ValidationMessage> walk(JsonNode node, JsonNode rootNode, String at, boolean shouldValidateSchema) {
ArrayList<Set<ValidationMessage>> results = new ArrayList<>(schemas.size());
Expand Down
72 changes: 62 additions & 10 deletions src/main/java/com/networknt/schema/IfValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,73 @@ public IfValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSche
public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
debug(logger, node, rootNode, at);

// As if-then-else might contain multiple schemas take a backup of evaluatedProperties.
Object backupEvaluatedProperties = CollectorContext.getInstance().get(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES);

Object ifEvaluatedProperties = null;

Object thenEvaluatedProperties = null;

Object elseEvaluatedProperties = null;

// Make the evaluatedProperties list empty.
CollectorContext.getInstance().add(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES, new ArrayList<>());

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

boolean ifConditionPassed;
try {
ifConditionPassed = ifSchema.validate(node, rootNode, at).isEmpty();
} catch (JsonSchemaException ex) {
// When failFast is enabled, validations are thrown as exceptions.
// An exception means the condition failed
ifConditionPassed = false;
}
try {
ifConditionPassed = ifSchema.validate(node, rootNode, at).isEmpty();
} catch (JsonSchemaException ex) {
// When failFast is enabled, validations are thrown as exceptions.
// An exception means the condition failed
ifConditionPassed = false;
}
// Evaluated Properties from if.
ifEvaluatedProperties = CollectorContext.getInstance().get(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES);

if (ifConditionPassed && thenSchema != null) {

// Make the evaluatedProperties list empty.
CollectorContext.getInstance().add(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES, new ArrayList<>());

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

// Collect the then evaluated properties.
thenEvaluatedProperties = CollectorContext.getInstance().get(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES);

if (ifConditionPassed && thenSchema != null) {
errors.addAll(thenSchema.validate(node, rootNode, at));
} else if (!ifConditionPassed && elseSchema != null) {
errors.addAll(elseSchema.validate(node, rootNode, at));
} else if (!ifConditionPassed && elseSchema != null) {

// Make the evaluatedProperties list empty.
CollectorContext.getInstance().add(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES, new ArrayList<>());

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

// Collect the else evaluated properties.
elseEvaluatedProperties = CollectorContext.getInstance().get(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES);
}

} finally {
if (errors.isEmpty()) {
List<String> backupEvaluatedPropertiesList = (backupEvaluatedProperties == null ? new ArrayList<>() : (List<String>) backupEvaluatedProperties);

if (ifEvaluatedProperties != null) {
backupEvaluatedPropertiesList.addAll((List<String>) ifEvaluatedProperties);
}

if (thenEvaluatedProperties != null) {
backupEvaluatedPropertiesList.addAll((List<String>) thenEvaluatedProperties);
}

if (elseEvaluatedProperties != null) {
backupEvaluatedPropertiesList.addAll((List<String>) elseEvaluatedProperties);
}

CollectorContext.getInstance().add(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES, backupEvaluatedPropertiesList);
} else {
CollectorContext.getInstance().add(UnEvaluatedPropertiesValidator.EVALUATED_PROPERTIES, backupEvaluatedProperties);
}
}

return Collections.unmodifiableSet(errors);
Expand Down
Loading