diff --git a/src/main/java/com/networknt/schema/SchemaLocation.java b/src/main/java/com/networknt/schema/SchemaLocation.java index d1b5f33b..2257e36e 100644 --- a/src/main/java/com/networknt/schema/SchemaLocation.java +++ b/src/main/java/com/networknt/schema/SchemaLocation.java @@ -142,17 +142,24 @@ public SchemaLocation resolve(String absoluteIriReferenceOrFragment) { return new SchemaLocation(this.getAbsoluteIri(), JSON_POINTER); } JsonNodePath fragment = JSON_POINTER; - String[] parts = absoluteIriReferenceOrFragment.split("#"); + int index = absoluteIriReferenceOrFragment.indexOf('#'); AbsoluteIri absoluteIri = this.getAbsoluteIri(); + String part0 = index == -1 ? absoluteIriReferenceOrFragment + : absoluteIriReferenceOrFragment.substring(0, index); if (absoluteIri != null) { - if (!parts[0].isEmpty()) { - absoluteIri = absoluteIri.resolve(parts[0]); + if (!part0.isEmpty()) { + absoluteIri = absoluteIri.resolve(part0); } } else { - absoluteIri = AbsoluteIri.of(parts[0]); + absoluteIri = AbsoluteIri.of(part0); } - if (parts.length > 1 && !parts[1].isEmpty()) { - fragment = Fragment.of(parts[1]); + if (index != -1) { + if (absoluteIriReferenceOrFragment.length() > index + 1) { + String part1 = absoluteIriReferenceOrFragment.substring(index + 1); + if (!part1.isEmpty()) { + fragment = Fragment.of(part1); + } + } } return new SchemaLocation(absoluteIri, fragment); } @@ -168,18 +175,26 @@ public static String resolve(SchemaLocation schemaLocation, String absoluteIriRe if ("#".equals(absoluteIriReferenceOrFragment)) { return schemaLocation.getAbsoluteIri().toString() + "#"; } - String[] parts = absoluteIriReferenceOrFragment.split("#"); + int index = absoluteIriReferenceOrFragment.indexOf('#'); AbsoluteIri absoluteIri = schemaLocation.getAbsoluteIri(); - String resolved = parts[0]; + String part0 = index == -1 ? absoluteIriReferenceOrFragment + : absoluteIriReferenceOrFragment.substring(0, index); + String resolved = part0; if (absoluteIri != null) { - if (!parts[0].isEmpty()) { - resolved = absoluteIri.resolve(parts[0]).toString(); + if (!part0.isEmpty()) { + resolved = absoluteIri.resolve(part0).toString(); } else { resolved = absoluteIri.toString(); } } - if (parts.length > 1 && !parts[1].isEmpty()) { - resolved = resolved + "#" + parts[1]; + String part1 = ""; + if (index != -1) { + if (absoluteIriReferenceOrFragment.length() > index + 1) { + part1 = absoluteIriReferenceOrFragment.substring(index + 1); + } + } + if (!part1.isEmpty()) { + resolved = resolved + "#" + part1; } else { resolved = resolved + "#"; } diff --git a/src/test/java/com/networknt/schema/SchemaLocationTest.java b/src/test/java/com/networknt/schema/SchemaLocationTest.java index c2b29d3a..7562e2b4 100644 --- a/src/test/java/com/networknt/schema/SchemaLocationTest.java +++ b/src/test/java/com/networknt/schema/SchemaLocationTest.java @@ -74,6 +74,24 @@ void schemaLocationResolveDocumentPointer() { SchemaLocation.resolve(schemaLocation, "#/allOf/12/properties")); } + @Test + void schemaLocationResolveHashInFragment() { + SchemaLocation schemaLocation = SchemaLocation.of("https://example.com/schemas/address#street_address"); + assertEquals( + "https://example.com/schemas/address#/paths/~1subscribe/post/callbacks/myEvent/{request.body#~1callbackUrl}/post/requestBody/content/application~1json/schema", + SchemaLocation.resolve(schemaLocation, + "#/paths/~1subscribe/post/callbacks/myEvent/{request.body#~1callbackUrl}/post/requestBody/content/application~1json/schema")); + } + + @Test + void schemaLocationResolvePathHashInFragment() { + SchemaLocation schemaLocation = SchemaLocation.of("https://example.com/schemas/address#street_address"); + assertEquals( + "https://example.com/schemas/hello#/paths/~1subscribe/post/callbacks/myEvent/{request.body#~1callbackUrl}/post/requestBody/content/application~1json/schema", + SchemaLocation.resolve(schemaLocation, + "hello#/paths/~1subscribe/post/callbacks/myEvent/{request.body#~1callbackUrl}/post/requestBody/content/application~1json/schema")); + } + @Test void schemaLocationResolveEmptyString() { SchemaLocation schemaLocation = SchemaLocation.of("https://example.com/schemas/address#street_address"); @@ -105,6 +123,26 @@ void resolveDocumentPointer() { schemaLocation.resolve("#/allOf/10/properties").toString()); } + @Test + void resolveHashInFragment() { + SchemaLocation schemaLocation = SchemaLocation.of("https://example.com/schemas/address#street_address"); + assertEquals( + "https://example.com/schemas/address#/paths/~1subscribe/post/callbacks/myEvent/{request.body#~1callbackUrl}/post/requestBody/content/application~1json/schema", + schemaLocation.resolve( + "#/paths/~1subscribe/post/callbacks/myEvent/{request.body#~1callbackUrl}/post/requestBody/content/application~1json/schema") + .toString()); + } + + @Test + void resolvePathHashInFragment() { + SchemaLocation schemaLocation = SchemaLocation.of("https://example.com/schemas/address#street_address"); + assertEquals( + "https://example.com/schemas/hello#/paths/~1subscribe/post/callbacks/myEvent/{request.body#~1callbackUrl}/post/requestBody/content/application~1json/schema", + schemaLocation.resolve( + "hello#/paths/~1subscribe/post/callbacks/myEvent/{request.body#~1callbackUrl}/post/requestBody/content/application~1json/schema") + .toString()); + } + @Test void resolveEmptyString() { SchemaLocation schemaLocation = SchemaLocation.of("https://example.com/schemas/address#street_address");