Skip to content

Commit f0a60ef

Browse files
authored
Merge branch 'master' into bug/cyclic-dep
2 parents 524dc47 + 2ef94a1 commit f0a60ef

File tree

8 files changed

+150
-4
lines changed

8 files changed

+150
-4
lines changed

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.fasterxml.jackson.databind.JsonNode;
2020
import com.fasterxml.jackson.databind.ObjectMapper;
2121
import com.networknt.schema.uri.*;
22+
import com.networknt.schema.urn.URNFactory;
2223
import org.slf4j.Logger;
2324
import org.slf4j.LoggerFactory;
2425

@@ -41,6 +42,7 @@ public static class Builder {
4142
private String defaultMetaSchemaURI;
4243
private final Map<String, URIFactory> uriFactoryMap = new HashMap<String, URIFactory>();
4344
private final Map<String, URIFetcher> uriFetcherMap = new HashMap<String, URIFetcher>();
45+
private URNFactory urnFactory;
4446
private final Map<String, JsonMetaSchema> jsonMetaSchemas = new HashMap<String, JsonMetaSchema>();
4547
private final Map<String, String> uriMap = new HashMap<String, String>();
4648

@@ -121,13 +123,19 @@ public Builder addUriMappings(final Map<String, String> map) {
121123
return this;
122124
}
123125

126+
public Builder addUrnFactory(URNFactory urnFactory) {
127+
this.urnFactory = urnFactory;
128+
return this;
129+
}
130+
124131
public JsonSchemaFactory build() {
125132
// create builtin keywords with (custom) formats.
126133
return new JsonSchemaFactory(
127134
objectMapper == null ? new ObjectMapper() : objectMapper,
128135
defaultMetaSchemaURI,
129136
new URISchemeFactory(uriFactoryMap),
130137
new URISchemeFetcher(uriFetcherMap),
138+
urnFactory,
131139
jsonMetaSchemas,
132140
uriMap
133141
);
@@ -138,15 +146,18 @@ public JsonSchemaFactory build() {
138146
private final String defaultMetaSchemaURI;
139147
private final URISchemeFactory uriFactory;
140148
private final URISchemeFetcher uriFetcher;
149+
private final URNFactory urnFactory;
141150
private final Map<String, JsonMetaSchema> jsonMetaSchemas;
142151
private final Map<String, String> uriMap;
143152
private final ConcurrentMap<URI, JsonSchema> uriSchemaCache = new ConcurrentHashMap<URI, JsonSchema>();
144153

154+
145155
private JsonSchemaFactory(
146156
final ObjectMapper mapper,
147157
final String defaultMetaSchemaURI,
148158
final URISchemeFactory uriFactory,
149159
final URISchemeFetcher uriFetcher,
160+
final URNFactory urnFactory,
150161
final Map<String, JsonMetaSchema> jsonMetaSchemas,
151162
final Map<String, String> uriMap) {
152163
if (mapper == null) {
@@ -174,6 +185,7 @@ private JsonSchemaFactory(
174185
this.defaultMetaSchemaURI = defaultMetaSchemaURI;
175186
this.uriFactory = uriFactory;
176187
this.uriFetcher = uriFetcher;
188+
this.urnFactory = urnFactory;
177189
this.jsonMetaSchemas = jsonMetaSchemas;
178190
this.uriMap = uriMap;
179191
}
@@ -258,7 +270,7 @@ protected JsonSchema newJsonSchema(final URI schemaUri, final JsonNode schemaNod
258270

259271
protected ValidationContext createValidationContext(final JsonNode schemaNode) {
260272
final JsonMetaSchema jsonMetaSchema = findMetaSchemaForSchema(schemaNode);
261-
return new ValidationContext(this.uriFactory, jsonMetaSchema, this, null);
273+
return new ValidationContext(this.uriFactory, this.urnFactory, jsonMetaSchema, this, null);
262274
}
263275

264276
private JsonMetaSchema findMetaSchemaForSchema(final JsonNode schemaNode) {
@@ -330,7 +342,7 @@ public JsonSchema getSchema(final URI schemaUri, final SchemaValidatorsConfig co
330342

331343
JsonSchema jsonSchema;
332344
if (idMatchesSourceUri(jsonMetaSchema, schemaNode, schemaUri)) {
333-
jsonSchema = new JsonSchema(new ValidationContext(this.uriFactory, jsonMetaSchema, this, config), mappedUri, schemaNode, true /*retrieved via id, resolving will not change anything*/);
345+
jsonSchema = new JsonSchema(new ValidationContext(this.uriFactory, this.urnFactory, jsonMetaSchema, this, config), mappedUri, schemaNode, true /*retrieved via id, resolving will not change anything*/);
334346
} else {
335347
final ValidationContext validationContext = createValidationContext(schemaNode);
336348
validationContext.setConfig(config);

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import com.fasterxml.jackson.databind.JsonNode;
2020
import com.networknt.schema.uri.URIFactory;
21+
import com.networknt.schema.urn.URNFactory;
2122
import org.slf4j.Logger;
2223
import org.slf4j.LoggerFactory;
2324

@@ -60,7 +61,15 @@ static JsonSchemaRef getRefSchema(JsonSchema parentSchema, ValidationContext val
6061
// account the current uri of the parent schema.
6162
URI schemaUri = determineSchemaUri(validationContext.getURIFactory(), parentSchema, refUri);
6263
if (schemaUri == null) {
63-
return null;
64+
// the URNFactory is optional
65+
if (validationContext.getURNFactory() == null) {
66+
return null;
67+
}
68+
// If the uri dose't determinate try to determinate with urn factory
69+
schemaUri = determineSchemaUrn(validationContext.getURNFactory(), refUri);
70+
if (schemaUri == null) {
71+
return null;
72+
}
6473
}
6574

6675
// This should retrieve schemas regardless of the protocol that is in the uri.
@@ -106,6 +115,16 @@ private static URI determineSchemaUri(final URIFactory uriFactory, final JsonSch
106115
return schemaUri;
107116
}
108117

118+
private static URI determineSchemaUrn(final URNFactory urnFactory, final String refUri) {
119+
URI schemaUrn;
120+
try {
121+
schemaUrn = urnFactory.create(refUri);
122+
} catch (IllegalArgumentException e) {
123+
schemaUrn = null;
124+
}
125+
return schemaUrn;
126+
}
127+
109128
public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
110129
debug(logger, node, rootNode, at);
111130

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,20 @@
1818

1919
import com.fasterxml.jackson.databind.JsonNode;
2020
import com.networknt.schema.uri.URIFactory;
21+
import com.networknt.schema.urn.URNFactory;
2122

2223
import java.util.HashMap;
2324
import java.util.Map;
2425

2526
public class ValidationContext {
2627
private final URIFactory uriFactory;
28+
private final URNFactory urnFactory;
2729
private final JsonMetaSchema metaSchema;
2830
private final JsonSchemaFactory jsonSchemaFactory;
2931
private SchemaValidatorsConfig config;
3032
private final Map<String, JsonSchemaRef> refParsingInProgress = new HashMap<String, JsonSchemaRef>();
3133

32-
public ValidationContext(URIFactory uriFactory, JsonMetaSchema metaSchema, JsonSchemaFactory jsonSchemaFactory, SchemaValidatorsConfig config) {
34+
public ValidationContext(URIFactory uriFactory, URNFactory urnFactory, JsonMetaSchema metaSchema, JsonSchemaFactory jsonSchemaFactory, SchemaValidatorsConfig config) {
3335
if (uriFactory == null) {
3436
throw new IllegalArgumentException("URIFactory must not be null");
3537
}
@@ -40,6 +42,7 @@ public ValidationContext(URIFactory uriFactory, JsonMetaSchema metaSchema, JsonS
4042
throw new IllegalArgumentException("JsonSchemaFactory must not be null");
4143
}
4244
this.uriFactory = uriFactory;
45+
this.urnFactory = urnFactory;
4346
this.metaSchema = metaSchema;
4447
this.jsonSchemaFactory = jsonSchemaFactory;
4548
this.config = config;
@@ -58,6 +61,10 @@ public URIFactory getURIFactory() {
5861
return this.uriFactory;
5962
}
6063

64+
public URNFactory getURNFactory() {
65+
return this.urnFactory;
66+
}
67+
6168
public JsonSchemaFactory getJsonSchemaFactory() {
6269
return jsonSchemaFactory;
6370
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.networknt.schema.urn;
2+
3+
import java.net.URI;
4+
5+
public interface URNFactory
6+
{
7+
/**
8+
* @param urn Some urn string.
9+
* @return The converted {@link URI}.
10+
* @throws IllegalArgumentException if there was a problem creating the {@link URI} with the given data.
11+
*/
12+
URI create(String urn);
13+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.networknt.schema;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import com.networknt.schema.uri.ClasspathURLFactory;
5+
import com.networknt.schema.uri.URLFactory;
6+
import com.networknt.schema.urn.URNFactory;
7+
import org.junit.Test;
8+
9+
import java.io.IOException;
10+
import java.io.InputStream;
11+
import java.net.URI;
12+
import java.net.URL;
13+
14+
import static org.junit.Assert.assertEquals;
15+
16+
public class UrnTest
17+
{
18+
private final ObjectMapper mapper = new ObjectMapper();
19+
private final ClasspathURLFactory classpathURLFactory = new ClasspathURLFactory();
20+
private final URLFactory urlFactory = new URLFactory();
21+
22+
/**
23+
* Validate that a JSON URI Mapping file containing the URI Mapping schema is
24+
* schema valid.
25+
*
26+
* @throws IOException if unable to parse the mapping file
27+
*/
28+
@Test
29+
public void testURNToURI() throws Exception {
30+
URL urlTestData = ClasspathURLFactory.convert(
31+
this.classpathURLFactory.create("resource:draft7/urn/test.json"));
32+
33+
URNFactory urnFactory = new URNFactory()
34+
{
35+
@Override public URI create(String urn)
36+
{
37+
try {
38+
URL absoluteURL = ClasspathURLFactory.convert(new ClasspathURLFactory().create(String.format("resource:draft7/urn/%s.schema.json", urn)));
39+
return absoluteURL.toURI();
40+
} catch (Exception ex) {
41+
return null;
42+
}
43+
}
44+
};
45+
46+
InputStream is = null;
47+
try {
48+
is = new URL("https://raw.githubusercontent.com/francesc79/json-schema-validator/feature/urn-management/src/test/resources/draft7/urn/urn.schema.json").openStream();
49+
JsonMetaSchema draftV7 = JsonMetaSchema.getV7();
50+
JsonSchemaFactory.Builder builder = JsonSchemaFactory.builder()
51+
.defaultMetaSchemaURI(draftV7.getUri())
52+
.addMetaSchema(draftV7)
53+
.addUrnFactory(urnFactory);
54+
JsonSchemaFactory instance = builder.build();
55+
JsonSchema schema = instance.getSchema(is);
56+
assertEquals(0, schema.validate(mapper.readTree(urlTestData)).size());
57+
} catch( Exception e) {
58+
e.printStackTrace();
59+
}
60+
finally {
61+
if (is != null) {
62+
is.close();
63+
}
64+
}
65+
}
66+
}
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-07/schema#",
3+
"title": "account",
4+
"type": "object",
5+
"properties": {
6+
"first-name": {
7+
"type": "string"
8+
},
9+
"age": {
10+
"type": "integer"
11+
}
12+
}
13+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"account": {
3+
"first-name": "Test",
4+
"age": 18
5+
}
6+
}
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-07/schema#",
3+
"title": "schema-with-urn-ref",
4+
"type": "object",
5+
"properties": {
6+
"account": {
7+
"$ref": "account"
8+
}
9+
}
10+
}

0 commit comments

Comments
 (0)