@@ -106,55 +106,56 @@ protected void validate(ExecutionContext executionContext, JsonNode node, JsonNo
106106 numberOfValidSubSchemas ++;
107107 }
108108
109- if (errors .isEmpty () && (!this .schemaContext .isDiscriminatorKeywordEnabled ())
110- && canShortCircuit () && canShortCircuit ( executionContext )) {
109+ if (errors .isEmpty () && (!this .schemaContext .isDiscriminatorKeywordEnabled ()) && canShortCircuit ()
110+ && canShortCircuit (executionContext )) {
111111 // Successful so return only the existing errors, ie. no new errors
112112 executionContext .setErrors (existingErrors );
113113 return ;
114114 } else if (this .schemaContext .isDiscriminatorKeywordEnabled ()) {
115- JsonNode refNode = schema .getSchemaNode ().get ("$ref" );
116- DiscriminatorState state = executionContext .getDiscriminatorMapping ().get (instanceLocation );
117- boolean discriminatorMatchFound = false ;
118- if (refNode != null ) {
119- // Check if there is a match
120- String discriminatingValue = state .getDiscriminatingValue ();
121- if (discriminatingValue != null ) {
122- String ref = refNode .asText ();
123- if (state .isExplicitMapping () && ref .equals (discriminatingValue )) {
124- // Explicit matching
125- discriminatorMatchFound = true ;
126- state .setMatch (ref );
127- } else if (!state .isExplicitMapping () && ref .endsWith (discriminatingValue )) {
128- // Implicit matching
129- discriminatorMatchFound = true ;
130- state .setMatch (ref );
131- }
132- }
133- }
115+ JsonNode refNode = schema .getSchemaNode ().get ("$ref" );
116+ DiscriminatorState state = executionContext .getDiscriminatorMapping ().get (instanceLocation );
117+ boolean discriminatorMatchFound = false ;
118+ if (refNode != null ) {
119+ // Check if there is a match
120+ String discriminatingValue = state .getMappedSchema ();
121+ if (discriminatingValue != null ) {
122+ String ref = refNode .asText ();
123+ if (state .isExplicitMapping () && ref .equals (discriminatingValue )) {
124+ // Explicit matching
125+ discriminatorMatchFound = true ;
126+ state .setMatchedSchema (ref );
127+ } else if (!state .isExplicitMapping () && ref .endsWith (discriminatingValue )) {
128+ // Implicit matching
129+ discriminatorMatchFound = true ;
130+ state .setMatchedSchema (ref );
131+ }
132+ }
133+ }
134134 if (discriminatorMatchFound ) {
135- /*
136- * Note that discriminator cannot change the outcome of the evaluation but can be used to filter off
137- * any additional messages
138- */
139- if (!errors .isEmpty ()) {
140- /*
141- * This means that the discriminated value has errors and doesn't match so these errors
142- * are the only ones that will be reported *IF* there are no other schemas that successfully
143- * validate to meet the requirement of anyOf.
144- *
145- * If there are any successful schemas as per anyOf, all these errors will be discarded.
146- */
147- discriminatorErrors = new ArrayList <>(errors );
148- allErrors = null ; // This is no longer needed
149- }
135+ /*
136+ * Note that discriminator cannot change the outcome of the evaluation but can
137+ * be used to filter off any additional messages
138+ */
139+ if (!errors .isEmpty ()) {
140+ /*
141+ * This means that the discriminated value has errors and doesn't match so these
142+ * errors are the only ones that will be reported *IF* there are no other
143+ * schemas that successfully validate to meet the requirement of anyOf.
144+ *
145+ * If there are any successful schemas as per anyOf, all these errors will be
146+ * discarded.
147+ */
148+ discriminatorErrors = new ArrayList <>(errors );
149+ allErrors = null ; // This is no longer needed
150+ }
150151 }
151152 }
152-
153153 /*
154- * This adds all the errors for this schema to the list that contains all the errors for later reporting.
154+ * This adds all the errors for this schema to the list that contains all the
155+ * errors for later reporting.
155156 *
156- * There's no need to add these if there was a discriminator match with errors as only the discriminator
157- * errors will be reported if all the schemas fail.
157+ * There's no need to add these if there was a discriminator match with errors
158+ * as only the discriminator errors will be reported if all the schemas fail.
158159 */
159160 if (!errors .isEmpty () && discriminatorErrors == null ) {
160161 if (allErrors == null ) {
@@ -169,21 +170,28 @@ && canShortCircuit() && canShortCircuit(executionContext)) {
169170 }
170171
171172 if (this .schemaContext .isDiscriminatorKeywordEnabled ()) {
172- // https://spec.openapis.org/oas/v3.1.0#discriminator-object
173- // If the discriminator value does not match an implicit or explicit mapping, no schema can be determined and validation SHOULD fail. Mapping keys MUST be string values, but tooling MAY convert response values to strings for comparison.
174-
175- /*
176- * The only case where the discriminator can change the outcome of the result is if the discriminator value does not match an implicit or explicit mapping
177- */
178- DiscriminatorState state = executionContext .getDiscriminatorMapping ().get (instanceLocation );
179- if (state != null && state .getMatch () == null && state .getPropertyValue () != null ) {
180- // state.getPropertyValue() == null means there is no value at propertyName
181- existingErrors .add (error ().keyword ("discriminator" ).instanceNode (node ).instanceLocation (instanceLocation )
182- .locale (executionContext .getExecutionConfig ().getLocale ())
183- .arguments (
184- "based on the provided discriminator. No alternative could be chosen based on the discriminator property" )
185- .build ());
186- }
173+ /*
174+ * The only case where the discriminator can change the outcome of the result is
175+ * if the discriminator value does not match an implicit or explicit mapping
176+ */
177+ /*
178+ * If the discriminator value does not match an implicit or explicit mapping, no
179+ * schema can be determined and validation SHOULD fail. Mapping keys MUST be
180+ * string values, but tooling MAY convert response values to strings for
181+ * comparison.
182+ *
183+ * https://spec.openapis.org/oas/v3.1.0#discriminator-object
184+ */
185+ DiscriminatorState state = executionContext .getDiscriminatorMapping ().get (instanceLocation );
186+ if (state != null && state .getMatchedSchema () == null && state .getDiscriminatingValue () != null ) {
187+ // state.getPropertyValue() == null means there is no value at propertyName
188+ existingErrors .add (error ().keyword ("discriminator" ).instanceNode (node )
189+ .instanceLocation (instanceLocation )
190+ .locale (executionContext .getExecutionConfig ().getLocale ())
191+ .arguments (
192+ "based on the provided discriminator. No alternative could be chosen based on the discriminator property" )
193+ .build ());
194+ }
187195 }
188196 } finally {
189197 if (this .schemaContext .isDiscriminatorKeywordEnabled ()) {
@@ -194,11 +202,12 @@ && canShortCircuit() && canShortCircuit(executionContext)) {
194202 // Successful so return only the existing errors, ie. no new errors
195203 executionContext .setErrors (existingErrors );
196204 } else {
197- if (discriminatorErrors != null ) {
198- // If errors are present matching the discriminator, only these errors should be reported
205+ if (discriminatorErrors != null ) {
206+ // If errors are present matching the discriminator, only these errors should be
207+ // reported
199208 existingErrors .addAll (discriminatorErrors );
200- } else if (allErrors != null ) {
201- // As the anyOf has failed, report all the errors
209+ } else if (allErrors != null ) {
210+ // As the anyOf has failed, report all the errors
202211 existingErrors .addAll (allErrors );
203212 }
204213 executionContext .setErrors (existingErrors );
0 commit comments