|
24 | 24 |
|
25 | 25 | public class AnyOfValidator extends BaseJsonValidator implements JsonValidator {
|
26 | 26 | private static final Logger logger = LoggerFactory.getLogger(RequiredValidator.class);
|
| 27 | + private static final String REMARK = "Remaining validation messages report why candidate schemas didn't match"; |
| 28 | + private static final String DISCRIMINATOR_REMARK = "and the discriminator-selected candidate schema didn't pass validation"; |
27 | 29 |
|
28 |
| - private List<JsonSchema> schemas = new ArrayList<JsonSchema>(); |
| 30 | + private final List<JsonSchema> schemas = new ArrayList<JsonSchema>(); |
| 31 | + private final ValidationContext validationContext; |
| 32 | + private final ValidationContext.DiscriminatorContext discriminatorContext; |
29 | 33 |
|
30 | 34 | public AnyOfValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) {
|
31 | 35 | super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.ANY_OF, validationContext);
|
| 36 | + this.validationContext = validationContext; |
32 | 37 | int size = schemaNode.size();
|
33 | 38 | for (int i = 0; i < size; i++) {
|
34 |
| - schemas.add(new JsonSchema(validationContext, getValidatorType().getValue(), parentSchema.getCurrentUri(), schemaNode.get(i), parentSchema)); |
| 39 | + schemas.add(new JsonSchema(validationContext, |
| 40 | + getValidatorType().getValue(), |
| 41 | + parentSchema.getCurrentUri(), |
| 42 | + schemaNode.get(i), |
| 43 | + parentSchema)); |
| 44 | + } |
| 45 | + |
| 46 | + if (config.isOpenAPI3StyleDiscriminators()) { |
| 47 | + this.discriminatorContext = new ValidationContext.DiscriminatorContext(); |
| 48 | + } else { |
| 49 | + this.discriminatorContext = null; |
35 | 50 | }
|
36 | 51 | }
|
37 | 52 |
|
38 | 53 | public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
|
39 | 54 | debug(logger, node, rootNode, at);
|
40 | 55 |
|
| 56 | + if (config.isOpenAPI3StyleDiscriminators()) { |
| 57 | + validationContext.enterDiscriminatorContext(this.discriminatorContext, at); |
| 58 | + } |
| 59 | + |
41 | 60 | Set<ValidationMessage> allErrors = new LinkedHashSet<ValidationMessage>();
|
42 | 61 | String typeValidatorName = "anyOf/type";
|
43 | 62 |
|
44 |
| - for (JsonSchema schema : schemas) { |
45 |
| - if (schema.getValidators().containsKey(typeValidatorName)) { |
46 |
| - TypeValidator typeValidator = ((TypeValidator) schema.getValidators().get(typeValidatorName)); |
47 |
| - //If schema has type validator and node type doesn't match with schemaType then ignore it |
48 |
| - //For union type, it is must to call TypeValidator |
49 |
| - if (typeValidator.getSchemaType() != JsonType.UNION && !typeValidator.equalsToSchemaType(node)) { |
50 |
| - allErrors.add(buildValidationMessage(at, typeValidator.getSchemaType().toString())); |
51 |
| - continue; |
| 63 | + try { |
| 64 | + for (JsonSchema schema : schemas) { |
| 65 | + if (schema.getValidators().containsKey(typeValidatorName)) { |
| 66 | + TypeValidator typeValidator = ((TypeValidator) schema.getValidators().get(typeValidatorName)); |
| 67 | + //If schema has type validator and node type doesn't match with schemaType then ignore it |
| 68 | + //For union type, it is must to call TypeValidator |
| 69 | + if (typeValidator.getSchemaType() != JsonType.UNION && !typeValidator.equalsToSchemaType(node)) { |
| 70 | + allErrors.add(buildValidationMessage(at, typeValidator.getSchemaType().toString())); |
| 71 | + continue; |
| 72 | + } |
52 | 73 | }
|
| 74 | + Set<ValidationMessage> errors = schema.validate(node, rootNode, at); |
| 75 | + if (errors.isEmpty() && !config.isOpenAPI3StyleDiscriminators()) { |
| 76 | + return errors; |
| 77 | + } else if (config.isOpenAPI3StyleDiscriminators()) { |
| 78 | + if (discriminatorContext.isDiscriminatorMatchFound()) { |
| 79 | + if (!errors.isEmpty()) { |
| 80 | + errors.add(buildValidationMessage(at, DISCRIMINATOR_REMARK)); |
| 81 | + } |
| 82 | + return errors; |
| 83 | + } |
| 84 | + } |
| 85 | + allErrors.addAll(errors); |
| 86 | +// allErrors.add(renderMissingMatchValidationMessage(at)); |
53 | 87 | }
|
54 |
| - Set<ValidationMessage> errors = schema.validate(node, rootNode, at); |
55 |
| - if (errors.isEmpty()) { |
56 |
| - return errors; |
| 88 | + } finally { |
| 89 | + if (config.isOpenAPI3StyleDiscriminators()) { |
| 90 | + validationContext.leaveDiscriminatorContextImmediately(at); |
57 | 91 | }
|
58 |
| - allErrors.addAll(errors); |
59 | 92 | }
|
60 | 93 | return Collections.unmodifiableSet(allErrors);
|
61 | 94 | }
|
62 | 95 |
|
| 96 | + private ValidationMessage renderMissingMatchValidationMessage(final String at) { |
| 97 | + if (config.isOpenAPI3StyleDiscriminators()) { |
| 98 | + return super.buildValidationMessage(at, "and no match could be found (respecting discriminators). " + REMARK); |
| 99 | + } |
| 100 | + return super.buildValidationMessage(at, "and no match could be found. " + REMARK); |
| 101 | + } |
63 | 102 | }
|
0 commit comments