diff options
author | Jon Marius Venstad <jonmv@gmail.com> | 2022-04-06 19:35:30 +0200 |
---|---|---|
committer | Jon Marius Venstad <jonmv@gmail.com> | 2022-04-06 19:35:30 +0200 |
commit | 039589faf5f989d80b9fec2b28ed955ac6fd86f6 (patch) | |
tree | 45c314cc9ede2d5c26a5d6b4f030ad3db2246a91 /container-core | |
parent | ec92b5f8882e400f94b851dffcf0b3511373e890 (diff) |
Use HttpURL.Path for Path.getRest()
Diffstat (limited to 'container-core')
6 files changed, 40 insertions, 22 deletions
diff --git a/container-core/src/main/java/com/yahoo/restapi/HttpURL.java b/container-core/src/main/java/com/yahoo/restapi/HttpURL.java index 9705b6f0e40..e890b0fe71a 100644 --- a/container-core/src/main/java/com/yahoo/restapi/HttpURL.java +++ b/container-core/src/main/java/com/yahoo/restapi/HttpURL.java @@ -223,14 +223,24 @@ public class HttpURL { segment, "path segments cannot be \"\", \".\", or \"..\""); } + /** Returns a copy of this where only the first segments are retained, and with a trailing slash. */ + public Path head(int count) { + return count == segments.size() ? this : new Path(segments.subList(0, count), true, validator); + } + + /** Returns a copy of this where only the last segments are retained. */ + public Path tail(int count) { + return count == segments.size() ? this : new Path(segments.subList(segments.size() - count, segments.size()), trailingSlash, validator); + } + /** Returns a copy of this where the first segments are skipped. */ public Path skip(int count) { - return new Path(segments.subList(count, segments.size()), trailingSlash, validator); + return count == 0 ? this : new Path(segments.subList(count, segments.size()), trailingSlash, validator); } - /** Returns a copy of this where the last segments are cut off. */ + /** Returns a copy of this where the last segments are cut off, and with a trailing slash. */ public Path cut(int count) { - return new Path(segments.subList(0, segments.size() - count), trailingSlash, validator); + return count == 0 ? this : new Path(segments.subList(0, segments.size() - count), true, validator); } /** Returns a copy of this with the <em>decoded</em> segment appended at the end; it may not be either of {@code ""}, {@code "."} or {@code ".."}. */ @@ -254,6 +264,11 @@ public class HttpURL { return new Path(copy, trailingSlash, validator); } + /** Whether this path has a trailing slash. */ + public boolean hasTrailingSlash() { + return trailingSlash; + } + /** Returns a copy of this which encodes a trailing slash. */ public Path withTrailingSlash() { return new Path(segments, true, validator); diff --git a/container-core/src/main/java/com/yahoo/restapi/Path.java b/container-core/src/main/java/com/yahoo/restapi/Path.java index 8a494d47be4..c639432db89 100644 --- a/container-core/src/main/java/com/yahoo/restapi/Path.java +++ b/container-core/src/main/java/com/yahoo/restapi/Path.java @@ -66,11 +66,9 @@ public class Path { else if ( ! specElements.get(i).equals(path.segments().get(i))) return false; } - - if (matchPrefix) { - this.rest = path.skip(specElements.size()); - } - + + rest = matchPrefix ? path.skip(specElements.size()) : null; + return true; } @@ -99,12 +97,10 @@ public class Path { } /** - * Returns the rest of the last matched path. - * This is always the empty string (never null) unless the path spec ends with {*} + * Returns the rest of the last matched path, or {@code null} if the path spec didn't end with {*}. */ - public String getRest() { - String raw = rest.raw(); - return raw.isEmpty() ? raw : raw.substring(1); + public HttpURL.Path getRest() { + return rest; } @Override diff --git a/container-core/src/main/java/com/yahoo/restapi/RestApi.java b/container-core/src/main/java/com/yahoo/restapi/RestApi.java index d6cc0cccf3f..353ac3eb5cc 100644 --- a/container-core/src/main/java/com/yahoo/restapi/RestApi.java +++ b/container-core/src/main/java/com/yahoo/restapi/RestApi.java @@ -153,7 +153,9 @@ public interface RestApi { default double getDoubleOrThrow(String name) { return Double.parseDouble(getStringOrThrow(name)); } } - interface PathParameters extends Parameters {} + interface PathParameters extends Parameters { + Optional<HttpURL.Path> getRest(); + } interface QueryParameters extends Parameters { List<String> getStringList(String name); } diff --git a/container-core/src/main/java/com/yahoo/restapi/RestApiImpl.java b/container-core/src/main/java/com/yahoo/restapi/RestApiImpl.java index 09de7ffa133..cc243a3e92b 100644 --- a/container-core/src/main/java/com/yahoo/restapi/RestApiImpl.java +++ b/container-core/src/main/java/com/yahoo/restapi/RestApiImpl.java @@ -429,16 +429,16 @@ class RestApiImpl implements RestApi { private class PathParametersImpl implements RestApi.RequestContext.PathParameters { @Override public Optional<String> getString(String name) { - if (name.equals("*")) { - String rest = pathMatcher.getRest(); - return rest.isEmpty() ? Optional.empty() : Optional.of(rest); - } return Optional.ofNullable(pathMatcher.get(name)); } @Override public String getStringOrThrow(String name) { return getString(name) .orElseThrow(() -> new RestApiException.BadRequest("Path parameter '" + name + "' is missing")); } + @Override public Optional<HttpURL.Path> getRest() { + return Optional.ofNullable(pathMatcher.getRest()); + } + } private class QueryParametersImpl implements RestApi.RequestContext.QueryParameters { diff --git a/container-core/src/test/java/com/yahoo/restapi/HttpURLTest.java b/container-core/src/test/java/com/yahoo/restapi/HttpURLTest.java index 05a218b0f04..858513c2a69 100644 --- a/container-core/src/test/java/com/yahoo/restapi/HttpURLTest.java +++ b/container-core/src/test/java/com/yahoo/restapi/HttpURLTest.java @@ -124,6 +124,11 @@ class HttpURLTest { assertEquals(List.of(expected.get(2), expected.get(0)), path.append(path).cut(2).skip(2).segments()); + for (int i = 0; i < 3; i++) { + assertEquals(path.head(i), path.cut(3 - i)); + assertEquals(path.tail(i), path.skip(3 - i)); + } + assertThrows(NullPointerException.class, () -> path.append((String) null)); diff --git a/container-core/src/test/java/com/yahoo/restapi/PathTest.java b/container-core/src/test/java/com/yahoo/restapi/PathTest.java index 065b02be0e4..4786eb9775c 100644 --- a/container-core/src/test/java/com/yahoo/restapi/PathTest.java +++ b/container-core/src/test/java/com/yahoo/restapi/PathTest.java @@ -35,7 +35,7 @@ public class PathTest { assertTrue(path.matches("/a/{foo}/bar/{b}/{*}")); assertEquals("1", path.get("foo")); assertEquals("fuz", path.get("b")); - assertEquals("", path.getRest()); + assertEquals("/", path.getRest().raw()); } { @@ -43,7 +43,7 @@ public class PathTest { assertTrue(path.matches("/a/{foo}/bar/{b}/{*}")); assertEquals("1", path.get("foo")); assertEquals("fuz", path.get("b")); - assertEquals("kanoo", path.getRest()); + assertEquals("/kanoo", path.getRest().raw()); } { @@ -51,7 +51,7 @@ public class PathTest { assertTrue(path.matches("/a/{foo}/bar/{b}/{*}")); assertEquals("1", path.get("foo")); assertEquals("fuz", path.get("b")); - assertEquals("kanoo/trips", path.getRest()); + assertEquals("/kanoo/trips", path.getRest().raw()); } { @@ -59,7 +59,7 @@ public class PathTest { assertTrue(path.matches("/a/{foo}/bar/{b}/{*}")); assertEquals("1", path.get("foo")); assertEquals("fuz", path.get("b")); - assertEquals("kanoo/trips/", path.getRest()); + assertEquals("/kanoo/trips/", path.getRest().raw()); } } |