You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2008/02/06 11:28:11 UTC
svn commit: r618949 - in /incubator/sling/trunk/jcr/resource/src:
main/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIterator.java
test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java
Author: fmeschbe
Date: Wed Feb 6 02:28:10 2008
New Revision: 618949
URL: http://svn.apache.org/viewvc?rev=618949&view=rev
Log:
SLING-226 Fix request path splitting
Modified:
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIterator.java
incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java
Modified: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIterator.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIterator.java?rev=618949&r1=618948&r2=618949&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIterator.java (original)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIterator.java Wed Feb 6 02:28:10 2008
@@ -23,51 +23,61 @@
/**
* Iterate over the the HTTP request path by creating shorter segments of that
- * path using "." and "/" as separators.
+ * path using "." as a separator. If the request path is for a request method
+ * other than <em>GET</em> or <em>HEAD</em>, after checking the last dot,
+ * the parent path is also checked.
* <p>
- * For example, if path = /some/stuff.a4.html/xyz the sequence is:
+ * For example, if path = /some/stuff.a4.html/xyz.ext the sequence is:
* <ol>
+ * <li> /some/stuff.a4.html/xyz.ext </li>
* <li> /some/stuff.a4.html/xyz </li>
- * <li> /some/stuff.a4.html </li>
- * <li> /some/stuff.a4 </li>
+ * <li> /some/stuff.a4</li>
* <li> /some/stuff </li>
- * <li> /some </li>
+ * <li> /some (only if the request method is neither GET nor HEAD) </li>
* </ol>
* <p>
- * The root path (/) is never returned. Creating a resource path iterator with a
- * null or empty path or a root path will not return anything.
- *
- * The above rules are not valid for GET or HEAD requests, where
- * we do not go up the path: for those requests, the path is
- * only split at dots that follow the last slash
+ * The root path (/) is never returned.
*/
public class ResourcePathIterator implements Iterator<String> {
+ // the next path to return, null if nothing more to return
private String nextPath;
- private final int smallestBreakPos;
+ // true if the parent of nextPath is to be considered after cutting
+ // off at all dots, initialy true only for non-GET/HEAD requests
+ private boolean considerParent;
+
+ /**
+ * Creates a new instance iterating over the given path
+ *
+ * @param path The path to iterate over. If this is empty or
+ * <code>null</code> this iterator will not return anything.
+ * @param httpMethod The HTTP request method causing this iterator to be
+ * created.
+ */
public ResourcePathIterator(String path, String httpMethod) {
- // For GET or HEAD requests, path can only be split after
- // the last slash (SLING-179)
- final boolean getOrHead = HttpConstants.METHOD_GET.equals(httpMethod)
- || HttpConstants.METHOD_HEAD.equals(httpMethod);
- smallestBreakPos = getOrHead ? path.lastIndexOf('/') : 0;
-
- if (path != null) {
- int i = path.length() - 1;
- while (i >= smallestBreakPos && path.charAt(i) == '/') {
- i--;
- }
- if (i < 0 || i <= smallestBreakPos) {
- nextPath = null;
- } else if (i < path.length() - 1) {
- nextPath = path.substring(0, i + 1);
- } else {
- nextPath = path;
- }
- } else {
+ // only consider a parent if not a GET or HEAD request
+ considerParent = !HttpConstants.METHOD_GET.equals(httpMethod)
+ && !HttpConstants.METHOD_HEAD.equals(httpMethod);
+
+ // find last non-slash character
+ int i = (path != null) ? path.length() - 1 : -1;
+ while (i >= 0 && path.charAt(i) == '/') {
+ i--;
+ }
+
+ if (i < 0) {
+ // only slash
nextPath = null;
+
+ } else if (i < path.length() - 1) {
+ // cut off slash
+ nextPath = path.substring(0, i + 1);
+
+ } else {
+ // no trailing slash
+ nextPath = path;
}
}
@@ -82,24 +92,34 @@
final String result = nextPath;
- // find next path
- int pos = result.length() - 1;
- while (pos >= smallestBreakPos) {
- final char c = result.charAt(pos);
- if (c == '.' || c == '/') {
- break;
+ // find last
+ int lastDot = nextPath.lastIndexOf('.');
+ if (lastDot > 0) {
+ nextPath = nextPath.substring(0, lastDot);
+ } else if (lastDot == 0) {
+ // path started with a dot ??
+ nextPath = null;
+ } else if (considerParent) {
+ // no dot any more, go up to parent for non-GET/HEAD
+ int lastSlash = nextPath.lastIndexOf('/');
+ if (lastSlash > 0) {
+ nextPath = nextPath.substring(0, lastSlash);
+ } else {
+ // never consider "/"
+ nextPath = null;
}
- pos--;
- }
- nextPath = (pos <= smallestBreakPos) ? null : result.substring(0, pos);
+ // prevent going further up the path by slashes
+ considerParent = false;
+ } else {
+ nextPath = null;
+ }
return result;
}
public void remove() {
- throw new UnsupportedOperationException(
- "Cannot remove() on ResourcePathIterator");
+ throw new UnsupportedOperationException("remove");
}
}
Modified: incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java?rev=618949&r1=618948&r2=618949&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java (original)
+++ incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java Wed Feb 6 02:28:10 2008
@@ -26,7 +26,7 @@
public class ResourcePathIteratorTest extends TestCase {
public void testNull() {
- ResourcePathIterator rpi = new ResourcePathIterator(null,"POST");
+ ResourcePathIterator rpi = new ResourcePathIterator(null, "POST");
assertFalse(rpi.hasNext());
try {
@@ -38,7 +38,7 @@
}
public void testEmpty() {
- ResourcePathIterator rpi = new ResourcePathIterator("","POST");
+ ResourcePathIterator rpi = new ResourcePathIterator("", "POST");
assertFalse(rpi.hasNext());
try {
@@ -50,7 +50,7 @@
}
public void testRoot() {
- ResourcePathIterator rpi = new ResourcePathIterator("/","POST");
+ ResourcePathIterator rpi = new ResourcePathIterator("/", "POST");
assertFalse(rpi.hasNext());
try {
@@ -62,11 +62,12 @@
}
public void testSlashed() {
- ResourcePathIterator rpi = new ResourcePathIterator("/root/child","POST");
+ ResourcePathIterator rpi = new ResourcePathIterator("/root/child",
+ "POST");
assertEquals("/root/child", rpi.next());
assertEquals("/root", rpi.next());
assertFalse(rpi.hasNext());
-
+
try {
rpi.next();
fail("Expected NoSuchElementException after end of iterator");
@@ -74,15 +75,16 @@
// expected
}
}
-
+
public void testOtherMethods() {
- final String [] methods = { "PUT", "WHATEVER.METHOD", null };
- for(String method : methods) {
- ResourcePathIterator rpi = new ResourcePathIterator("/root/child",method);
+ final String[] methods = { "PUT", "WHATEVER.METHOD", null };
+ for (String method : methods) {
+ ResourcePathIterator rpi = new ResourcePathIterator("/root/child",
+ method);
assertEquals("/root/child", rpi.next());
assertEquals("/root", rpi.next());
assertFalse(rpi.hasNext());
-
+
try {
rpi.next();
fail("Expected NoSuchElementException after end of iterator");
@@ -91,13 +93,14 @@
}
}
}
-
+
public void testSlashedTrailingSlash1() {
- ResourcePathIterator rpi = new ResourcePathIterator("/root/child/","POST");
+ ResourcePathIterator rpi = new ResourcePathIterator("/root/child/",
+ "POST");
assertEquals("/root/child", rpi.next());
assertEquals("/root", rpi.next());
assertFalse(rpi.hasNext());
-
+
try {
rpi.next();
fail("Expected NoSuchElementException after end of iterator");
@@ -105,9 +108,10 @@
// expected
}
}
-
+
public void testSlashedTrailingSlash2() {
- ResourcePathIterator rpi = new ResourcePathIterator("/root/child//","POST");
+ ResourcePathIterator rpi = new ResourcePathIterator("/root/child//",
+ "POST");
assertEquals("/root/child", rpi.next());
assertEquals("/root", rpi.next());
assertFalse(rpi.hasNext());
@@ -121,7 +125,8 @@
}
public void testDotted() {
- ResourcePathIterator rpi = new ResourcePathIterator("/root.child","POST");
+ ResourcePathIterator rpi = new ResourcePathIterator("/root.child",
+ "POST");
assertEquals("/root.child", rpi.next());
assertEquals("/root", rpi.next());
assertFalse(rpi.hasNext());
@@ -134,11 +139,10 @@
}
}
- public void testMixed() {
- ResourcePathIterator rpi = new ResourcePathIterator("/root/child.print.a4.html/with/suffix","POST");
+ public void testMixedPost() {
+ ResourcePathIterator rpi = new ResourcePathIterator(
+ "/root/child.print.a4.html/with/suffix", "POST");
assertEquals("/root/child.print.a4.html/with/suffix", rpi.next());
- assertEquals("/root/child.print.a4.html/with", rpi.next());
- assertEquals("/root/child.print.a4.html", rpi.next());
assertEquals("/root/child.print.a4", rpi.next());
assertEquals("/root/child.print", rpi.next());
assertEquals("/root/child", rpi.next());
@@ -152,67 +156,97 @@
// expected
}
}
-
+
+ public void testMixedGet() {
+ ResourcePathIterator rpi = new ResourcePathIterator(
+ "/root/child.print.a4.html/with/suffix", "GET");
+ assertEquals("/root/child.print.a4.html/with/suffix", rpi.next());
+ assertEquals("/root/child.print.a4", rpi.next());
+ assertEquals("/root/child.print", rpi.next());
+ assertEquals("/root/child", rpi.next());
+ assertFalse(rpi.hasNext());
+
+ try {
+ rpi.next();
+ fail("Expected NoSuchElementException after end of iterator");
+ } catch (NoSuchElementException nsee) {
+ // expected
+ }
+ }
+
public void testNoSeparators() {
- final Iterator<String> it = new ResourcePathIterator("MickeyMouseWasHere","POST");
+ final Iterator<String> it = new ResourcePathIterator(
+ "MickeyMouseWasHere", "POST");
assertTrue(it.hasNext());
- assertEquals("MickeyMouseWasHere",it.next());
+ assertEquals("MickeyMouseWasHere", it.next());
assertFalse("done iterating", it.hasNext());
}
public void testGetA() {
- final Iterator<String> it = new ResourcePathIterator("/some/stuff/more.a4.html","GET");
+ final Iterator<String> it = new ResourcePathIterator(
+ "/some/stuff/more.a4.html", "GET");
assertTrue(it.hasNext());
- assertEquals("/some/stuff/more.a4.html",it.next());
+ assertEquals("/some/stuff/more.a4.html", it.next());
assertTrue(it.hasNext());
- assertEquals("/some/stuff/more.a4",it.next());
+ assertEquals("/some/stuff/more.a4", it.next());
assertTrue(it.hasNext());
- assertEquals("/some/stuff/more",it.next());
+ assertEquals("/some/stuff/more", it.next());
assertFalse("done iterating", it.hasNext());
}
-
+
public void testGetB() {
- final Iterator<String> it = new ResourcePathIterator("/some/stuff/more.html","GET");
+ final Iterator<String> it = new ResourcePathIterator(
+ "/some/stuff/more.html", "GET");
assertTrue(it.hasNext());
- assertEquals("/some/stuff/more.html",it.next());
+ assertEquals("/some/stuff/more.html", it.next());
assertTrue(it.hasNext());
- assertEquals("/some/stuff/more",it.next());
+ assertEquals("/some/stuff/more", it.next());
assertFalse("done iterating", it.hasNext());
}
-
+
public void testHeadB() {
- final Iterator<String> it = new ResourcePathIterator("/some/stuff/more.html","HEAD");
+ final Iterator<String> it = new ResourcePathIterator(
+ "/some/stuff/more.html", "HEAD");
assertTrue(it.hasNext());
- assertEquals("/some/stuff/more.html",it.next());
+ assertEquals("/some/stuff/more.html", it.next());
assertTrue(it.hasNext());
- assertEquals("/some/stuff/more",it.next());
+ assertEquals("/some/stuff/more", it.next());
assertFalse("done iterating", it.hasNext());
}
-
+
public void testGetC() {
- final Iterator<String> it = new ResourcePathIterator("/some/stuff/more","GET");
- assertTrue(it.hasNext());
- assertEquals("/some/stuff/more",it.next());
+ final Iterator<String> it = new ResourcePathIterator(
+ "/some/stuff/more", "GET");
+ assertEquals("/some/stuff/more", it.next());
assertFalse("done iterating", it.hasNext());
}
-
+
public void testGetD() {
- final Iterator<String> it = new ResourcePathIterator("/some/stuff.print/more.html","GET");
- assertTrue(it.hasNext());
- assertEquals("/some/stuff.print/more.html",it.next());
- assertTrue(it.hasNext());
- assertEquals("/some/stuff.print/more",it.next());
+ final Iterator<String> it = new ResourcePathIterator(
+ "/some/stuff.print/more.html", "GET");
+ assertEquals("/some/stuff.print/more.html", it.next());
+ assertEquals("/some/stuff.print/more", it.next());
+ assertEquals("/some/stuff", it.next());
assertFalse("done iterating", it.hasNext());
}
-
- public void testRelativePath() {
- final Iterator<String> it = new ResourcePathIterator("some/stuff.print","POST");
+
+ public void testRelativePathPost() {
+ final Iterator<String> it = new ResourcePathIterator(
+ "some/stuff.print", "POST");
assertTrue(it.hasNext());
- assertEquals("some/stuff.print",it.next());
+ assertEquals("some/stuff.print", it.next());
assertTrue(it.hasNext());
- assertEquals("some/stuff",it.next());
+ assertEquals("some/stuff", it.next());
assertTrue(it.hasNext());
- assertEquals("some",it.next());
+ assertEquals("some", it.next());
+ assertFalse("done iterating", it.hasNext());
+ }
+
+ public void testRelativePathGet() {
+ final Iterator<String> it = new ResourcePathIterator(
+ "some/stuff.print", "GET");
+ assertEquals("some/stuff.print", it.next());
+ assertEquals("some/stuff", it.next());
assertFalse("done iterating", it.hasNext());
}
}