summaryrefslogtreecommitdiffstats
path: root/container-core
diff options
context:
space:
mode:
authortoby <smorgrav@yahoo-inc.com>2019-03-15 16:58:02 +0100
committertoby <smorgrav@yahoo-inc.com>2019-03-15 16:58:02 +0100
commit5039958f9fa1d692d913ac97a5c179605f83b07e (patch)
tree80ea5812a36c68843beb94addd82ddf1f15616ed /container-core
parentd0c0baba17829572ee5af428fcf6b068f013d55d (diff)
Add support for an optional prefix to path matching
Diffstat (limited to 'container-core')
-rw-r--r--container-core/src/main/java/com/yahoo/restapi/Path.java47
-rw-r--r--container-core/src/test/java/com/yahoo/restapi/PathTest.java15
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}"));