Skip to content

Commit 9222b16

Browse files
committed
initial implementation of Validator interface
* introducing the Validator interface which is a top-level public orchestrator of the validation process * adding Validator#ValidatorBuilder which is a configuration point for the validation process * implementing Validator#failFirst
1 parent c5f41d4 commit 9222b16

File tree

6 files changed

+128
-28
lines changed

6 files changed

+128
-28
lines changed

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,7 @@ protected Schema(Builder<?> builder) {
9393
* if the {@code subject} is invalid against this schema.
9494
*/
9595
public void validate(Object subject) {
96-
ValidatingVisitor visitor = new ValidatingVisitor(subject, this);
97-
visitor.visit(this);
98-
visitor.failIfErrorFound();
96+
Validator.builder().build().performValidation(this, subject);
9997
}
10098

10199
/**

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,16 @@ private static boolean isNull(Object obj) {
1919

2020
private ValidationFailureReporter failureReporter;
2121

22-
ValidatingVisitor(Object subject, Schema schema) {
22+
ValidatingVisitor(Schema schema, Object subject) {
2323
this.subject = subject;
2424
this.failureReporter = new CollectingFailureReporter(schema);
2525
}
2626

27+
ValidatingVisitor(Object subject, ValidationFailureReporter failureReporter) {
28+
this.subject = subject;
29+
this.failureReporter = failureReporter;
30+
}
31+
2732
@Override void visitNumberSchema(NumberSchema numberSchema) {
2833
numberSchema.accept(new NumberSchemaValidatingVisitor(subject, failureReporter));
2934
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package org.everit.json.schema;
2+
3+
import java.util.function.BiFunction;
4+
5+
public interface Validator {
6+
7+
class ValidatorBuilder {
8+
9+
private boolean failEarly = false;
10+
11+
public ValidatorBuilder failEarly() {
12+
this.failEarly = true;
13+
return this;
14+
}
15+
16+
public Validator build() {
17+
return new DefaultValidator(failEarly);
18+
}
19+
20+
}
21+
22+
static ValidatorBuilder builder() {
23+
return new ValidatorBuilder();
24+
}
25+
26+
void performValidation(Schema schema, Object input);
27+
}
28+
29+
class DefaultValidator implements Validator {
30+
31+
private BiFunction<Schema, Object, ValidatingVisitor> visitorFactory;
32+
33+
private boolean failEarly;
34+
35+
public DefaultValidator(boolean failEarly) {
36+
this.failEarly = failEarly;
37+
}
38+
39+
@Override public void performValidation(Schema schema, Object input) {
40+
ValidationFailureReporter failureReporter = createFailureReporter(schema);
41+
ValidatingVisitor visitor = new ValidatingVisitor(input, failureReporter);
42+
visitor.visit(schema);
43+
visitor.failIfErrorFound();
44+
}
45+
46+
private ValidationFailureReporter createFailureReporter(Schema schema) {
47+
if (failEarly) {
48+
return new EarlyFailingFailureReporter(schema);
49+
}
50+
return new CollectingFailureReporter(schema);
51+
}
52+
}

core/src/test/java/org/everit/json/schema/ObjectSchemaTest.java

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,37 @@
1515
*/
1616
package org.everit.json.schema;
1717

18-
import nl.jqno.equalsverifier.EqualsVerifier;
19-
import nl.jqno.equalsverifier.Warning;
20-
import org.everit.json.schema.loader.SchemaLoader;
21-
import org.json.JSONObject;
22-
import org.json.JSONPointer;
23-
import org.junit.Test;
24-
25-
import java.util.List;
26-
import java.util.concurrent.Callable;
27-
2818
import static java.util.Arrays.asList;
2919
import static org.everit.json.schema.TestSupport.buildWithLocation;
3020
import static org.everit.json.schema.TestSupport.loadAsV6;
3121
import static org.junit.Assert.assertEquals;
3222
import static org.junit.Assert.assertTrue;
3323
import static org.junit.Assert.fail;
3424

25+
import java.util.List;
26+
import java.util.concurrent.Callable;
27+
28+
import org.everit.json.schema.loader.SchemaLoader;
29+
import org.json.JSONObject;
30+
import org.json.JSONPointer;
31+
import org.junit.Test;
32+
33+
import nl.jqno.equalsverifier.EqualsVerifier;
34+
import nl.jqno.equalsverifier.Warning;
35+
3536
public class ObjectSchemaTest {
3637

37-
private static final JSONObject OBJECTS = ResourceLoader.DEFAULT.readObj("objecttestcases.json");
38+
private static final JSONObject OBJECTS = ResourceLoader.DEFAULT.readObj("objecttestcases.json");
3839

3940
private ResourceLoader loader = ResourceLoader.DEFAULT;
4041

42+
public static final Schema MULTIPLE_VIOLATIONS_SCHEMA = ObjectSchema.builder()
43+
.addPropertySchema("numberProp", new NumberSchema())
44+
.patternProperty("^string.*", new StringSchema())
45+
.addPropertySchema("boolProp", BooleanSchema.INSTANCE)
46+
.addRequiredProperty("boolProp")
47+
.build();
48+
4149
@Test
4250
public void additionalPropertiesOnEmptyObject() {
4351
ObjectSchema.builder()
@@ -133,14 +141,8 @@ public void multipleSchemaDepViolation() {
133141

134142
@Test
135143
public void multipleViolations() {
136-
Schema subject = ObjectSchema.builder()
137-
.addPropertySchema("numberProp", new NumberSchema())
138-
.patternProperty("^string.*", new StringSchema())
139-
.addPropertySchema("boolProp", BooleanSchema.INSTANCE)
140-
.addRequiredProperty("boolProp")
141-
.build();
142144
try {
143-
subject.validate(OBJECTS.get("multipleViolations"));
145+
MULTIPLE_VIOLATIONS_SCHEMA.validate(OBJECTS.get("multipleViolations"));
144146
fail("did not throw exception for 3 schema violations");
145147
} catch (ValidationException e) {
146148
assertEquals(3, e.getCausingExceptions().size());
@@ -268,9 +270,9 @@ public void patternPropsOverrideAdditionalProps() {
268270
public void propertyDepViolation() {
269271
ObjectSchema subject = buildWithLocation(
270272
ObjectSchema.builder()
271-
.addPropertySchema("ifPresent", NullSchema.INSTANCE)
272-
.addPropertySchema("mustBePresent", BooleanSchema.INSTANCE)
273-
.propertyDependency("ifPresent", "mustBePresent")
273+
.addPropertySchema("ifPresent", NullSchema.INSTANCE)
274+
.addPropertySchema("mustBePresent", BooleanSchema.INSTANCE)
275+
.propertyDependency("ifPresent", "mustBePresent")
274276
);
275277
TestSupport.failureOf(subject)
276278
.input(OBJECTS.get("propertyDepViolation"))
@@ -290,9 +292,9 @@ public void propertySchemaViolation() {
290292
public void requiredProperties() {
291293
ObjectSchema subject = buildWithLocation(
292294
ObjectSchema.builder()
293-
.addPropertySchema("boolProp", BooleanSchema.INSTANCE)
294-
.addPropertySchema("nullProp", NullSchema.INSTANCE)
295-
.addRequiredProperty("boolProp")
295+
.addPropertySchema("boolProp", BooleanSchema.INSTANCE)
296+
.addPropertySchema("nullProp", NullSchema.INSTANCE)
297+
.addRequiredProperty("boolProp")
296298
);
297299
TestSupport.failureOf(subject)
298300
.expectedPointer("#")
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package org.everit.json.schema;
2+
3+
import static org.junit.Assert.assertEquals;
4+
import static org.junit.Assert.assertTrue;
5+
import static org.junit.Assert.fail;
6+
7+
import org.junit.Test;
8+
9+
public class ValidatorTest {
10+
11+
@Test
12+
public void testCollectAllMode() {
13+
Validator actual = Validator.builder().build();
14+
try {
15+
actual.performValidation(ObjectSchemaTest.MULTIPLE_VIOLATIONS_SCHEMA,
16+
ResourceLoader.DEFAULT.readObj("objecttestcases.json").get("multipleViolations"));
17+
fail("did not throw exception");
18+
} catch (ValidationException e) {
19+
assertEquals("#: 3 schema violations found", e.getMessage());
20+
assertEquals(3, e.getCausingExceptions().size());
21+
}
22+
}
23+
24+
@Test
25+
public void testFailEarlyMode() {
26+
Validator actual = Validator.builder().failEarly().build();
27+
try {
28+
actual.performValidation(ObjectSchemaTest.MULTIPLE_VIOLATIONS_SCHEMA,
29+
ResourceLoader.DEFAULT.readObj("objecttestcases.json").get("multipleViolations"));
30+
fail("did not throw exception");
31+
} catch (ValidationException e) {
32+
assertEquals("#: required key [boolProp] not found", e.getMessage());
33+
assertTrue("no causing exceptions", e.getCausingExceptions().isEmpty());
34+
}
35+
}
36+
37+
}

tests/src/test/java/org/everit/json/schema/TestCase.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ private TestCase(JSONObject input, JSONObject schemaTest, String fileName) {
6565
inputData = input.get("data");
6666
}
6767

68+
private void testInEarlyFailureMode(Schema schema) {
69+
// validator = new ValidatorBuilder().failEarly().build();
70+
// validator = new ValidatorBuilder().failEarly().loadDefaultValues().build();
71+
// validator.performValidation(schema, inputData);
72+
}
73+
6874
public void runTest(SchemaLoader.SchemaLoaderBuilder loaderBuilder) {
6975
try {
7076
SchemaLoader loader = loaderBuilder.schemaJson(schemaJson).build();

0 commit comments

Comments
 (0)