Skip to content

Commit 9830d29

Browse files
committed
fixing #30
1 parent defdad5 commit 9830d29

File tree

4 files changed

+130
-47
lines changed

4 files changed

+130
-47
lines changed

core/src/main/java/org/everit/json/schema/loader/SchemaLoader.java

Lines changed: 54 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public class SchemaLoader {
6969
*/
7070
@FunctionalInterface
7171
private interface CombinedSchemaProvider
72-
extends Function<Collection<Schema>, CombinedSchema.Builder> {
72+
extends Function<Collection<Schema>, CombinedSchema.Builder> {
7373

7474
}
7575

@@ -138,6 +138,11 @@ public SchemaLoaderBuilder schemaJson(final JSONObject schemaJson) {
138138
return this;
139139
}
140140

141+
private SchemaLoaderBuilder formatValidators(final Map<String, FormatValidator> formatValidators) {
142+
this.formatValidators = formatValidators;
143+
return this;
144+
}
145+
141146
}
142147

143148
private static final List<String> ARRAY_SCHEMA_PROPS = Arrays.asList("items", "additionalItems",
@@ -252,19 +257,19 @@ public SchemaLoader(final SchemaLoaderBuilder builder) {
252257

253258
private void addDependencies(final Builder builder, final JSONObject deps) {
254259
Arrays.stream(JSONObject.getNames(deps))
255-
.forEach(ifPresent -> addDependency(builder, ifPresent, deps.get(ifPresent)));
260+
.forEach(ifPresent -> addDependency(builder, ifPresent, deps.get(ifPresent)));
256261
}
257262

258263
private void addDependency(final Builder builder, final String ifPresent, final Object deps) {
259264
typeMultiplexer(deps)
260-
.ifObject().then(obj -> {
261-
builder.schemaDependency(ifPresent, loadChild(obj).build());
262-
})
263-
.ifIs(JSONArray.class).then(propNames -> {
264-
IntStream.range(0, propNames.length())
265-
.mapToObj(i -> propNames.getString(i))
266-
.forEach(dependency -> builder.propertyDependency(ifPresent, dependency));
267-
}).requireAny();
265+
.ifObject().then(obj -> {
266+
builder.schemaDependency(ifPresent, loadChild(obj).build());
267+
})
268+
.ifIs(JSONArray.class).then(propNames -> {
269+
IntStream.range(0, propNames.length())
270+
.mapToObj(i -> propNames.getString(i))
271+
.forEach(dependency -> builder.propertyDependency(ifPresent, dependency));
272+
}).requireAny();
268273
}
269274

270275
private void addFormatValidator(final StringSchema.Builder builder, final String formatName) {
@@ -274,11 +279,11 @@ private void addFormatValidator(final StringSchema.Builder builder, final String
274279
private void addPropertySchemaDefinition(final String keyOfObj, final Object definition,
275280
final ObjectSchema.Builder builder) {
276281
typeMultiplexer(definition)
277-
.ifObject()
278-
.then(obj -> {
279-
builder.addPropertySchema(keyOfObj, loadChild(obj).build());
280-
})
281-
.requireAny();
282+
.ifObject()
283+
.then(obj -> {
284+
builder.addPropertySchema(keyOfObj, loadChild(obj).build());
285+
})
286+
.requireAny();
282287
}
283288

284289
private CombinedSchema.Builder buildAnyOfSchemaForMultipleTypes() {
@@ -301,15 +306,15 @@ private ArraySchema.Builder buildArraySchema() {
301306
ifPresent("uniqueItems", Boolean.class, builder::uniqueItems);
302307
if (schemaJson.has("additionalItems")) {
303308
typeMultiplexer("additionalItems", schemaJson.get("additionalItems"))
304-
.ifIs(Boolean.class).then(builder::additionalItems)
305-
.ifObject().then(jsonObj -> builder.schemaOfAdditionalItems(loadChild(jsonObj).build()))
306-
.requireAny();
309+
.ifIs(Boolean.class).then(builder::additionalItems)
310+
.ifObject().then(jsonObj -> builder.schemaOfAdditionalItems(loadChild(jsonObj).build()))
311+
.requireAny();
307312
}
308313
if (schemaJson.has("items")) {
309314
typeMultiplexer("items", schemaJson.get("items"))
310-
.ifObject().then(itemSchema -> builder.allItemSchema(loadChild(itemSchema).build()))
311-
.ifIs(JSONArray.class).then(arr -> buildTupleSchema(builder, arr))
312-
.requireAny();
315+
.ifObject().then(itemSchema -> builder.allItemSchema(loadChild(itemSchema).build()))
316+
.ifIs(JSONArray.class).then(arr -> buildTupleSchema(builder, arr))
317+
.requireAny();
313318
}
314319
return builder;
315320
}
@@ -318,8 +323,8 @@ private EnumSchema.Builder buildEnumSchema() {
318323
Set<Object> possibleValues = new HashSet<>();
319324
JSONArray arr = schemaJson.getJSONArray("enum");
320325
IntStream.range(0, arr.length())
321-
.mapToObj(arr::get)
322-
.forEach(possibleValues::add);
326+
.mapToObj(arr::get)
327+
.forEach(possibleValues::add);
323328
return EnumSchema.builder().possibleValues(possibleValues);
324329
}
325330

@@ -344,21 +349,21 @@ private ObjectSchema.Builder buildObjectSchema() {
344349
ifPresent("maxProperties", Integer.class, builder::maxProperties);
345350
if (schemaJson.has("properties")) {
346351
typeMultiplexer(schemaJson.get("properties"))
347-
.ifObject().then(propertyDefs -> {
348-
populatePropertySchemas(propertyDefs, builder);
349-
}).requireAny();
352+
.ifObject().then(propertyDefs -> {
353+
populatePropertySchemas(propertyDefs, builder);
354+
}).requireAny();
350355
}
351356
if (schemaJson.has("additionalProperties")) {
352357
typeMultiplexer("additionalProperties", schemaJson.get("additionalProperties"))
353-
.ifIs(Boolean.class).then(builder::additionalProperties)
354-
.ifObject().then(def -> builder.schemaOfAdditionalProperties(loadChild(def).build()))
355-
.requireAny();
358+
.ifIs(Boolean.class).then(builder::additionalProperties)
359+
.ifObject().then(def -> builder.schemaOfAdditionalProperties(loadChild(def).build()))
360+
.requireAny();
356361
}
357362
if (schemaJson.has("required")) {
358363
JSONArray requiredJson = schemaJson.getJSONArray("required");
359364
IntStream.range(0, requiredJson.length())
360-
.mapToObj(requiredJson::getString)
361-
.forEach(builder::addRequiredProperty);
365+
.mapToObj(requiredJson::getString)
366+
.forEach(builder::addRequiredProperty);
362367
}
363368
if (schemaJson.has("patternProperties")) {
364369
JSONObject patternPropsJson = schemaJson.getJSONObject("patternProperties");
@@ -403,8 +408,8 @@ private StringSchema.Builder buildStringSchema() {
403408
private void buildTupleSchema(final ArraySchema.Builder builder, final JSONArray itemSchema) {
404409
for (int i = 0; i < itemSchema.length(); ++i) {
405410
typeMultiplexer(itemSchema.get(i))
406-
.ifObject().then(schema -> builder.addItemSchema(loadChild(schema).build()))
407-
.requireAny();
411+
.ifObject().then(schema -> builder.addItemSchema(loadChild(schema).build()))
412+
.requireAny();
408413
}
409414
}
410415

@@ -518,16 +523,16 @@ private Schema.Builder<?> lookupReference(final String relPointerString, final J
518523
}
519524
JSONPointer pointer = absPointerString.startsWith("#")
520525
? JSONPointer.forDocument(rootSchemaJson, absPointerString)
521-
: JSONPointer.forURL(httpClient, absPointerString);
522-
ReferenceSchema.Builder refBuilder = ReferenceSchema.builder();
523-
pointerSchemas.put(absPointerString, refBuilder);
524-
QueryResult result = pointer.query();
525-
JSONObject resultObject = extend(withoutRef(ctx), result.getQueryResult());
526-
SchemaLoader childLoader = selfBuilder().schemaJson(resultObject)
527-
.rootSchemaJson(result.getContainingDocument()).build();
528-
Schema referredSchema = childLoader.load().build();
529-
refBuilder.build().setReferredSchema(referredSchema);
530-
return refBuilder;
526+
: JSONPointer.forURL(httpClient, absPointerString);
527+
ReferenceSchema.Builder refBuilder = ReferenceSchema.builder();
528+
pointerSchemas.put(absPointerString, refBuilder);
529+
QueryResult result = pointer.query();
530+
JSONObject resultObject = extend(withoutRef(ctx), result.getQueryResult());
531+
SchemaLoader childLoader = selfBuilder().schemaJson(resultObject)
532+
.rootSchemaJson(result.getContainingDocument()).build();
533+
Schema referredSchema = childLoader.load().build();
534+
refBuilder.build().setReferredSchema(referredSchema);
535+
return refBuilder;
531536
}
532537

533538
private void populatePropertySchemas(final JSONObject propertyDefs,
@@ -546,10 +551,12 @@ private boolean schemaHasAnyOf(final Collection<String> propNames) {
546551
}
547552

548553
private SchemaLoaderBuilder selfBuilder() {
549-
return builder().id(id).schemaJson(schemaJson)
554+
SchemaLoaderBuilder rval = builder().id(id).schemaJson(schemaJson)
550555
.rootSchemaJson(rootSchemaJson)
551556
.pointerSchemas(pointerSchemas)
552-
.httpClient(httpClient);
557+
.httpClient(httpClient)
558+
.formatValidators(this.formatValidators);
559+
return rval;
553560
}
554561

555562
private Schema.Builder<?> sniffSchemaByProps() {
@@ -621,8 +628,8 @@ JSONObject withoutRef(final JSONObject original) {
621628
}
622629
JSONObject rval = new JSONObject();
623630
Arrays.stream(names)
624-
.filter(name -> !"$ref".equals(name))
625-
.forEach(name -> rval.put(name, original.get(name)));
631+
.filter(name -> !"$ref".equals(name))
632+
.forEach(name -> rval.put(name, original.get(name)));
626633
return rval;
627634
}
628635
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright (C) 2011 Everit Kft. (http://www.everit.org)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.everit.json.schema.loader;
17+
18+
import java.util.Optional;
19+
20+
import org.everit.json.schema.FormatValidator;
21+
import org.everit.json.schema.ValidationException;
22+
import org.json.JSONObject;
23+
import org.json.JSONTokener;
24+
import org.junit.Assert;
25+
import org.junit.Test;
26+
27+
public class CustomFormatValidatorTest {
28+
29+
static class EvenCharNumValidator implements FormatValidator {
30+
31+
@Override
32+
public Optional<String> validate(final String subject) {
33+
if (subject.length() % 2 == 0) {
34+
return Optional.empty();
35+
} else {
36+
return Optional.of(String.format("the length of srtring [%s] is odd", subject));
37+
}
38+
}
39+
}
40+
41+
private JSONObject read(final String path) {
42+
return new JSONObject(new JSONTokener(getClass().getResourceAsStream(path)));
43+
}
44+
45+
@Test
46+
public void test() {
47+
SchemaLoader schemaLoader = SchemaLoader.builder()
48+
.schemaJson(read("/org/everit/jsonvalidator/customformat-schema.json"))
49+
.addFormatValidator("evenlength", new EvenCharNumValidator())
50+
.build();
51+
try {
52+
schemaLoader.load().build()
53+
.validate(read("/org/everit/jsonvalidator/customformat-data.json"));
54+
Assert.fail("did not throw exception");
55+
} catch (ValidationException ve) {
56+
}
57+
58+
}
59+
60+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"id": "everitorg"
3+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"$schema":"http://json-schema.org/draft-04/schema#",
3+
"type":"object",
4+
"properties": {
5+
"id": {
6+
"type": "string",
7+
"maxLength": 10,
8+
"minLength": 3,
9+
"format": "evenlength"
10+
}
11+
},
12+
"required": ["id"]
13+
}

0 commit comments

Comments
 (0)