17
17
package com .networknt .schema ;
18
18
19
19
import com .fasterxml .jackson .databind .JsonNode ;
20
+ import com .networknt .schema .CollectorContext .Scope ;
21
+
20
22
import org .slf4j .Logger ;
21
23
import org .slf4j .LoggerFactory ;
22
24
@@ -61,64 +63,64 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
61
63
62
64
Set <ValidationMessage > allErrors = new LinkedHashSet <>();
63
65
64
- // As anyOf might contain multiple schemas take a backup of evaluated stuff.
65
- Collection <String > backupEvaluatedItems = collectorContext .getEvaluatedItems ();
66
- Collection <String > backupEvaluatedProperties = collectorContext .getEvaluatedProperties ();
67
-
68
- // Make the evaluated lists empty.
69
- collectorContext .resetEvaluatedItems ();
70
- collectorContext .resetEvaluatedProperties ();
71
-
66
+ Scope grandParentScope = collectorContext .enterDynamicScope ();
72
67
try {
73
68
int numberOfValidSubSchemas = 0 ;
74
- for (int i = 0 ; i < this .schemas .size (); ++i ) {
75
- JsonSchema schema = this .schemas .get (i );
76
- state .setMatchedNode (initialHasMatchedNode );
77
- Set <ValidationMessage > errors ;
78
-
79
- if (schema .hasTypeValidator ()) {
80
- TypeValidator typeValidator = schema .getTypeValidator ();
81
- //If schema has type validator and node type doesn't match with schemaType then ignore it
82
- //For union type, it is a must to call TypeValidator
83
- if (typeValidator .getSchemaType () != JsonType .UNION && !typeValidator .equalsToSchemaType (node )) {
84
- allErrors .add (buildValidationMessage (at , typeValidator .getSchemaType ().toString ()));
85
- continue ;
69
+ for (JsonSchema schema : this .schemas ) {
70
+ Set <ValidationMessage > errors = Collections .emptySet ();
71
+ Scope parentScope = collectorContext .enterDynamicScope ();
72
+ try {
73
+ state .setMatchedNode (initialHasMatchedNode );
74
+
75
+ if (schema .hasTypeValidator ()) {
76
+ TypeValidator typeValidator = schema .getTypeValidator ();
77
+ //If schema has type validator and node type doesn't match with schemaType then ignore it
78
+ //For union type, it is a must to call TypeValidator
79
+ if (typeValidator .getSchemaType () != JsonType .UNION && !typeValidator .equalsToSchemaType (node )) {
80
+ allErrors .add (buildValidationMessage (at , typeValidator .getSchemaType ().toString ()));
81
+ continue ;
82
+ }
86
83
}
87
- }
88
- if (!state .isWalkEnabled ()) {
89
- errors = schema .validate (node , rootNode , at );
90
- } else {
91
- errors = schema .walk (node , rootNode , at , true );
92
- }
93
-
94
- // check if any validation errors have occurred
95
- if (errors .isEmpty ()) {
96
- // check whether there are no errors HOWEVER we have validated the exact validator
97
- if (!state .hasMatchedNode ()) {
98
- continue ;
84
+ if (!state .isWalkEnabled ()) {
85
+ errors = schema .validate (node , rootNode , at );
86
+ } else {
87
+ errors = schema .walk (node , rootNode , at , true );
99
88
}
100
- // we found a valid subschema, so increase counter
101
- numberOfValidSubSchemas ++;
102
- }
103
89
104
- if (errors .isEmpty () && (!this .validationContext .getConfig ().isOpenAPI3StyleDiscriminators ())) {
105
- // Clear all errors.
106
- allErrors .clear ();
107
- // return empty errors.
108
- return errors ;
109
- } else if (this .validationContext .getConfig ().isOpenAPI3StyleDiscriminators ()) {
110
- if (this .discriminatorContext .isDiscriminatorMatchFound ()) {
111
- if (!errors .isEmpty ()) {
112
- errors .add (buildValidationMessage (at , DISCRIMINATOR_REMARK ));
113
- allErrors .addAll (errors );
114
- } else {
115
- // Clear all errors.
116
- allErrors .clear ();
90
+ // check if any validation errors have occurred
91
+ if (errors .isEmpty ()) {
92
+ // check whether there are no errors HOWEVER we have validated the exact validator
93
+ if (!state .hasMatchedNode ()) {
94
+ continue ;
117
95
}
96
+ // we found a valid subschema, so increase counter
97
+ numberOfValidSubSchemas ++;
98
+ }
99
+
100
+ if (errors .isEmpty () && (!this .validationContext .getConfig ().isOpenAPI3StyleDiscriminators ())) {
101
+ // Clear all errors.
102
+ allErrors .clear ();
103
+ // return empty errors.
118
104
return errors ;
105
+ } else if (this .validationContext .getConfig ().isOpenAPI3StyleDiscriminators ()) {
106
+ if (this .discriminatorContext .isDiscriminatorMatchFound ()) {
107
+ if (!errors .isEmpty ()) {
108
+ allErrors .addAll (errors );
109
+ allErrors .add (buildValidationMessage (at , DISCRIMINATOR_REMARK ));
110
+ } else {
111
+ // Clear all errors.
112
+ allErrors .clear ();
113
+ }
114
+ return errors ;
115
+ }
116
+ }
117
+ allErrors .addAll (errors );
118
+ } finally {
119
+ Scope scope = collectorContext .exitDynamicScope ();
120
+ if (errors .isEmpty ()) {
121
+ parentScope .mergeWith (scope );
119
122
}
120
123
}
121
- allErrors .addAll (errors );
122
124
}
123
125
124
126
// determine only those errors which are NOT of type "required" property missing
@@ -138,14 +140,12 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
138
140
if (this .validationContext .getConfig ().isOpenAPI3StyleDiscriminators ()) {
139
141
this .validationContext .leaveDiscriminatorContextImmediately (at );
140
142
}
143
+
144
+ Scope parentScope = collectorContext .exitDynamicScope ();
141
145
if (allErrors .isEmpty ()) {
142
146
state .setMatchedNode (true );
143
- } else {
144
- collectorContext .getEvaluatedItems ().clear ();
145
- collectorContext .getEvaluatedProperties ().clear ();
147
+ grandParentScope .mergeWith (parentScope );
146
148
}
147
- collectorContext .getEvaluatedItems ().addAll (backupEvaluatedItems );
148
- collectorContext .getEvaluatedProperties ().addAll (backupEvaluatedProperties );
149
149
}
150
150
return Collections .unmodifiableSet (allErrors );
151
151
}
0 commit comments