Skip to content

Commit 415980e

Browse files
authored
Changed the development approach - new attempt from scratch (#390)
1 parent 9a9032d commit 415980e

File tree

8 files changed

+910
-174
lines changed

8 files changed

+910
-174
lines changed

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

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,34 @@
1616

1717
package com.networknt.schema;
1818

19+
import java.util.ArrayList;
20+
import java.util.Collections;
21+
import java.util.Iterator;
22+
import java.util.LinkedHashSet;
23+
import java.util.List;
24+
import java.util.Set;
25+
1926
import com.fasterxml.jackson.databind.JsonNode;
27+
import com.fasterxml.jackson.databind.node.ObjectNode;
2028
import org.slf4j.Logger;
2129
import org.slf4j.LoggerFactory;
2230

23-
import java.util.*;
24-
2531
public class AllOfValidator extends BaseJsonValidator implements JsonValidator {
2632
private static final Logger logger = LoggerFactory.getLogger(AllOfValidator.class);
2733

28-
private List<JsonSchema> schemas = new ArrayList<JsonSchema>();
29-
34+
private final ValidationContext validationContext;
35+
private final List<JsonSchema> schemas = new ArrayList<JsonSchema>();
36+
3037
public AllOfValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) {
3138
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.ALL_OF, validationContext);
39+
this.validationContext = validationContext;
3240
int size = schemaNode.size();
3341
for (int i = 0; i < size; i++) {
34-
schemas.add(new JsonSchema(validationContext, getValidatorType().getValue(), parentSchema.getCurrentUri(), schemaNode.get(i), parentSchema));
42+
schemas.add(new JsonSchema(validationContext,
43+
getValidatorType().getValue(),
44+
parentSchema.getCurrentUri(),
45+
schemaNode.get(i),
46+
parentSchema));
3547
}
3648
}
3749

@@ -42,20 +54,49 @@ public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String
4254

4355
for (JsonSchema schema : schemas) {
4456
errors.addAll(schema.validate(node, rootNode, at));
57+
58+
if (config.isOpenAPI3StyleDiscriminators()) {
59+
final Iterator<JsonNode> arrayElements = schemaNode.elements();
60+
while (arrayElements.hasNext()) {
61+
final ObjectNode allOfEntry = (ObjectNode) arrayElements.next();
62+
final JsonNode $ref = allOfEntry.get("$ref");
63+
if (null != $ref) {
64+
final ValidationContext.DiscriminatorContext currentDiscriminatorContext = validationContext
65+
.getCurrentDiscriminatorContext();
66+
final ObjectNode discriminator = currentDiscriminatorContext
67+
.getDiscriminatorForPath(allOfEntry.get("$ref").asText());
68+
if (null != discriminator) {
69+
registerAndMergeDiscriminator(currentDiscriminatorContext, discriminator, parentSchema, at);
70+
// now we have to check whether we have hit the right target
71+
final String discriminatorPropertyName = discriminator.get("propertyName").asText();
72+
final String discriminatorPropertyValue = node.get(discriminatorPropertyName).textValue();
73+
74+
final JsonSchema jsonSchema = parentSchema;
75+
checkDiscriminatorMatch(
76+
currentDiscriminatorContext,
77+
discriminator,
78+
discriminatorPropertyValue,
79+
jsonSchema);
80+
}
81+
}
82+
}
83+
}
4584
}
4685

4786
return Collections.unmodifiableSet(errors);
4887
}
49-
50-
@Override
51-
public Set<ValidationMessage> walk(JsonNode node, JsonNode rootNode, String at, boolean shouldValidateSchema) {
52-
Set<ValidationMessage> validationMessages = new LinkedHashSet<ValidationMessage>();
53-
54-
for (JsonSchema schema : schemas) {
55-
// Walk through the schema
56-
validationMessages.addAll(schema.walk(node, rootNode, at, shouldValidateSchema));
57-
}
58-
return Collections.unmodifiableSet(validationMessages);
59-
}
88+
89+
90+
91+
@Override
92+
public Set<ValidationMessage> walk(JsonNode node, JsonNode rootNode, String at, boolean shouldValidateSchema) {
93+
Set<ValidationMessage> validationMessages = new LinkedHashSet<ValidationMessage>();
94+
95+
for (JsonSchema schema : schemas) {
96+
// Walk through the schema
97+
validationMessages.addAll(schema.walk(node, rootNode, at, shouldValidateSchema));
98+
}
99+
return Collections.unmodifiableSet(validationMessages);
100+
}
60101

61102
}

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

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,40 +24,79 @@
2424

2525
public class AnyOfValidator extends BaseJsonValidator implements JsonValidator {
2626
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";
2729

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;
2933

3034
public AnyOfValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) {
3135
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.ANY_OF, validationContext);
36+
this.validationContext = validationContext;
3237
int size = schemaNode.size();
3338
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;
3550
}
3651
}
3752

3853
public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
3954
debug(logger, node, rootNode, at);
4055

56+
if (config.isOpenAPI3StyleDiscriminators()) {
57+
validationContext.enterDiscriminatorContext(this.discriminatorContext, at);
58+
}
59+
4160
Set<ValidationMessage> allErrors = new LinkedHashSet<ValidationMessage>();
4261
String typeValidatorName = "anyOf/type";
4362

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+
}
5273
}
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));
5387
}
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);
5791
}
58-
allErrors.addAll(errors);
5992
}
6093
return Collections.unmodifiableSet(allErrors);
6194
}
6295

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+
}
63102
}

0 commit comments

Comments
 (0)