Skip to content

Commit 27a0a87

Browse files
committed
started to rework ObjectSchema
1 parent 038f7b1 commit 27a0a87

13 files changed

+137
-85
lines changed

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

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
import java.util.Map;
2525
import java.util.Map.Entry;
2626
import java.util.Objects;
27+
import java.util.Optional;
2728
import java.util.Set;
2829
import java.util.regex.Pattern;
30+
import java.util.stream.Collectors;
2931
import java.util.stream.Stream;
3032

3133
import org.json.JSONObject;
@@ -247,6 +249,15 @@ public Schema getSchemaOfAdditionalProperties() {
247249
return schemaOfAdditionalProperties;
248250
}
249251

252+
private Optional<ValidationException> ifFails(final Schema schema, final Object input) {
253+
try {
254+
schema.validate(input);
255+
return Optional.empty();
256+
} catch (ValidationException e) {
257+
return Optional.of(e);
258+
}
259+
}
260+
250261
private boolean matchesAnyPattern(final String key) {
251262
return patternProperties.keySet().stream()
252263
.filter(pattern -> pattern.matcher(key).find())
@@ -262,30 +273,45 @@ public boolean requiresObject() {
262273
return requiresObject;
263274
}
264275

265-
private void testAdditionalProperties(final JSONObject subject) {
276+
private List<ValidationException> testAdditionalProperties(final JSONObject subject) {
266277
if (!additionalProperties) {
267-
getAdditionalProperties(subject)
278+
return getAdditionalProperties(subject)
268279
.findFirst()
269-
.ifPresent(unneeded -> failure("extraneous key [%s] is not permitted", unneeded));
280+
.map(unneeded -> String.format("extraneous key [%s] is not permitted", unneeded))
281+
.map(msg -> new ValidationException(this, msg))
282+
.map(exc -> Arrays.asList(exc))
283+
.orElse(Collections.emptyList());
270284
} else if (schemaOfAdditionalProperties != null) {
271-
getAdditionalProperties(subject)
272-
.map(subject::get)
273-
.forEach(schemaOfAdditionalProperties::validate);
285+
List<String> additionalPropNames = getAdditionalProperties(subject)
286+
.collect(Collectors.toList());
287+
List<ValidationException> rval = new ArrayList<ValidationException>();
288+
for (String propName : additionalPropNames) {
289+
Object propVal = subject.get(propName);
290+
ifFails(schemaOfAdditionalProperties, propVal)
291+
.map(failure -> failure.prepend(propName, this))
292+
.ifPresent(rval::add);
293+
}
294+
return rval;
274295
}
296+
return Collections.emptyList();
275297
}
276298

277-
private void testPatternProperties(final JSONObject subject) {
299+
private List<ValidationException> testPatternProperties(final JSONObject subject) {
278300
String[] propNames = JSONObject.getNames(subject);
279301
if (propNames == null || propNames.length == 0) {
280-
return;
302+
return Collections.emptyList();
281303
}
304+
List<ValidationException> rval = new ArrayList<>();
282305
for (Entry<Pattern, Schema> entry : patternProperties.entrySet()) {
283306
for (String propName : propNames) {
284307
if (entry.getKey().matcher(propName).find()) {
285-
entry.getValue().validate(subject.get(propName));
308+
ifFails(entry.getValue(), subject.get(propName))
309+
.map(exc -> exc.prepend(propName, exc.getViolatedSchema()))
310+
.ifPresent(rval::add);
286311
}
287312
}
288313
}
314+
return rval;
289315
}
290316

291317
private void testProperties(final JSONObject subject) {
@@ -301,36 +327,36 @@ private void testProperties(final JSONObject subject) {
301327

302328
private void testPropertyDependencies(final JSONObject subject) {
303329
propertyDependencies.keySet().stream()
304-
.filter(subject::has)
305-
.flatMap(ifPresent -> propertyDependencies.get(ifPresent).stream())
306-
.filter(mustBePresent -> !subject.has(mustBePresent))
307-
.findFirst()
308-
.ifPresent(missing -> failure("property [%s] is required", missing));
330+
.filter(subject::has)
331+
.flatMap(ifPresent -> propertyDependencies.get(ifPresent).stream())
332+
.filter(mustBePresent -> !subject.has(mustBePresent))
333+
.findFirst()
334+
.ifPresent(missing -> failure("property [%s] is required", missing));
309335
}
310336

311337
private void testRequiredProperties(final JSONObject subject) {
312338
requiredProperties.stream()
313-
.filter(key -> !subject.has(key))
314-
.findFirst()
315-
.ifPresent(missing -> failure("required key [%s] not found", missing));
339+
.filter(key -> !subject.has(key))
340+
.findFirst()
341+
.ifPresent(missing -> failure("required key [%s] not found", missing));
316342
}
317343

318344
private void testSchemaDependencies(final JSONObject subject) {
319345
schemaDependencies.keySet().stream()
320-
.filter(subject::has)
321-
.map(schemaDependencies::get)
322-
.forEach(schema -> schema.validate(subject));
346+
.filter(subject::has)
347+
.map(schemaDependencies::get)
348+
.forEach(schema -> schema.validate(subject));
323349
}
324350

325351
private void testSize(final JSONObject subject) {
326352
int actualSize = subject.length();
327353
if (minProperties != null && actualSize < minProperties.intValue()) {
328-
throw new ValidationException(String.format("minimum size: [%d], found: [%d]", minProperties,
329-
actualSize));
354+
throw new ValidationException(this, String.format("minimum size: [%d], found: [%d]",
355+
minProperties, actualSize));
330356
}
331357
if (maxProperties != null && actualSize > maxProperties.intValue()) {
332-
throw new ValidationException(String.format("maximum size: [%d], found: [%d]", maxProperties,
333-
actualSize));
358+
throw new ValidationException(this, String.format("maximum size: [%d], found: [%d]",
359+
maxProperties, actualSize));
334360
}
335361
}
336362

@@ -341,14 +367,18 @@ public void validate(final Object subject) {
341367
throw new ValidationException(JSONObject.class, subject);
342368
}
343369
} else {
370+
List<ValidationException> failures = new ArrayList<>();
344371
JSONObject objSubject = (JSONObject) subject;
345372
testProperties(objSubject);
346373
testRequiredProperties(objSubject);
347-
testAdditionalProperties(objSubject);
374+
failures.addAll(testAdditionalProperties(objSubject));
348375
testSize(objSubject);
349376
testPropertyDependencies(objSubject);
350377
testSchemaDependencies(objSubject);
351-
testPatternProperties(objSubject);
378+
failures.addAll(testPatternProperties(objSubject));
379+
if (failures.size() == 1) {
380+
throw failures.get(0);
381+
}
352382
}
353383
}
354384

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,10 @@ public ValidationException(final String message) {
6262
}
6363

6464
private ValidationException(final StringBuilder pointerToViolation,
65+
final Schema violatedSchema,
6566
final ValidationException original) {
6667
super(original.getMessage());
67-
this.violatedSchema = original.violatedSchema;
68+
this.violatedSchema = violatedSchema;
6869
this.pointerToViolation = pointerToViolation;
6970
}
7071

@@ -76,10 +77,10 @@ public Schema getViolatedSchema() {
7677
return violatedSchema;
7778
}
7879

79-
public ValidationException prepend(final String fragment) {
80+
public ValidationException prepend(final String fragment, final Schema violatingSchema) {
8081
Objects.requireNonNull(fragment, "fragment cannot be null");
8182
return new ValidationException(this.pointerToViolation.insert(1, '/').insert(2, fragment),
82-
this);
83+
violatingSchema, this);
8384
}
8485

8586
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public void doesNotRequireExplicitArray() {
5555
}
5656

5757
private void exceptFailure(final Schema failingSchema, final String testInputName) {
58-
TestSupport.exceptFailure(failingSchema, ARRAYS.get(testInputName));
58+
TestSupport.expectFailure(failingSchema, ARRAYS.get(testInputName));
5959
}
6060

6161
@Test

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public class BooleanSchemaTest {
2121

2222
@Test
2323
public void failure() {
24-
TestSupport.exceptFailure(BooleanSchema.INSTANCE, "false");
24+
TestSupport.expectFailure(BooleanSchema.INSTANCE, "false");
2525
}
2626

2727
@Test

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,17 @@ public void oneCriterionSuccess() {
7474

7575
@Test
7676
public void validateAll() {
77-
TestSupport.exceptFailure(CombinedSchema.allOf(SUBSCHEMAS).build(), 20);
77+
TestSupport.expectFailure(CombinedSchema.allOf(SUBSCHEMAS).build(), 20);
7878
}
7979

8080
@Test
8181
public void validateAny() {
82-
TestSupport.exceptFailure(CombinedSchema.anyOf(SUBSCHEMAS).build(), 5);
82+
TestSupport.expectFailure(CombinedSchema.anyOf(SUBSCHEMAS).build(), 5);
8383
}
8484

8585
@Test
8686
public void validateOne() {
87-
TestSupport.exceptFailure(CombinedSchema.oneOf(SUBSCHEMAS).build(), 30);
87+
TestSupport.expectFailure(CombinedSchema.oneOf(SUBSCHEMAS).build(), 30);
8888
}
8989

9090
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public void before() {
3939
@Test
4040
public void failure() {
4141
EnumSchema subject = subject();
42-
TestSupport.exceptFailure(subject, new JSONArray("[1]"));
42+
TestSupport.expectFailure(subject, new JSONArray("[1]"));
4343
}
4444

4545
private EnumSchema subject() {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public class NotSchemaTest {
2222
@Test
2323
public void failure() {
2424
NotSchema subject = NotSchema.builder().mustNotMatch(BooleanSchema.INSTANCE).build();
25-
TestSupport.exceptFailure(subject, true);
25+
TestSupport.expectFailure(subject, true);
2626
}
2727

2828
@Test

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public class NullSchemaTest {
2222

2323
@Test
2424
public void failure() {
25-
TestSupport.exceptFailure(NullSchema.INSTANCE, "null");
25+
TestSupport.expectFailure(NullSchema.INSTANCE, "null");
2626
}
2727

2828
@Test

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,31 @@ public class NumberSchemaTest {
2222
@Test
2323
public void exclusiveMinimum() {
2424
NumberSchema subject = NumberSchema.builder().minimum(10.0).exclusiveMinimum(true).build();
25-
TestSupport.exceptFailure(subject, 10);
25+
TestSupport.expectFailure(subject, 10);
2626
}
2727

2828
@Test
2929
public void maximum() {
3030
NumberSchema subject = NumberSchema.builder().maximum(20.0).build();
31-
TestSupport.exceptFailure(subject, 21);
31+
TestSupport.expectFailure(subject, 21);
3232
}
3333

3434
@Test
3535
public void maximumExclusive() {
3636
NumberSchema subject = NumberSchema.builder().maximum(20.0).exclusiveMaximum(true).build();
37-
TestSupport.exceptFailure(subject, 20);
37+
TestSupport.expectFailure(subject, 20);
3838
}
3939

4040
@Test
4141
public void minimumFailure() {
4242
NumberSchema subject = NumberSchema.builder().minimum(10.0).build();
43-
TestSupport.exceptFailure(subject, 9);
43+
TestSupport.expectFailure(subject, 9);
4444
}
4545

4646
@Test
4747
public void multipleOfFailure() {
4848
NumberSchema subject = NumberSchema.builder().multipleOf(10).build();
49-
TestSupport.exceptFailure(subject, 15);
49+
TestSupport.expectFailure(subject, 15);
5050
}
5151

5252
@Test
@@ -57,7 +57,7 @@ public void notRequiresNumber() {
5757
@Test
5858
public void requiresIntegerFailure() {
5959
NumberSchema subject = NumberSchema.builder().requiresInteger(true).build();
60-
TestSupport.exceptFailure(subject, 10.2f);
60+
TestSupport.expectFailure(subject, 10.2f);
6161
}
6262

6363
@Test

0 commit comments

Comments
 (0)