Skip to content

Commit a5494b3

Browse files
authored
Merge pull request #144 from zgyorffi/if_then_else_support
If-then-else support
2 parents 21d2e21 + 600c107 commit a5494b3

File tree

6 files changed

+374
-16
lines changed

6 files changed

+374
-16
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package org.everit.json.schema;
2+
3+
import java.util.Optional;
4+
5+
/**
6+
* Validator for {@code if}, {@code then}, {@code else} schemas.
7+
*/
8+
public class ConditionalSchema extends Schema {
9+
10+
/**
11+
* Builder class for {@link ConditionalSchema}.
12+
*/
13+
public static class Builder extends Schema.Builder<ConditionalSchema> {
14+
private Schema ifSchema;
15+
private Schema thenSchema;
16+
private Schema elseSchema;
17+
18+
public Builder ifSchema(final Schema ifSchema) {
19+
this.ifSchema = ifSchema;
20+
return this;
21+
}
22+
23+
public Builder thenSchema(final Schema thenSchema) {
24+
this.thenSchema = thenSchema;
25+
return this;
26+
}
27+
28+
public Builder elseSchema(final Schema elseSchema) {
29+
this.elseSchema = elseSchema;
30+
return this;
31+
}
32+
33+
@Override
34+
public ConditionalSchema build() {
35+
return new ConditionalSchema(this);
36+
}
37+
}
38+
39+
public static Builder builder() {
40+
return new Builder();
41+
}
42+
43+
private final Schema ifSchema;
44+
private final Schema thenSchema;
45+
private final Schema elseSchema;
46+
47+
public ConditionalSchema(Builder builder) {
48+
super(builder);
49+
this.ifSchema = builder.ifSchema;
50+
this.thenSchema = builder.thenSchema;
51+
this.elseSchema = builder.elseSchema;
52+
}
53+
54+
public Optional<Schema> getIfSchema() {
55+
return Optional.ofNullable(ifSchema);
56+
}
57+
58+
public Optional<Schema> getThenSchema() {
59+
return Optional.ofNullable(thenSchema);
60+
}
61+
62+
public Optional<Schema> getElseSchema() {
63+
return Optional.ofNullable(elseSchema);
64+
}
65+
66+
@Override
67+
void accept(Visitor visitor) {
68+
visitor.visitConditionalSchema(this);
69+
}
70+
71+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package org.everit.json.schema;
2+
3+
4+
import java.util.Arrays;
5+
6+
import static java.util.Objects.requireNonNull;
7+
8+
class ConditionalSchemaValidatingVisitor extends Visitor {
9+
10+
private final Object subject;
11+
12+
private final ValidatingVisitor owner;
13+
14+
private ConditionalSchema conditionalSchema;
15+
16+
private ValidationException ifSchemaException;
17+
18+
public ConditionalSchemaValidatingVisitor(Object subject, ValidatingVisitor owner) {
19+
this.subject = subject;
20+
this.owner = requireNonNull(owner, "owner cannot be null");
21+
}
22+
23+
@Override
24+
void visitConditionalSchema(ConditionalSchema conditionalSchema) {
25+
this.conditionalSchema = conditionalSchema;
26+
if (!conditionalSchema.getIfSchema().isPresent() ||
27+
(!conditionalSchema.getThenSchema().isPresent() && !conditionalSchema.getElseSchema().isPresent())) {
28+
return;
29+
}
30+
super.visitConditionalSchema(conditionalSchema);
31+
}
32+
33+
@Override
34+
void visitIfSchema(Schema ifSchema) {
35+
if (conditionalSchema.getIfSchema().isPresent()) {
36+
ifSchemaException = owner.getFailureOfSchema(ifSchema, subject);
37+
}
38+
}
39+
40+
@Override
41+
void visitThenSchema(Schema thenSchema) {
42+
if (ifSchemaException == null) {
43+
ValidationException thenSchemaException = owner.getFailureOfSchema(thenSchema, subject);
44+
if (thenSchemaException != null) {
45+
owner.failure(new ValidationException(conditionalSchema,
46+
new StringBuilder(new StringBuilder("#")),
47+
"input is invalid against the \"then\" schema",
48+
Arrays.asList(thenSchemaException),
49+
"then",
50+
conditionalSchema.getSchemaLocation()));
51+
}
52+
}
53+
}
54+
55+
@Override
56+
void visitElseSchema(Schema elseSchema) {
57+
if (ifSchemaException != null) {
58+
ValidationException elseSchemaException = owner.getFailureOfSchema(elseSchema, subject);
59+
if (elseSchemaException != null) {
60+
owner.failure(new ValidationException(conditionalSchema,
61+
new StringBuilder(new StringBuilder("#")),
62+
"input is invalid against both the \"if\" and \"else\" schema",
63+
Arrays.asList(ifSchemaException, elseSchemaException),
64+
"else",
65+
conditionalSchema.getSchemaLocation()));
66+
}
67+
}
68+
}
69+
70+
}

core/src/main/java/org/everit/json/schema/ValidatingVisitor.java

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package org.everit.json.schema;
22

3-
import static java.lang.String.format;
4-
import static org.everit.json.schema.EnumSchema.toJavaValue;
3+
import org.json.JSONObject;
54

65
import java.util.ArrayList;
76
import java.util.Collection;
87
import java.util.List;
98

10-
import org.json.JSONObject;
9+
import static java.lang.String.format;
10+
import static org.everit.json.schema.EnumSchema.toJavaValue;
1111

1212
class ValidatingVisitor extends Visitor {
1313

@@ -32,27 +32,32 @@ void visit(Schema schema) {
3232
this.failureReporter = failureReporter;
3333
}
3434

35-
@Override void visitNumberSchema(NumberSchema numberSchema) {
35+
@Override
36+
void visitNumberSchema(NumberSchema numberSchema) {
3637
numberSchema.accept(new NumberSchemaValidatingVisitor(subject, this));
3738
}
3839

39-
@Override void visitArraySchema(ArraySchema arraySchema) {
40+
@Override
41+
void visitArraySchema(ArraySchema arraySchema) {
4042
arraySchema.accept(new ArraySchemaValidatingVisitor(subject, this));
4143
}
4244

43-
@Override void visitBooleanSchema(BooleanSchema schema) {
45+
@Override
46+
void visitBooleanSchema(BooleanSchema schema) {
4447
if (!(subject instanceof Boolean)) {
4548
failureReporter.failure(Boolean.class, subject);
4649
}
4750
}
4851

49-
@Override void visitNullSchema(NullSchema nullSchema) {
52+
@Override
53+
void visitNullSchema(NullSchema nullSchema) {
5054
if (!(subject == null || subject == JSONObject.NULL)) {
5155
failureReporter.failure("expected: null, found: " + subject.getClass().getSimpleName(), "type");
5256
}
5357
}
5458

55-
@Override void visitConstSchema(ConstSchema constSchema) {
59+
@Override
60+
void visitConstSchema(ConstSchema constSchema) {
5661
if (isNull(subject) && isNull(constSchema.getPermittedValue())) {
5762
return;
5863
}
@@ -62,7 +67,8 @@ void visit(Schema schema) {
6267
}
6368
}
6469

65-
@Override void visitEnumSchema(EnumSchema enumSchema) {
70+
@Override
71+
void visitEnumSchema(EnumSchema enumSchema) {
6672
Object effectiveSubject = toJavaValue(subject);
6773
for (Object possibleValue : enumSchema.getPossibleValues()) {
6874
if (ObjectComparator.deepEquals(possibleValue, effectiveSubject)) {
@@ -72,19 +78,22 @@ void visit(Schema schema) {
7278
failureReporter.failure(format("%s is not a valid enum value", subject), "enum");
7379
}
7480

75-
@Override void visitFalseSchema(FalseSchema falseSchema) {
81+
@Override
82+
void visitFalseSchema(FalseSchema falseSchema) {
7683
failureReporter.failure("false schema always fails", "false");
7784
}
7885

79-
@Override void visitNotSchema(NotSchema notSchema) {
86+
@Override
87+
void visitNotSchema(NotSchema notSchema) {
8088
Schema mustNotMatch = notSchema.getMustNotMatch();
8189
ValidationException failure = getFailureOfSchema(mustNotMatch, subject);
8290
if (failure == null) {
8391
failureReporter.failure("subject must not be valid against schema " + mustNotMatch, "not");
8492
}
8593
}
8694

87-
@Override void visitReferenceSchema(ReferenceSchema referenceSchema) {
95+
@Override
96+
void visitReferenceSchema(ReferenceSchema referenceSchema) {
8897
Schema referredSchema = referenceSchema.getReferredSchema();
8998
if (referredSchema == null) {
9099
throw new IllegalStateException("referredSchema must be injected before validation");
@@ -95,15 +104,18 @@ void visit(Schema schema) {
95104
}
96105
}
97106

98-
@Override void visitObjectSchema(ObjectSchema objectSchema) {
107+
@Override
108+
void visitObjectSchema(ObjectSchema objectSchema) {
99109
objectSchema.accept(new ObjectSchemaValidatingVisitor(subject, this));
100110
}
101111

102-
@Override void visitStringSchema(StringSchema stringSchema) {
112+
@Override
113+
void visitStringSchema(StringSchema stringSchema) {
103114
stringSchema.accept(new StringSchemaValidatingVisitor(subject, this));
104115
}
105116

106-
@Override void visitCombinedSchema(CombinedSchema combinedSchema) {
117+
@Override
118+
void visitCombinedSchema(CombinedSchema combinedSchema) {
107119
List<ValidationException> failures = new ArrayList<>();
108120
Collection<Schema> subschemas = combinedSchema.getSubschemas();
109121
CombinedSchema.ValidationCriterion criterion = combinedSchema.getCriterion();
@@ -126,6 +138,11 @@ void visit(Schema schema) {
126138
}
127139
}
128140

141+
@Override
142+
void visitConditionalSchema(ConditionalSchema conditionalSchema) {
143+
conditionalSchema.accept(new ConditionalSchemaValidatingVisitor(subject, this));
144+
}
145+
129146
ValidationException getFailureOfSchema(Schema schema, Object input) {
130147
Object origSubject = this.subject;
131148
this.subject = input;

core/src/main/java/org/everit/json/schema/Visitor.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,4 +183,19 @@ void visitMinLength(Integer minLength) {
183183

184184
void visitCombinedSchema(CombinedSchema combinedSchema) {
185185
}
186+
187+
void visitConditionalSchema(ConditionalSchema conditionalSchema){
188+
conditionalSchema.getIfSchema().ifPresent(this::visitIfSchema);
189+
conditionalSchema.getThenSchema().ifPresent(this::visitThenSchema);
190+
conditionalSchema.getElseSchema().ifPresent(this::visitElseSchema);
191+
}
192+
193+
void visitIfSchema(Schema ifSchema) {
194+
}
195+
196+
void visitThenSchema(Schema thenSchema) {
197+
}
198+
199+
void visitElseSchema(Schema elseSchema) {
200+
}
186201
}

0 commit comments

Comments
 (0)