diff options
author | toby <smorgrav@yahoo-inc.com> | 2019-03-15 16:58:02 +0100 |
---|---|---|
committer | toby <smorgrav@yahoo-inc.com> | 2019-03-15 16:58:02 +0100 |
commit | 5039958f9fa1d692d913ac97a5c179605f83b07e (patch) | |
tree | 80ea5812a36c68843beb94addd82ddf1f15616ed /container-core/src | |
parent | d0c0baba17829572ee5af428fcf6b068f013d55d (diff) |
Add support for an optional prefix to path matching
Diffstat (limited to 'container-core/src')
-rw-r--r-- | container-core/src/main/java/com/yahoo/restapi/Path.java | 47 | ||||
-rw-r--r-- | container-core/src/test/java/com/yahoo/restapi/PathTest.java | 15 |
2 files changed, 46 insertions, 16 deletions
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 7f78572f2d7..0afa196b607 100644 --- a/container-core/src/main/java/com/yahoo/restapi/Path.java +++ b/container-core/src/main/java/com/yahoo/restapi/Path.java @@ -21,37 +21,36 @@ import java.util.stream.Collectors; * * Note that for convenience in common use this has state which changes as a side effect of each matches * invocation. It is therefore for single thread use. - * + * + * A optional prefix can be used to match the path spec against an alternative path. This + * is used when you have alternative paths mapped to the same resource. + * * @author bratseth */ public class Path { // This path private final String pathString; + private final String optionalPrefix; private final String[] elements; // Info about the last match private final Map<String, String> values = new HashMap<>(); private String rest = ""; - + public Path(String path) { + this.optionalPrefix = ""; this.pathString = path; this.elements = path.split("/"); } - /** - * Parses the path according to pathSpec - must be called prior to {@link #get} - * - * Returns whether this path matches the given template string. - * If the given template has placeholders, their values (accessible by get) are reset by calling this, - * whether or not the path matches the given template. - * - * This will NOT match empty path elements. - * - * @param pathSpec the path string to match to this - * @return true if the string matches, false otherwise - */ - public boolean matches(String pathSpec) { + public Path(String path, String optionalPrefix) { + this.optionalPrefix = optionalPrefix; + this.pathString = path; + this.elements = path.split("/"); + } + + private boolean matches_inner(String pathSpec) { values.clear(); String[] specElements = pathSpec.split("/"); boolean matchPrefix = false; @@ -87,6 +86,24 @@ public class Path { } /** + * Parses the path according to pathSpec - must be called prior to {@link #get} + * + * Returns whether this path matches the given template string. + * If the given template has placeholders, their values (accessible by get) are reset by calling this, + * whether or not the path matches the given template. + * + * This will NOT match empty path elements. + * + * @param pathSpec the path string to match to this + * @return true if the string matches, false otherwise + */ + public boolean matches(String pathSpec) { + if (matches_inner(pathSpec)) return true; + if (optionalPrefix.isEmpty() || optionalPrefix.length() > pathSpec.length()) return false; + return matches_inner(optionalPrefix + pathSpec); + } + + /** * Returns the value of the given template variable in the last path matched, or null * if the previous matches call returned false or if this has not matched anything yet. */ 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 9e77dc7b3f0..566209d941b 100644 --- a/container-core/src/test/java/com/yahoo/restapi/PathTest.java +++ b/container-core/src/test/java/com/yahoo/restapi/PathTest.java @@ -11,7 +11,20 @@ import static org.junit.Assert.assertEquals; * @author bratseth */ public class PathTest { - + + @Test + public void testWithPrefix() { + // Test that a path with a prefix matches spec + Path path = new Path("/ball/a/1/bar/fuz", "/ball"); + assertTrue(path.matches("/a/{foo}/bar/{b}")); + assertEquals("1", path.get("foo")); + assertEquals("fuz", path.get("b")); + + // One negative test where the prefix should not count + assertFalse(path.matches("/ball/a/{foo}/zoo/{b}")); + } + + @Test public void testPath() { assertFalse(new Path("").matches("/a/{foo}/bar/{b}")); |