Skip to content

Commit 48c3818

Browse files
committed
Checks
1 parent 7dce21f commit 48c3818

File tree

4 files changed

+68
-1
lines changed

4 files changed

+68
-1
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
import java.util.ArrayDeque;
2020
import java.util.ArrayList;
2121
import java.util.HashMap;
22+
import java.util.Iterator;
2223
import java.util.List;
2324
import java.util.Map;
2425
import java.util.function.Consumer;
2526

2627
import com.networknt.schema.annotation.Annotations;
2728
import com.networknt.schema.keyword.DiscriminatorState;
29+
import com.networknt.schema.keyword.KeywordValidator;
2830
import com.networknt.schema.path.NodePath;
2931
import com.networknt.schema.result.InstanceResults;
3032
import com.networknt.schema.walk.WalkConfig;
@@ -45,6 +47,7 @@ public class ExecutionContext {
4547

4648
final ArrayDeque<Object> evaluationPath = new ArrayDeque<>(64);
4749
final ArrayDeque<Schema> evaluationSchema = new ArrayDeque<>(64);
50+
final ArrayDeque<Object> evaluationSchemaPath = new ArrayDeque<>(64);
4851

4952
public ArrayDeque<Object> getEvaluationPath() {
5053
return evaluationPath;
@@ -53,6 +56,10 @@ public ArrayDeque<Object> getEvaluationPath() {
5356
public ArrayDeque<Schema> getEvaluationSchema() {
5457
return evaluationSchema;
5558
}
59+
60+
public ArrayDeque<Object> getEvaluationSchemaPath() {
61+
return evaluationSchemaPath;
62+
}
5663

5764
public Map<NodePath, DiscriminatorState> getDiscriminatorMapping() {
5865
return discriminatorMapping;

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,10 +723,12 @@ public void validate(ExecutionContext executionContext, JsonNode jsonNode, JsonN
723723
int currentErrors = executionContext.getErrors().size();
724724
for (KeywordValidator v : getValidators()) {
725725
executionContext.evaluationPath.addLast(v.getKeyword());
726+
executionContext.evaluationSchemaPath.addLast(v.getKeyword());
726727
try {
727728
v.validate(executionContext, jsonNode, rootNode, instanceLocation);
728729
} finally {
729730
executionContext.evaluationPath.removeLast();
731+
executionContext.evaluationSchemaPath.removeLast();
730732
}
731733
}
732734
if (executionContext.getErrors().size() > currentErrors) {

src/main/java/com/networknt/schema/keyword/AbstractKeywordValidator.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@
1616

1717
package com.networknt.schema.keyword;
1818

19+
import java.util.ArrayDeque;
20+
import java.util.Iterator;
1921
import java.util.function.Consumer;
2022

2123
import com.fasterxml.jackson.databind.JsonNode;
2224
import com.networknt.schema.ExecutionContext;
25+
import com.networknt.schema.Schema;
2326
import com.networknt.schema.SchemaLocation;
2427
import com.networknt.schema.annotation.Annotation;
28+
import com.networknt.schema.path.EvaluationPath;
2529
import com.networknt.schema.path.NodePath;
2630

2731
/**
@@ -122,4 +126,58 @@ protected void putAnnotation(ExecutionContext executionContext, Consumer<Annotat
122126
customizer.accept(builder);
123127
executionContext.getAnnotations().put(builder.build());
124128
}
129+
130+
131+
/**
132+
* Determines if the keyword exists adjacent in the evaluation path.
133+
* <p>
134+
* This does not check if the keyword exists in the current meta schema as this
135+
* can be a cross-draft case where the properties keyword is in a Draft 7 schema
136+
* and the unevaluatedProperties keyword is in an outer Draft 2020-12 schema.
137+
* <p>
138+
* The fact that the validator exists in the evaluation path implies that the
139+
* keyword was valid in whatever meta schema for that schema it was created for.
140+
*
141+
* @param keyword the keyword to check
142+
* @return true if found
143+
*/
144+
protected boolean hasAdjacentKeywordInEvaluationPath(ExecutionContext executionContext, String keyword) {
145+
Iterator<Object> evaluationSchemaPathIterator = executionContext.getEvaluationSchemaPath().descendingIterator();
146+
Iterator<Schema> evaluationSchemaIterator = executionContext.getEvaluationSchema().descendingIterator();
147+
148+
ArrayDeque<Object> current = executionContext.getEvaluationSchemaPath().clone();
149+
150+
// Skip the first as this is the path pointing to the current keyword eg. properties eg /$ref/properties
151+
// What is needed is the evaluationPath pointing to the current evaluationSchema eg /$ref
152+
if (evaluationSchemaPathIterator.hasNext()) {
153+
evaluationSchemaPathIterator.next();
154+
155+
current.removeLast();
156+
}
157+
158+
while (evaluationSchemaIterator.hasNext()) {
159+
Schema schema = evaluationSchemaIterator.next();
160+
for (KeywordValidator validator : schema.getValidators()) {
161+
if (keyword.equals(validator.getKeyword())) {
162+
return true;
163+
}
164+
}
165+
String newPath = new EvaluationPath(current).toString();
166+
String oldPath = schema.getEvaluationPath().toString();
167+
if (!oldPath.equals(newPath)) {
168+
System.out.println("OLD: "+oldPath);
169+
System.out.println("NEW: "+newPath);
170+
}
171+
172+
if (evaluationSchemaPathIterator.hasNext()) {
173+
Object evaluationPath = evaluationSchemaPathIterator.next();
174+
current.removeLast();
175+
if ("properties".equals(evaluationPath) || "items".equals(evaluationPath)) {
176+
// If there is a change in instance location then return false
177+
return false;
178+
}
179+
}
180+
}
181+
return false;
182+
}
125183
}

src/main/java/com/networknt/schema/keyword/PropertiesValidator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public void validate(ExecutionContext executionContext, JsonNode node, JsonNode
6565
protected void validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
6666
NodePath instanceLocation, boolean walk) {
6767

68-
68+
boolean c = hasAdjacentKeywordInEvaluationPath(executionContext, "unevaluatedProperties");
6969
Set<String> matchedInstancePropertyNames = null;
7070
boolean collectAnnotations = collectAnnotations() || collectAnnotations(executionContext);
7171
for (Entry<String, Schema> entry : this.schemas.entrySet()) {

0 commit comments

Comments
 (0)