Skip to content

Commit d07f04d

Browse files
author
Jake Waffle
committed
Merged with the latest json-schema-validator.
2 parents e3b4c4a + ee6ee43 commit d07f04d

File tree

10 files changed

+159
-17
lines changed

10 files changed

+159
-17
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Add the following to your `pom.xml`:
5151
<dependency>
5252
<groupId>com.networknt</groupId>
5353
<artifactId>json-schema-validator</artifactId>
54-
<version>1.0.4</version>
54+
<version>1.0.7</version>
5555
</dependency>
5656
```
5757

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ private static JsonSchema obtainSubSchemaNode(JsonNode schemaNode, ValidationCon
8383
}
8484
else {
8585
URL url = URLFactory.toURL(node.textValue());
86-
return validationContext.getJsonSchemaFactory().getSchema(url);
86+
return validationContext.getJsonSchemaFactory().getSchema(url, validationContext.getConfig());
8787
}
8888
} catch (MalformedURLException e) {
8989
return null;

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.fasterxml.jackson.databind.JsonNode;
3030
import com.fasterxml.jackson.databind.ObjectMapper;
3131
import com.networknt.schema.url.StandardURLFetcher;
32+
import com.networknt.schema.url.URLFactory;
3233
import com.networknt.schema.url.URLFetcher;
3334

3435
public class JsonSchemaFactory {
@@ -41,7 +42,7 @@ public static class Builder {
4142
private URLFetcher urlFetcher;
4243
private String defaultMetaSchemaURI;
4344
private Map<String, JsonMetaSchema> jsonMetaSchemas = new HashMap<String, JsonMetaSchema>();
44-
private Map<URL, URL> urlMap = new HashMap<URL, URL>();
45+
private Map<String, String> urlMap = new HashMap<String, String>();
4546

4647
public Builder objectMapper(ObjectMapper objectMapper) {
4748
this.objectMapper = objectMapper;
@@ -70,7 +71,7 @@ public Builder addMetaSchemas(Collection<? extends JsonMetaSchema> jsonMetaSchem
7071
return this;
7172
}
7273

73-
public Builder addUrlMappings(Map<URL, URL> map) {
74+
public Builder addUrlMappings(Map<String, String> map) {
7475
this.urlMap.putAll(map);
7576
return this;
7677
}
@@ -91,13 +92,14 @@ public JsonSchemaFactory build() {
9192
private final URLFetcher urlFetcher;
9293
private final String defaultMetaSchemaURI;
9394
private final Map<String, JsonMetaSchema> jsonMetaSchemas;
94-
private final Map<URL, URL> urlMap;
95+
private final Map<String, String> urlMap;
9596

9697
private JsonSchemaFactory(
9798
ObjectMapper mapper,
9899
URLFetcher urlFetcher,
99100
String defaultMetaSchemaURI,
100-
Map<String, JsonMetaSchema> jsonMetaSchemas, Map<URL, URL> urlMap) {
101+
Map<String, JsonMetaSchema> jsonMetaSchemas,
102+
Map<String, String> urlMap) {
101103
if (mapper == null) {
102104
throw new IllegalArgumentException("ObjectMapper must not be null");
103105
}
@@ -208,9 +210,9 @@ public JsonSchema getSchema(InputStream schemaStream) {
208210
public JsonSchema getSchema(URL schemaURL, SchemaValidatorsConfig config) {
209211
try {
210212
InputStream inputStream = null;
211-
Map<URL, URL> map = (config != null) ? config.getUrlMappings() : new HashMap<URL, URL>(urlMap);
213+
Map<String, String> map = (config != null) ? config.getUrlMappings() : new HashMap<String, String>(urlMap);
212214
map.putAll(urlMap);
213-
URL mappedURL = map.getOrDefault(schemaURL, schemaURL);
215+
URL mappedURL = URLFactory.toURL(map.getOrDefault(schemaURL.toString(), schemaURL.toString()));
214216
try {
215217
inputStream = urlFetcher.fetch(mappedURL);
216218
JsonNode schemaNode = mapper.readTree(inputStream);

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public class SchemaValidatorsConfig {
4343
* validation of schemas that refer to public URLs. This is merged with any mappings the {@link JsonSchemaFactory}
4444
* may have been built with.
4545
*/
46-
private Map<URL, URL> urlMappings = new HashMap<URL, URL>();
46+
private Map<String, String> urlMappings = new HashMap<String, String>();
4747

4848
public boolean isTypeLoose() {
4949
return typeLoose;
@@ -53,11 +53,12 @@ public void setTypeLoose(boolean typeLoose) {
5353
this.typeLoose = typeLoose;
5454
}
5555

56-
public Map<URL, URL> getUrlMappings() {
57-
return new HashMap<URL, URL>(urlMappings);
56+
public Map<String, String> getUrlMappings() {
57+
// return a copy of the mappings
58+
return new HashMap<String, String>(urlMappings);
5859
}
5960

60-
public void setUrlMappings(Map<URL, URL> urlMappings) {
61+
public void setUrlMappings(Map<String, String> urlMappings) {
6162
this.urlMappings = urlMappings;
6263
}
6364

@@ -83,6 +84,6 @@ public SchemaValidatorsConfig() {
8384

8485
private void loadDefaultConfig() {
8586
this.typeLoose = true;
86-
this.urlMappings = new HashMap<URL, URL>();
87+
this.urlMappings = new HashMap<String, String>();
8788
}
8889
}

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,20 @@
2424
import java.util.Set;
2525

2626
public class TypeValidator extends BaseJsonValidator implements JsonValidator {
27+
private static final String TYPE = "type";
28+
private static final String ENUM = "enum";
29+
private static final String REF = "$ref";
30+
2731
private static final Logger logger = LoggerFactory.getLogger(TypeValidator.class);
2832

2933
private JsonType schemaType;
34+
private JsonSchema parentSchema;
3035
private UnionTypeValidator unionTypeValidator;
3136

3237
public TypeValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) {
3338
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.TYPE, validationContext);
3439
schemaType = TypeFactory.getSchemaNodeType(schemaNode);
40+
this.parentSchema = parentSchema;
3541

3642
if (schemaType == JsonType.UNION) {
3743
unionTypeValidator = new UnionTypeValidator(schemaPath, schemaNode, parentSchema, validationContext);
@@ -62,6 +68,11 @@ public boolean equalsToSchemaType(JsonNode node) {
6268
return true;
6369
}
6470
}
71+
// Skip the type validation when the schema is an enum object schema. Since the current type
72+
// of node itself can be used for type validation.
73+
if (isEnumObjectSchema(parentSchema)) {
74+
return true;
75+
}
6576
if(config.isTypeLoose()) {
6677
if (nodeType == JsonType.STRING) {
6778
if(schemaType == JsonType.INTEGER) {
@@ -215,4 +226,28 @@ public static boolean isNumber(JsonNode node, boolean isTypeLoose) {
215226
}
216227
return false;
217228
}
229+
230+
private static boolean isEnumObjectSchema(JsonSchema jsonSchema) {
231+
// There are three conditions for enum object schema
232+
// 1. The current schema contains key "type", and the value is object
233+
// 2. The current schema contains key "enum", and the value is an array
234+
// 3. The parent schema if refer from components, which means the corresponding enum object class would be generated
235+
JsonNode typeNode = null;
236+
JsonNode enumNode = null;
237+
JsonNode refNode = null;
238+
239+
if (jsonSchema != null) {
240+
if (jsonSchema.getSchemaNode() != null) {
241+
typeNode = jsonSchema.getSchemaNode().get(TYPE);
242+
enumNode = jsonSchema.getSchemaNode().get(ENUM);
243+
}
244+
if (jsonSchema.getParentSchema() != null && jsonSchema.getParentSchema().getSchemaNode() != null) {
245+
refNode = jsonSchema.getParentSchema().getSchemaNode().get(REF);
246+
}
247+
}
248+
if (typeNode != null && enumNode != null && refNode != null) {
249+
return TypeFactory.getSchemaNodeType(typeNode) == JsonType.OBJECT && enumNode.isArray();
250+
}
251+
return false;
252+
}
218253
}

src/test/java/com/networknt/schema/JsonSchemaTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,11 @@ public void testUnionTypeValidator() throws Exception {
293293
public void testUniqueItemsValidator() throws Exception {
294294
runTestFile("tests/uniqueItems.json");
295295
}
296+
297+
@Test
298+
public void testEnumObject() throws Exception {
299+
runTestFile("tests/enumObject.json");
300+
}
296301

297302
@Test
298303
public void testIdSchemaWithUrl() throws Exception {

src/test/java/com/networknt/schema/UrlMappingTest.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,22 @@ public void testValidatorConfigExampleMappings() throws IOException {
130130
assertEquals(0, schema.validate(mapper.createObjectNode()).size());
131131
}
132132

133-
private Map<URL, URL> getUrlMappingsFromUrl(URL url) throws MalformedURLException, IOException {
134-
HashMap<URL, URL> map = new HashMap<URL, URL>();
133+
@Test
134+
public void testMappingsForRef() throws IOException {
135+
JsonSchemaFactory instance = JsonSchemaFactory.getInstance();
136+
URL mappings = URLFactory.toURL("resource:tests/url_mapping/schema-with-ref-mapping.json");
137+
SchemaValidatorsConfig config = new SchemaValidatorsConfig();
138+
config.setUrlMappings(getUrlMappingsFromUrl(mappings));
139+
JsonSchema schema = instance.getSchema(URLFactory.toURL("resource:tests/url_mapping/schema-with-ref.json"),
140+
config);
141+
assertEquals(0, schema.validate(mapper.readTree("[]")).size());
142+
}
143+
144+
private Map<String, String> getUrlMappingsFromUrl(URL url) throws MalformedURLException, IOException {
145+
HashMap<String, String> map = new HashMap<String, String>();
135146
for (JsonNode mapping : mapper.readTree(url)) {
136-
map.put(URLFactory.toURL(mapping.get("publicURL").asText()),
137-
URLFactory.toURL(mapping.get("localURL").asText()));
147+
map.put(mapping.get("publicURL").asText(),
148+
mapping.get("localURL").asText());
138149
}
139150
return map;
140151
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
[
2+
{
3+
"description": "simple enum object validation",
4+
"schema": {
5+
"properties": {
6+
"foo": {
7+
"type": "object",
8+
"enum": [1, 2, 3]
9+
},
10+
"bar": {
11+
"$ref": "#/properties/foo"
12+
}
13+
}
14+
},
15+
"tests": [
16+
{
17+
"description": "one of the enum is valid",
18+
"data": {
19+
"bar": 1
20+
},
21+
"valid": true
22+
},
23+
{
24+
"description": "one of the enum is valid",
25+
"isTypeLoose": true,
26+
"data": {
27+
"bar": "1"
28+
},
29+
"valid": true
30+
},
31+
{
32+
"description": "something else is invalid",
33+
"isTypeLoose": false,
34+
"data": {
35+
"bar": "1"
36+
},
37+
"valid": false
38+
},
39+
{
40+
"description": "something else is invalid",
41+
"data": {
42+
"bar": 4
43+
},
44+
"valid": false
45+
}
46+
]
47+
},
48+
{
49+
"description": "fake enum object validation",
50+
"schema": {
51+
"type": "object",
52+
"enum": [1, 2, {"key": "value"}]
53+
},
54+
"tests": [
55+
{
56+
"description": "one of the enum is invalid",
57+
"data": 1,
58+
"valid": false
59+
},
60+
{
61+
"description": "one of the enum is valid",
62+
"isTypeLoose": true,
63+
"data": {"key": "value"},
64+
"valid": true
65+
}
66+
]
67+
}
68+
]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[
2+
{
3+
"publicURL": "http://json-schema.org/draft-04/schema#",
4+
"localURL": "resource:/draftv4.schema.json"
5+
},
6+
{
7+
"publicURL": "http://example.com/invalid/schema/url",
8+
"localURL": "resource:/tests/url_mapping/example-schema.json"
9+
}
10+
]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-04/schema#",
3+
"title": "json-object-with-schema",
4+
"type": "array",
5+
"properties": {
6+
"schema": {
7+
"$ref": "http://example.com/invalid/schema/url"
8+
}
9+
}
10+
}

0 commit comments

Comments
 (0)