Skip to content

Commit 0a64900

Browse files
author
Jake Waffle
committed
Finished adding support for URIs. Standard URLs and the classpath URLs are handled by default, but can be overwritten.
1 parent 28d5a62 commit 0a64900

20 files changed

+558
-163
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ private static JsonSchema obtainSubSchemaNode(final JsonNode schemaNode, final V
8282
else {
8383
final URI uri;
8484
try {
85-
uri = URI.create(node.textValue());
85+
uri = validationContext.getJsonSchemaFactory().getURIFactory().create(node.textValue());
8686
} catch (IllegalArgumentException e) {
8787
return null;
8888
}

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,11 @@ private URI combineCurrentUriWithIds(URI currentUri, JsonNode schemaNode) {
8080
if (idNode == null) {
8181
return currentUri;
8282
} else {
83-
try {
84-
return currentUri.resolve(idNode.asText());
85-
} catch (IllegalArgumentException e) {
86-
throw new JsonSchemaException(ValidationMessage.of(ValidatorTypeCode.ID.getValue(), ValidatorTypeCode.ID, idNode.asText(), currentUri.toString()));
87-
}
83+
try {
84+
return this.validationContext.getJsonSchemaFactory().getURIFactory().create(currentUri, idNode.asText());
85+
} catch (IllegalArgumentException e) {
86+
throw new JsonSchemaException(ValidationMessage.of(ValidatorTypeCode.ID.getValue(), ValidatorTypeCode.ID, idNode.asText(), currentUri.toString()));
87+
}
8888
}
8989
}
9090

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

Lines changed: 76 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,14 @@
2828

2929
import com.fasterxml.jackson.databind.JsonNode;
3030
import com.fasterxml.jackson.databind.ObjectMapper;
31-
import com.networknt.schema.uri.ClasspathURIFetcher;
32-
import com.networknt.schema.uri.DefaultURLFetcher;
31+
import com.networknt.schema.uri.ClasspathURLFactory;
32+
import com.networknt.schema.uri.ClasspathURLFetcher;
33+
import com.networknt.schema.uri.URIFactory;
3334
import com.networknt.schema.uri.URIFetcher;
35+
import com.networknt.schema.uri.URISchemeFactory;
36+
import com.networknt.schema.uri.URISchemeFetcher;
37+
import com.networknt.schema.uri.URLFactory;
38+
import com.networknt.schema.uri.URLFetcher;
3439

3540
public class JsonSchemaFactory {
3641
private static final Logger logger = LoggerFactory
@@ -39,40 +44,69 @@ public class JsonSchemaFactory {
3944

4045
public static class Builder {
4146
private ObjectMapper objectMapper = new ObjectMapper();
42-
private Map<String, URIFetcher> uriFetcherMap = new HashMap<String, URIFetcher>();
4347
private String defaultMetaSchemaURI;
44-
private Map<String, JsonMetaSchema> jsonMetaSchemas = new HashMap<String, JsonMetaSchema>();
45-
private Map<String, String> uriMap = new HashMap<String, String>();
48+
private final Map<String, URIFactory> uriFactoryMap = new HashMap<String, URIFactory>();
49+
private final Map<String, URIFetcher> uriFetcherMap = new HashMap<String, URIFetcher>();
50+
private final Map<String, JsonMetaSchema> jsonMetaSchemas = new HashMap<String, JsonMetaSchema>();
51+
private final Map<String, String> uriMap = new HashMap<String, String>();
4652

4753
public Builder() {
48-
// By default we add support for custom classpath URIs.
49-
final URIFetcher classpathUriFetcher = new ClasspathURIFetcher();
50-
for (final String scheme : ClasspathURIFetcher.SUPPORTED_SCHEMES) {
51-
this.uriFetcherMap.put(scheme, classpathUriFetcher);
52-
}
54+
// Adds support for creating {@link URL}s.
55+
final URIFactory urlFactory = new URLFactory();
56+
for (final String scheme : URLFactory.SUPPORTED_SCHEMES) {
57+
this.uriFactoryMap.put(scheme, urlFactory);
58+
}
59+
60+
// Adds support for fetching with {@link URL}s.
61+
final URIFetcher urlFetcher = new URLFetcher();
62+
for (final String scheme : URLFetcher.SUPPORTED_SCHEMES) {
63+
this.uriFetcherMap.put(scheme, urlFetcher);
64+
}
65+
66+
// Adds support for creating and fetching with classpath {@link URL}s.
67+
final URIFactory classpathURLFactory = new ClasspathURLFactory();
68+
final URIFetcher classpathURLFetcher = new ClasspathURLFetcher();
69+
for (final String scheme : ClasspathURLFactory.SUPPORTED_SCHEMES) {
70+
this.uriFactoryMap.put(scheme, classpathURLFactory);
71+
this.uriFetcherMap.put(scheme, classpathURLFetcher);
72+
}
5373
}
5474

5575
public Builder objectMapper(final ObjectMapper objectMapper) {
5676
this.objectMapper = objectMapper;
5777
return this;
5878
}
5979

80+
public Builder defaultMetaSchemaURI(final String defaultMetaSchemaURI) {
81+
this.defaultMetaSchemaURI = defaultMetaSchemaURI;
82+
return this;
83+
}
84+
85+
/**
86+
* Maps a number of schemes to a {@link URIFactory}.
87+
* @param uriFactory the uri factory that will be used for the given schemes.
88+
* @param scheme the scheme that the uri factory will be assocaited with.
89+
* @return this builder.
90+
*/
91+
public Builder uriFactory(final URIFactory uriFactory, final String... schemes) {
92+
for (final String scheme : schemes)
93+
{
94+
this.uriFactoryMap.put(scheme, uriFactory);
95+
}
96+
return this;
97+
}
98+
6099
/**
61-
* Maps a number of scheme to a {@link URIFetcher}.
100+
* Maps a number of schemes to a {@link URIFetcher}.
62101
* @param uriFetcher the uri fetcher that will be used for the given schemes.
63102
* @param scheme the scheme that the uri fetcher will be assocaited with.
64103
* @return this builder.
65104
*/
66105
public Builder uriFetcher(final URIFetcher uriFetcher, final String... schemes) {
67106
for (final String scheme : schemes)
68-
{
107+
{
69108
this.uriFetcherMap.put(scheme, uriFetcher);
70-
}
71-
return this;
72-
}
73-
74-
public Builder defaultMetaSchemaURI(final String defaultMetaSchemaURI) {
75-
this.defaultMetaSchemaURI = defaultMetaSchemaURI;
109+
}
76110
return this;
77111
}
78112

@@ -97,37 +131,41 @@ public JsonSchemaFactory build() {
97131
// create builtin keywords with (custom) formats.
98132
return new JsonSchemaFactory(
99133
objectMapper == null ? new ObjectMapper() : objectMapper,
100-
uriFetcherMap,
101134
defaultMetaSchemaURI,
135+
new URISchemeFactory(uriFactoryMap),
136+
new URISchemeFetcher(uriFetcherMap),
102137
jsonMetaSchemas,
103138
uriMap
104139
);
105140
}
106141
}
107142

108-
private static final URIFetcher DEFAULT_URI_FETCHER = new DefaultURLFetcher();
109-
110143
private final ObjectMapper mapper;
111-
private final Map<String, URIFetcher> uriFetcherMap;
112144
private final String defaultMetaSchemaURI;
145+
private final URISchemeFactory uriFactory;
146+
private final URISchemeFetcher uriFetcher;
113147
private final Map<String, JsonMetaSchema> jsonMetaSchemas;
114148
private final Map<String, String> uriMap;
115149

116150
private JsonSchemaFactory(
117151
final ObjectMapper mapper,
118-
final Map<String, URIFetcher> uriFetcherMap,
119152
final String defaultMetaSchemaURI,
153+
final URISchemeFactory uriFactory,
154+
final URISchemeFetcher uriFetcher,
120155
final Map<String, JsonMetaSchema> jsonMetaSchemas,
121156
final Map<String, String> uriMap) {
122157
if (mapper == null) {
123158
throw new IllegalArgumentException("ObjectMapper must not be null");
124159
}
125-
if (uriFetcherMap == null) {
126-
throw new IllegalArgumentException("URLFetcher must not be null");
127-
}
128160
if (defaultMetaSchemaURI == null || defaultMetaSchemaURI.trim().isEmpty()) {
129161
throw new IllegalArgumentException("defaultMetaSchemaURI must not be null or empty");
130162
}
163+
if (uriFactory == null) {
164+
throw new IllegalArgumentException("URIFactory must not be null");
165+
}
166+
if (uriFetcher == null) {
167+
throw new IllegalArgumentException("URIFetcher must not be null");
168+
}
131169
if (jsonMetaSchemas == null || jsonMetaSchemas.isEmpty()) {
132170
throw new IllegalArgumentException("Json Meta Schemas must not be null or empty");
133171
}
@@ -139,7 +177,8 @@ private JsonSchemaFactory(
139177
}
140178
this.mapper = mapper;
141179
this.defaultMetaSchemaURI = defaultMetaSchemaURI;
142-
this.uriFetcherMap = uriFetcherMap;
180+
this.uriFactory = uriFactory;
181+
this.uriFetcher = uriFetcher;
143182
this.jsonMetaSchemas = jsonMetaSchemas;
144183
this.uriMap = uriMap;
145184
}
@@ -174,7 +213,11 @@ public static Builder builder(final JsonSchemaFactory blueprint) {
174213
.objectMapper(blueprint.mapper)
175214
.addUriMappings(blueprint.uriMap);
176215

177-
for (Map.Entry<String, URIFetcher> entry : blueprint.uriFetcherMap.entrySet())
216+
for (Map.Entry<String, URIFactory> entry : blueprint.uriFactory.getURIFactories().entrySet())
217+
{
218+
builder = builder.uriFactory(entry.getValue(), entry.getKey());
219+
}
220+
for (Map.Entry<String, URIFetcher> entry : blueprint.uriFetcher.getURIFetchers().entrySet())
178221
{
179222
builder = builder.uriFetcher(entry.getValue(), entry.getKey());
180223
}
@@ -202,6 +245,10 @@ private JsonMetaSchema findMetaSchemaForSchema(final JsonNode schemaNode) {
202245
}
203246
return jsonMetaSchema;
204247
}
248+
249+
public URIFactory getURIFactory() {
250+
return this.uriFactory;
251+
}
205252

206253
public JsonSchema getSchema(final String schema, final SchemaValidatorsConfig config) {
207254
try {
@@ -245,8 +292,7 @@ public JsonSchema getSchema(final URI schemaUri, final SchemaValidatorsConfig co
245292
throw new JsonSchemaException(e);
246293
}
247294
try {
248-
final URIFetcher uriFetcher = this.uriFetcherMap.getOrDefault(mappedUri.getScheme(), DEFAULT_URI_FETCHER);
249-
inputStream = uriFetcher.fetch(mappedUri);
295+
inputStream = this.uriFetcher.fetch(mappedUri);
250296
final JsonNode schemaNode = mapper.readTree(inputStream);
251297
final JsonMetaSchema jsonMetaSchema = findMetaSchemaForSchema(schemaNode);
252298

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.slf4j.LoggerFactory;
2626

2727
import com.fasterxml.jackson.databind.JsonNode;
28+
import com.networknt.schema.uri.URIFactory;
2829

2930
public class RefValidator extends BaseJsonValidator implements JsonValidator {
3031
private static final Logger logger = LoggerFactory.getLogger(RefValidator.class);
@@ -56,7 +57,7 @@ static JsonSchema getRefSchema(JsonSchema parentSchema, ValidationContext valida
5657

5758
// This will determine the correct absolute uri for the refUri. This decision will take into
5859
// account the current uri of the parent schema.
59-
URI schemaUri = determineSchemaUri(parentSchema, refUri);
60+
URI schemaUri = determineSchemaUri(validationContext.getJsonSchemaFactory().getURIFactory(), parentSchema, refUri);
6061
if (schemaUri == null) {
6162
return null;
6263
}
@@ -81,18 +82,18 @@ static JsonSchema getRefSchema(JsonSchema parentSchema, ValidationContext valida
8182
return null;
8283
}
8384

84-
private static URI determineSchemaUri(final JsonSchema parentSchema, final String refUri) {
85+
private static URI determineSchemaUri(final URIFactory uriFactory, final JsonSchema parentSchema, final String refUri) {
8586
URI schemaUri;
8687
final URI currentUri = parentSchema.getCurrentUri();
8788
try
8889
{
8990
if (currentUri == null)
9091
{
91-
schemaUri = URI.create(refUri);
92+
schemaUri = uriFactory.create(refUri);
9293
}
9394
else
9495
{
95-
schemaUri = currentUri.resolve(URI.create(refUri));
96+
schemaUri = uriFactory.create(currentUri, refUri);
9697
}
9798
} catch (IllegalArgumentException e) {
9899
schemaUri = null;

src/main/java/com/networknt/schema/uri/ClasspathURIFetcher.java

Lines changed: 0 additions & 77 deletions
This file was deleted.

0 commit comments

Comments
 (0)