Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions src/main/java/com/networknt/schema/JsonSchemaFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public static class Builder {
private final Map<String, JsonMetaSchema> jsonMetaSchemas = new HashMap<String, JsonMetaSchema>();
private final Map<String, String> uriMap = new HashMap<String, String>();
private boolean forceHttps = true;
private boolean removeEmptyFragmentSuffix = true;

public Builder() {
// Adds support for creating {@link URL}s.
Expand Down Expand Up @@ -145,6 +145,11 @@ public Builder forceHttps(boolean forceHttps) {
return this;
}

public Builder removeEmptyFragmentSuffix(boolean removeEmptyFragmentSuffix) {
this.removeEmptyFragmentSuffix = removeEmptyFragmentSuffix;
return this;
}

public JsonSchemaFactory build() {
// create builtin keywords with (custom) formats.
return new JsonSchemaFactory(
Expand All @@ -155,7 +160,8 @@ public JsonSchemaFactory build() {
urnFactory,
jsonMetaSchemas,
uriMap,
forceHttps
forceHttps,
removeEmptyFragmentSuffix
);
}
}
Expand All @@ -169,6 +175,7 @@ public JsonSchemaFactory build() {
private final Map<String, String> uriMap;
private final ConcurrentMap<URI, JsonSchema> uriSchemaCache = new ConcurrentHashMap<URI, JsonSchema>();
private final boolean forceHttps;
private final boolean removeEmptyFragmentSuffix;


private JsonSchemaFactory(
Expand All @@ -179,7 +186,8 @@ private JsonSchemaFactory(
final URNFactory urnFactory,
final Map<String, JsonMetaSchema> jsonMetaSchemas,
final Map<String, String> uriMap,
final boolean forceHttps) {
final boolean forceHttps,
final boolean removeEmptyFragmentSuffix) {
if (mapper == null) {
throw new IllegalArgumentException("ObjectMapper must not be null");
} else if (defaultMetaSchemaURI == null || defaultMetaSchemaURI.trim().isEmpty()) {
Expand All @@ -203,6 +211,7 @@ private JsonSchemaFactory(
this.jsonMetaSchemas = jsonMetaSchemas;
this.uriMap = uriMap;
this.forceHttps = forceHttps;
this.removeEmptyFragmentSuffix = removeEmptyFragmentSuffix;
}

/**
Expand Down Expand Up @@ -281,7 +290,7 @@ protected ValidationContext createValidationContext(final JsonNode schemaNode) {

private JsonMetaSchema findMetaSchemaForSchema(final JsonNode schemaNode) {
final JsonNode uriNode = schemaNode.get("$schema");
final String uri = uriNode == null || uriNode.isNull() ? defaultMetaSchemaURI : normalizeMetaSchemaUri(uriNode.textValue(), forceHttps);
final String uri = uriNode == null || uriNode.isNull() ? defaultMetaSchemaURI : normalizeMetaSchemaUri(uriNode.textValue(), forceHttps, removeEmptyFragmentSuffix);
final JsonMetaSchema jsonMetaSchema = jsonMetaSchemas.get(uri);
if (jsonMetaSchema == null) {
throw new JsonSchemaException("Unknown MetaSchema: " + uri);
Expand Down Expand Up @@ -409,12 +418,17 @@ private boolean idMatchesSourceUri(final JsonMetaSchema metaSchema, final JsonNo
return result;
}

static protected String normalizeMetaSchemaUri(String u, boolean forceHttps) {
static protected String normalizeMetaSchemaUri(String u, boolean forceHttps, boolean removeEmptyFragmentSuffix) {
try {
URI uri = new URI(u);
String scheme = forceHttps ? "https" : uri.getScheme();
URI newUri = new URI(scheme, uri.getUserInfo(), uri.getHost(), uri.getPort(), uri.getPath(), null, null);
return newUri.toString();

if (!removeEmptyFragmentSuffix && u.endsWith("#")) {
return newUri + "#";
} else {
return newUri.toString();
}
} catch (URISyntaxException e) {
throw new JsonSchemaException("Wrong MetaSchema URI: " + u);
}
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/com/networknt/schema/SpecVersionDetector.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ public static SpecVersion.VersionFlag detect(JsonNode jsonNode) {
if (!jsonNode.has(SCHEMA_TAG))
throw new JsonSchemaException("Schema tag not present");

String schemaUri = JsonSchemaFactory.normalizeMetaSchemaUri(jsonNode.get(SCHEMA_TAG).asText(), true);
final boolean forceHttps = true;
final boolean removeEmptyFragmentSuffix = true;

String schemaUri = JsonSchemaFactory.normalizeMetaSchemaUri(jsonNode.get(SCHEMA_TAG).asText(), forceHttps, removeEmptyFragmentSuffix);
if (schemaUri.equals(JsonMetaSchema.getV4().getUri()))
return SpecVersion.VersionFlag.V4;
else if (schemaUri.equals(JsonMetaSchema.getV6().getUri()))
Expand Down
30 changes: 30 additions & 0 deletions src/test/java/com/networknt/schema/Issue518Test.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.networknt.schema;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.io.InputStream;

public class Issue518Test {
private static final JsonMetaSchema igluMetaSchema =
JsonMetaSchema
.builder("http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#", JsonMetaSchema.getV7())
.build();

private static final JsonSchemaFactory FACTORY =
JsonSchemaFactory
.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7))
.addMetaSchema(igluMetaSchema)
.forceHttps(false)
.removeEmptyFragmentSuffix(false)
.build();

@Test
public void testPreservingEmptyFragmentSuffix() {
String schemaPath = "/schema/issue518-v7.json";
InputStream schemaInputStream = getClass().getResourceAsStream(schemaPath);
JsonSchema schema = FACTORY.getSchema(schemaInputStream);

Assertions.assertNotNull(schema);
}
}
46 changes: 42 additions & 4 deletions src/test/java/com/networknt/schema/UnknownMetaSchemaTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,53 @@ public void testSchema3() throws IOException {

@Test
public void testNormalize() throws JsonSchemaException {
final boolean forceHttps = true;
final boolean removeEmptyFragmentSuffix = true;

String uri01 = "http://json-schema.org/draft-07/schema";
String uri02 = "http://json-schema.org/draft-07/schema#";
String uri03 = "http://json-schema.org/draft-07/schema?key=value";
String uri04 = "http://json-schema.org/draft-07/schema?key=value&key2=value2";
String expected = "https://json-schema.org/draft-07/schema";
Assertions.assertEquals(expected, JsonSchemaFactory.normalizeMetaSchemaUri(uri01, true));
Assertions.assertEquals(expected, JsonSchemaFactory.normalizeMetaSchemaUri(uri02, true));
Assertions.assertEquals(expected, JsonSchemaFactory.normalizeMetaSchemaUri(uri03, true));
Assertions.assertEquals(expected, JsonSchemaFactory.normalizeMetaSchemaUri(uri04, true));

Assertions.assertEquals(expected, JsonSchemaFactory.normalizeMetaSchemaUri(uri01, forceHttps, removeEmptyFragmentSuffix));
Assertions.assertEquals(expected, JsonSchemaFactory.normalizeMetaSchemaUri(uri02, forceHttps, removeEmptyFragmentSuffix));
Assertions.assertEquals(expected, JsonSchemaFactory.normalizeMetaSchemaUri(uri03, forceHttps, removeEmptyFragmentSuffix));
Assertions.assertEquals(expected, JsonSchemaFactory.normalizeMetaSchemaUri(uri04, forceHttps, removeEmptyFragmentSuffix));

}

@Test
public void testNormalizeForceHttpsDisabled() throws JsonSchemaException {
final boolean forceHttps = false;
final boolean removeEmptyFragmentSuffix = true;

String uri01 = "http://json-schema.org/draft-07/schema";
String uri02 = "http://json-schema.org/draft-07/schema#";
String uri03 = "http://json-schema.org/draft-07/schema?key=value";
String uri04 = "http://json-schema.org/draft-07/schema?key=value&key2=value2";
String expected = "http://json-schema.org/draft-07/schema";

Assertions.assertEquals(expected, JsonSchemaFactory.normalizeMetaSchemaUri(uri01, forceHttps, removeEmptyFragmentSuffix));
Assertions.assertEquals(expected, JsonSchemaFactory.normalizeMetaSchemaUri(uri02, forceHttps, removeEmptyFragmentSuffix));
Assertions.assertEquals(expected, JsonSchemaFactory.normalizeMetaSchemaUri(uri03, forceHttps, removeEmptyFragmentSuffix));
Assertions.assertEquals(expected, JsonSchemaFactory.normalizeMetaSchemaUri(uri04, forceHttps, removeEmptyFragmentSuffix));

}

@Test
public void testNormalizeRemovingEmptyFragmentSuffixDisabled() throws JsonSchemaException {
final boolean forceHttps = true;
final boolean removeEmptyFragmentSuffix = false;

String uri01 = "http://json-schema.org/draft-07/schema#";
String uri02 = "http://json-schema.org/draft-07/schema?key=value#";
String uri03 = "http://json-schema.org/draft-07/schema?key=value&key2=value2#";
String expected = "https://json-schema.org/draft-07/schema#";

Assertions.assertEquals(expected, JsonSchemaFactory.normalizeMetaSchemaUri(uri01, forceHttps, removeEmptyFragmentSuffix));
Assertions.assertEquals(expected, JsonSchemaFactory.normalizeMetaSchemaUri(uri02, forceHttps, removeEmptyFragmentSuffix));
Assertions.assertEquals(expected, JsonSchemaFactory.normalizeMetaSchemaUri(uri03, forceHttps, removeEmptyFragmentSuffix));

}
}
4 changes: 4 additions & 0 deletions src/test/resources/schema/issue518-v7.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"type": "object"
}