You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2008/01/28 13:29:35 UTC
svn commit: r615860 - in /incubator/sling/trunk/jcr/resource/src:
main/java/org/apache/sling/jcr/resource/internal/
main/java/org/apache/sling/jcr/resource/internal/helper/
test/java/org/apache/sling/jcr/resource/internal/
test/java/org/apache/sling/jc...
Author: bdelacretaz
Date: Mon Jan 28 04:29:30 2008
New Revision: 615860
URL: http://svn.apache.org/viewvc?rev=615860&view=rev
Log:
SLING-179 - ResourceResolver should not go up the path for GET requests
Modified:
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolver.java
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/JcrResourceResolverTest.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/JcrResourceResolver.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolver.java?rev=615860&r1=615859&r2=615860&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolver.java (original)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolver.java Mon Jan 28 04:29:30 2008
@@ -27,9 +27,6 @@
import java.util.List;
import java.util.Map;
-import javax.jcr.Item;
-import javax.jcr.Node;
-import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
@@ -50,7 +47,6 @@
import org.apache.sling.jcr.resource.internal.helper.ResourcePathIterator;
import org.apache.sling.jcr.resource.internal.helper.ResourceProviderEntry;
import org.apache.sling.jcr.resource.internal.helper.jcr.JcrNodeResourceIterator;
-import org.apache.sling.jcr.resource.internal.helper.jcr.JcrPropertyResource;
import org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProviderEntry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -80,7 +76,7 @@
public Resource resolve(HttpServletRequest request) throws SlingException {
String pathInfo = request.getPathInfo();
- Resource result = resolve(pathInfo);
+ Resource result = resolve(pathInfo, request.getMethod());
if (result == null) {
result = new NonExistingResource(pathInfo);
@@ -221,6 +217,45 @@
* to this manager's session.
*/
public Resource resolve(String uri) throws SlingException {
+ // TODO for now use null as a method to make sure this goes up the path
+ // (see SLING-179)
+ return resolve(uri, null);
+ }
+
+ public String pathToURL(Resource resource) {
+ String path = resource.getPath();
+
+ // get first map
+ String href = null;
+ Mapping[] mappings = factory.getMappings();
+ for (int i = 0; i < mappings.length && href == null; i++) {
+ href = mappings[i].mapHandle(path);
+ }
+
+ // if no mapping's to prefix matches the handle, use the handle itself
+ if (href == null) {
+ href = path;
+ }
+
+ // check virtual mappings
+ String virtual = factory.realToVirtualUri(href);
+ if (virtual != null) {
+ log.debug("pathToURL: Using virtual URI {} for path {}", virtual,
+ href);
+ href = virtual;
+ }
+
+ log.debug("MapHandle: {} -> {}", path, href);
+ return href;
+ }
+
+ // ---------- implementation helper ----------------------------------------
+
+ /**
+ * @throws AccessControlException If an item would exist but is not readable
+ * to this manager's session.
+ */
+ public Resource resolve(String uri, String httpMethod) throws SlingException {
// decode the request URI (required as the servlet container does not
try {
@@ -242,7 +277,7 @@
try {
// translate url to a mapped url structure
- Resource result = transformURL(uri);
+ Resource result = urlToResource(uri, httpMethod);
return result;
} catch (AccessControlException ace) {
@@ -259,40 +294,11 @@
}
}
- public String pathToURL(Resource resource) {
- String path = resource.getPath();
-
- // get first map
- String href = null;
- Mapping[] mappings = factory.getMappings();
- for (int i = 0; i < mappings.length && href == null; i++) {
- href = mappings[i].mapHandle(path);
- }
-
- // if no mapping's to prefix matches the handle, use the handle itself
- if (href == null) {
- href = path;
- }
-
- // check virtual mappings
- String virtual = factory.realToVirtualUri(href);
- if (virtual != null) {
- log.debug("pathToURL: Using virtual URI {} for path {}", virtual,
- href);
- href = virtual;
- }
-
- log.debug("MapHandle: {} -> {}", path, href);
- return href;
- }
-
- // ---------- implementation helper ----------------------------------------
-
public Session getSession() {
return rootProvider.getSession();
}
- private Resource transformURL(String uri) throws SlingException {
+ private Resource urlToResource(String uri, String httpMethod) throws SlingException {
Mapping[] mappings = factory.getMappings();
for (int i = 0; i < mappings.length; i++) {
// exchange the 'to'-portion with the 'from' portion and check
@@ -302,7 +308,7 @@
continue;
}
- Resource resource = scanPath(mappedUri);
+ Resource resource = scanPath(mappedUri, httpMethod);
if (resource != null) {
ResourceMetadata rm = resource.getResourceMetadata();
@@ -324,11 +330,11 @@
}
- private Resource scanPath(String uriPath) throws SlingException {
+ private Resource scanPath(String uriPath, String httpMethod) throws SlingException {
Resource resource = null;
String curPath = uriPath;
try {
- final ResourcePathIterator it = new ResourcePathIterator(uriPath);
+ final ResourcePathIterator it = new ResourcePathIterator(uriPath, httpMethod);
while (it.hasNext() && resource == null) {
curPath = it.next();
resource = getResourceInternal(curPath);
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=615860&r1=615859&r2=615860&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 Mon Jan 28 04:29:30 2008
@@ -34,18 +34,31 @@
* <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
*/
public class ResourcePathIterator implements Iterator<String> {
private String nextPath;
+ private final String httpMethod;
+ private final int smallestBreakPos;
- public ResourcePathIterator(String path) {
+ public ResourcePathIterator(String path, String httpMethod) {
+ this.httpMethod = httpMethod;
+
+ // For GET or HEAD requests, path can only be split after
+ // the last slash (SLING-179)
+ final boolean getOrHead = "GET".equals(httpMethod) || "HEAD".equals(httpMethod);
+ smallestBreakPos = getOrHead ? path.lastIndexOf('/') : 0;
+
if (path != null) {
int i = path.length() - 1;
- while (i >= 0 && path.charAt(i) == '/') {
+ while (i >= smallestBreakPos && path.charAt(i) == '/') {
i--;
}
- if (i < 0) {
+ if (i < 0 || i <= smallestBreakPos) {
nextPath = null;
} else if (i < path.length() - 1) {
nextPath = path.substring(0, i + 1);
@@ -70,7 +83,7 @@
// find next path
int pos = result.length() - 1;
- while (pos >= 0) {
+ while (pos >= smallestBreakPos) {
final char c = result.charAt(pos);
if (c == '.' || c == '/') {
break;
@@ -78,7 +91,7 @@
pos--;
}
- nextPath = (pos <= 0) ? null : result.substring(0, pos);
+ nextPath = (pos <= smallestBreakPos) ? null : result.substring(0, pos);
return result;
}
Modified: incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java?rev=615860&r1=615859&r2=615860&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java (original)
+++ incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java Mon Jan 28 04:29:30 2008
@@ -27,50 +27,40 @@
import javax.jcr.NamespaceRegistry;
import javax.jcr.Node;
-import javax.jcr.Session;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
-import junit.framework.TestCase;
-
import org.apache.sling.api.SlingConstants;
import org.apache.sling.api.resource.NonExistingResource;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.commons.testing.jcr.RepositoryUtil;
-import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.commons.testing.jcr.RepositoryTestBase;
import org.apache.sling.jcr.resource.JcrResourceConstants;
import org.apache.sling.jcr.resource.internal.helper.Mapping;
-public class JcrResourceResolverTest extends TestCase {
-
- private Session session;
-
- private String root;
+public class JcrResourceResolverTest extends RepositoryTestBase {
+ private String rootPath;
private Node rootNode;
-
private ResourceResolver resResolver;
protected void setUp() throws Exception {
- RepositoryUtil.startRepository();
- SlingRepository repository = RepositoryUtil.getRepository();
-
+ super.setUp();
+ getSession();
+
JcrResourceResolverFactoryImpl resFac = new JcrResourceResolverFactoryImpl();
Field repoField = resFac.getClass().getDeclaredField("repository");
repoField.setAccessible(true);
- repoField.set(resFac, repository);
+ repoField.set(resFac, getRepository());
Field mappingsField = resFac.getClass().getDeclaredField("mappings");
mappingsField.setAccessible(true);
mappingsField.set(resFac, new Mapping[] { Mapping.DIRECT });
- session = RepositoryUtil.getRepository().loginAdministrative(null);
-
try {
NamespaceRegistry nsr = session.getWorkspace().getNamespaceRegistry();
nsr.registerNamespace(SlingConstants.NAMESPACE_PREFIX,
@@ -81,8 +71,8 @@
resResolver = resFac.getResourceResolver(session);
- root = "/test" + System.currentTimeMillis();
- rootNode = session.getRootNode().addNode(root.substring(1),
+ rootPath = "/test" + System.currentTimeMillis();
+ rootNode = getSession().getRootNode().addNode(rootPath.substring(1),
"nt:unstructured");
session.save();
}
@@ -93,19 +83,13 @@
rootNode.remove();
session.save();
}
-
- if (session != null) {
- session.logout();
- }
-
- RepositoryUtil.stopRepository();
}
public void testGetResource() throws Exception {
// existing resource
- Resource res = resResolver.getResource(root);
+ Resource res = resResolver.getResource(rootPath);
assertNotNull(res);
- assertEquals(root, res.getPath());
+ assertEquals(rootPath, res.getPath());
assertEquals(rootNode.getPrimaryNodeType().getName(),
res.getResourceType());
@@ -113,16 +97,16 @@
assertTrue(rootNode.isSame(res.adaptTo(Node.class)));
// missing resource
- String path = root + "/missing";
+ String path = rootPath + "/missing";
res = resResolver.getResource(path);
assertNull(res);
}
public void testResolveResource() throws Exception {
// existing resource
- Resource res = resResolver.resolve(new ResourceResolverTestRequest(root));
+ Resource res = resResolver.resolve(new ResourceResolverTestRequest(rootPath));
assertNotNull(res);
- assertEquals(root, res.getPath());
+ assertEquals(rootPath, res.getPath());
assertEquals(rootNode.getPrimaryNodeType().getName(),
res.getResourceType());
@@ -130,10 +114,10 @@
assertTrue(rootNode.isSame(res.adaptTo(Node.class)));
// missing resource below root should resolve root
- String path = root + "/missing";
+ String path = rootPath + "/missing";
res = resResolver.resolve(new ResourceResolverTestRequest(path));
assertNotNull(res);
- assertEquals(root, res.getPath());
+ assertEquals(rootPath, res.getPath());
assertEquals(rootNode.getPrimaryNodeType().getName(),
res.getResourceType());
@@ -141,10 +125,10 @@
assertTrue(rootNode.isSame(res.adaptTo(Node.class)));
// root with selectors/ext should resolve root
- path = root + ".print.a4.html";
+ path = rootPath + ".print.a4.html";
res = resResolver.resolve(new ResourceResolverTestRequest(path));
assertNotNull(res);
- assertEquals(root, res.getPath());
+ assertEquals(rootPath, res.getPath());
assertEquals(rootNode.getPrimaryNodeType().getName(),
res.getResourceType());
@@ -152,20 +136,54 @@
assertTrue(rootNode.isSame(res.adaptTo(Node.class)));
// missing resource should return NON_EXISTING Resource
- path = root + System.currentTimeMillis();
+ path = rootPath + System.currentTimeMillis();
res = resResolver.resolve(new ResourceResolverTestRequest(path));
assertNotNull(res);
assertTrue(res instanceof NonExistingResource);
assertEquals(path, res.getPath());
assertEquals(Resource.RESOURCE_TYPE_NON_EXISTING, res.getResourceType());
}
+
+ public void testGetDoesNotGoUp() throws Exception {
+
+ final String path = rootPath + "/nothing";
+
+ {
+ final Resource res = resResolver.resolve(new ResourceResolverTestRequest(path, "POST"));
+ assertNotNull(res);
+ assertEquals("POST request resolution goes up up the path to rootPath", rootPath, res.getPath());
+ assertEquals(rootNode.getPrimaryNodeType().getName(), res.getResourceType());
+ }
+
+ {
+ final Resource res = resResolver.resolve(new ResourceResolverTestRequest(path, "GET"));
+ assertNotNull(res);
+ assertEquals("GET request resolution does not go up the path",
+ Resource.RESOURCE_TYPE_NON_EXISTING, res.getResourceType());
+ }
+ }
+
+ public void testGetRemovesExtensionInResolution() throws Exception {
+ final String path = rootPath + ".whatever";
+ final Resource res = resResolver.resolve(new ResourceResolverTestRequest(path, "GET"));
+ assertNotNull(res);
+ assertEquals(rootPath, res.getPath());
+ assertEquals(rootNode.getPrimaryNodeType().getName(), res.getResourceType());
+ }
+
private static class ResourceResolverTestRequest implements HttpServletRequest {
- private String pathInfo;
+ private final String pathInfo;
+ private final String method;
ResourceResolverTestRequest(String pathInfo) {
+ this(pathInfo, null);
+ }
+
+ ResourceResolverTestRequest(String pathInfo, String httpMethod) {
this.pathInfo = pathInfo;
+ this.method = httpMethod;
}
public String getPathInfo() {
@@ -318,7 +336,7 @@
}
public String getMethod() {
- return null;
+ return method;
}
public String getPathTranslated() {
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=615860&r1=615859&r2=615860&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 Mon Jan 28 04:29:30 2008
@@ -18,6 +18,7 @@
*/
package org.apache.sling.jcr.resource.internal.helper;
+import java.util.Iterator;
import java.util.NoSuchElementException;
import junit.framework.TestCase;
@@ -25,7 +26,7 @@
public class ResourcePathIteratorTest extends TestCase {
public void testNull() {
- ResourcePathIterator rpi = new ResourcePathIterator(null);
+ ResourcePathIterator rpi = new ResourcePathIterator(null,"POST");
assertFalse(rpi.hasNext());
try {
@@ -37,7 +38,7 @@
}
public void testEmpty() {
- ResourcePathIterator rpi = new ResourcePathIterator("");
+ ResourcePathIterator rpi = new ResourcePathIterator("","POST");
assertFalse(rpi.hasNext());
try {
@@ -49,7 +50,7 @@
}
public void testRoot() {
- ResourcePathIterator rpi = new ResourcePathIterator("/");
+ ResourcePathIterator rpi = new ResourcePathIterator("/","POST");
assertFalse(rpi.hasNext());
try {
@@ -61,7 +62,7 @@
}
public void testSlashed() {
- ResourcePathIterator rpi = new ResourcePathIterator("/root/child");
+ ResourcePathIterator rpi = new ResourcePathIterator("/root/child","POST");
assertEquals("/root/child", rpi.next());
assertEquals("/root", rpi.next());
assertFalse(rpi.hasNext());
@@ -74,8 +75,25 @@
}
}
+ public void testOtherMethods() {
+ 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");
+ } catch (NoSuchElementException nsee) {
+ // expected
+ }
+ }
+ }
+
public void testSlashedTrailingSlash1() {
- ResourcePathIterator rpi = new ResourcePathIterator("/root/child/");
+ ResourcePathIterator rpi = new ResourcePathIterator("/root/child/","POST");
assertEquals("/root/child", rpi.next());
assertEquals("/root", rpi.next());
assertFalse(rpi.hasNext());
@@ -89,7 +107,7 @@
}
public void testSlashedTrailingSlash2() {
- ResourcePathIterator rpi = new ResourcePathIterator("/root/child//");
+ ResourcePathIterator rpi = new ResourcePathIterator("/root/child//","POST");
assertEquals("/root/child", rpi.next());
assertEquals("/root", rpi.next());
assertFalse(rpi.hasNext());
@@ -103,7 +121,7 @@
}
public void testDotted() {
- ResourcePathIterator rpi = new ResourcePathIterator("/root.child");
+ ResourcePathIterator rpi = new ResourcePathIterator("/root.child","POST");
assertEquals("/root.child", rpi.next());
assertEquals("/root", rpi.next());
assertFalse(rpi.hasNext());
@@ -117,7 +135,7 @@
}
public void testMixed() {
- ResourcePathIterator rpi = new ResourcePathIterator("/root/child.print.a4.html/with/suffix");
+ 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());
@@ -134,5 +152,67 @@
// expected
}
}
-
-}
+
+ public void testNoSeparators() {
+ final Iterator<String> it = new ResourcePathIterator("MickeyMouseWasHere","POST");
+ assertTrue(it.hasNext());
+ assertEquals("MickeyMouseWasHere",it.next());
+ assertFalse("done iterating", it.hasNext());
+ }
+
+ public void testGetA() {
+ final Iterator<String> it = new ResourcePathIterator("/some/stuff/more.a4.html","GET");
+ assertTrue(it.hasNext());
+ assertEquals("/some/stuff/more.a4.html",it.next());
+ assertTrue(it.hasNext());
+ assertEquals("/some/stuff/more.a4",it.next());
+ assertTrue(it.hasNext());
+ 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");
+ assertTrue(it.hasNext());
+ assertEquals("/some/stuff/more.html",it.next());
+ assertTrue(it.hasNext());
+ 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");
+ assertTrue(it.hasNext());
+ assertEquals("/some/stuff/more.html",it.next());
+ assertTrue(it.hasNext());
+ 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());
+ 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());
+ assertFalse("done iterating", it.hasNext());
+ }
+
+ public void testRelativePath() {
+ final Iterator<String> it = new ResourcePathIterator("some/stuff.print","POST");
+ assertTrue(it.hasNext());
+ assertEquals("some/stuff.print",it.next());
+ assertTrue(it.hasNext());
+ assertEquals("some/stuff",it.next());
+ assertTrue(it.hasNext());
+ assertEquals("some",it.next());
+ assertFalse("done iterating", it.hasNext());
+ }
+}
\ No newline at end of file