Skip to content

Commit a9e8a49

Browse files
authored
Optimize hasAdjacentKeywordInEvaluationPath (#1092)
* Detect when instance location changes for adjacent keyword * Add test
1 parent 11f9af0 commit a9e8a49

File tree

4 files changed

+3347
-6
lines changed

4 files changed

+3347
-6
lines changed

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

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -391,21 +391,32 @@ public String toString() {
391391
* @return true if found
392392
*/
393393
protected boolean hasAdjacentKeywordInEvaluationPath(String keyword) {
394-
boolean hasValidator = false;
395394
JsonSchema schema = getEvaluationParentSchema();
395+
boolean checkInstance = false;
396+
boolean anchor = false;
397+
boolean stop = false;
396398
while (schema != null) {
397399
for (JsonValidator validator : schema.getValidators()) {
398400
if (keyword.equals(validator.getKeyword())) {
399-
hasValidator = true;
400-
break;
401+
return true;
402+
}
403+
if (checkInstance) {
404+
if ("properties".equals(validator.getKeyword()) || "items".equals(validator.getKeyword())) {
405+
stop = true;
406+
} else if ("$dynamicAnchor".equals(validator.getKeyword()) || "$recursiveAnchor".equals(validator.getKeyword())) {
407+
anchor = true;
408+
}
401409
}
402410
}
403-
if (hasValidator) {
404-
break;
411+
if (stop && !anchor) {
412+
// If there is a change in instance location then return false
413+
return false;
405414
}
406415
schema = schema.getEvaluationParentSchema();
416+
checkInstance = true;
417+
anchor = false;
407418
}
408-
return hasValidator;
419+
return false;
409420
}
410421

411422
@Override
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (c) 2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.networknt.schema;
17+
18+
import static org.junit.jupiter.api.Assertions.assertEquals;
19+
20+
import java.util.List;
21+
import java.util.stream.Collectors;
22+
23+
import org.junit.jupiter.api.Disabled;
24+
import org.junit.jupiter.api.Test;
25+
26+
import com.fasterxml.jackson.databind.JsonNode;
27+
import com.networknt.schema.SpecVersion.VersionFlag;
28+
import com.networknt.schema.serialization.JsonMapperFactory;
29+
30+
public class Issue1091Test {
31+
@Test
32+
@Disabled // Disabled as this test takes quite long to run for ci
33+
void testHasAdjacentKeywordInEvaluationPath() throws Exception {
34+
SchemaValidatorsConfig config = SchemaValidatorsConfig.builder().cacheRefs(false).build();
35+
36+
JsonSchema schema = JsonSchemaFactory.getInstance(VersionFlag.V4)
37+
.getSchema(SchemaLocation.of("classpath:schema/issue1091.json"), config);
38+
JsonNode node = JsonMapperFactory.getInstance()
39+
.readTree(Issue1091Test.class.getClassLoader().getResource("data/issue1091.json"));
40+
41+
List<String> messages = schema.validate(node)
42+
.stream()
43+
.map(ValidationMessage::getMessage)
44+
.collect(Collectors.toList());
45+
46+
assertEquals(0, messages.size());
47+
}
48+
}

0 commit comments

Comments
 (0)