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/05 19:29:36 UTC
svn commit: r618734 - in /incubator/sling/trunk/jcr/resource/src:
main/java/org/apache/sling/jcr/resource/internal/
main/java/org/apache/sling/jcr/resource/internal/helper/
main/java/org/apache/sling/jcr/resource/internal/helper/jcr/
test/java/org/apac...
Author: fmeschbe
Date: Tue Feb 5 10:29:33 2008
New Revision: 618734
URL: http://svn.apache.org/viewvc?rev=618734&view=rev
Log:
SLING-220 Refactoring the resource resolution process using the ResourceProviderEntry tree.
See issue for more information.
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/ResourceProviderEntry.java
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProviderEntry.java
incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.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=618734&r1=618733&r2=618734&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 Tue Feb 5 10:29:33 2008
@@ -45,7 +45,6 @@
import org.apache.sling.jcr.resource.internal.helper.Descendable;
import org.apache.sling.jcr.resource.internal.helper.Mapping;
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.JcrResourceProviderEntry;
import org.slf4j.Logger;
@@ -54,20 +53,23 @@
/**
* The <code>JcrResourceResolver</code> class implements the Sling
* <code>ResourceResolver</code> and <code>ResourceResolver</code>
- * interfaces and in addition is a {@link PathMapper}. Instances of this
- * class are retrieved through the
+ * interfaces and in addition is a {@link PathMapper}. Instances of this class
+ * are retrieved through the
* {@link org.apache.sling.jcr.resource.JcrResourceResolverFactory#getResourceResolver(Session)}
* method.
*/
-public class JcrResourceResolver extends SlingAdaptable implements ResourceResolver {
+public class JcrResourceResolver extends SlingAdaptable implements
+ ResourceResolver {
/** default log */
private final Logger log = LoggerFactory.getLogger(getClass());
private final JcrResourceProviderEntry rootProvider;
+
private final JcrResourceResolverFactoryImpl factory;
- public JcrResourceResolver(JcrResourceProviderEntry rootProvider, JcrResourceResolverFactoryImpl factory) {
+ public JcrResourceResolver(JcrResourceProviderEntry rootProvider,
+ JcrResourceResolverFactoryImpl factory) {
this.rootProvider = rootProvider;
this.factory = factory;
}
@@ -120,8 +122,7 @@
// check virtual mappings
String virtual = factory.realToVirtualUri(href);
if (virtual != null) {
- log.debug("map: Using virtual URI {} for path {}", virtual,
- href);
+ log.debug("map: Using virtual URI {} for path {}", virtual, href);
href = virtual;
}
@@ -148,7 +149,7 @@
// no resource found, if we get here
return null;
- }
+ }
public Resource getResource(Resource base, String path) {
@@ -188,7 +189,8 @@
try {
QueryResult res = JcrResourceUtil.query(getSession(), query,
language);
- return new JcrNodeResourceIterator(rootProvider.getResourceProvider(), res.getNodes());
+ return new JcrNodeResourceIterator(
+ rootProvider.getResourceProvider(), res.getNodes());
} catch (javax.jcr.query.InvalidQueryException iqe) {
throw new QuerySyntaxException(iqe.getMessage(), query, language,
iqe);
@@ -253,7 +255,8 @@
* @throws AccessControlException If an item would exist but is not readable
* to this manager's session.
*/
- private Resource resolve(String uri, String httpMethod) throws SlingException {
+ private Resource resolve(String uri, String httpMethod)
+ throws SlingException {
// decode the request URI (required as the servlet container does not
try {
@@ -296,7 +299,8 @@
return rootProvider.getSession();
}
- private Resource urlToResource(String uri, String httpMethod) 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
@@ -328,11 +332,13 @@
}
- private Resource scanPath(String uriPath, String httpMethod) throws SlingException {
+ private Resource scanPath(String uriPath, String httpMethod)
+ throws SlingException {
Resource resource = null;
String curPath = uriPath;
try {
- final ResourcePathIterator it = new ResourcePathIterator(uriPath, httpMethod);
+ final ResourcePathIterator it = new ResourcePathIterator(uriPath,
+ httpMethod);
while (it.hasNext() && resource == null) {
curPath = it.next();
resource = getResourceInternal(curPath);
@@ -347,23 +353,13 @@
/**
* Creates a JcrNodeResource with the given path if existing
- *
+ *
* @throws AccessControlException If an item exists but this manager has no
* read access
*/
protected Resource getResourceInternal(String path) {
- Resource resource= null;
-
- ResourceProviderEntry rp = rootProvider.getResourceProvider(path);
- while (rp != null && resource == null) {
- // resource provider can be null (TODO - why?)
- if ( rp.getResourceProvider() != null ) {
- resource = rp.getResourceProvider().getResource(path);
- }
- rp = rp.getParentEntry();
- }
-
+ Resource resource = rootProvider.getResource(path);
if (resource != null) {
resource.getResourceMetadata().put(
ResourceMetadata.RESOLUTION_PATH, path);
Modified: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntry.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntry.java?rev=618734&r1=618733&r2=618734&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntry.java (original)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntry.java Tue Feb 5 10:29:33 2008
@@ -22,27 +22,57 @@
import java.util.SortedSet;
import java.util.TreeSet;
+import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceProvider;
+/**
+ * The <code>ResourceProviderEntry</code> class represents a node in the tree
+ * of resource providers spanned by the root paths of the provider resources.
+ * <p>
+ * This class is comparable to itself to help keep the child entries list sorted
+ * by their prefix.
+ */
public class ResourceProviderEntry implements Comparable<ResourceProviderEntry> {
+ // the path to resources provided by the resource provider of this
+ // entry. this path is relative to the path of the parent resource
+ // provider entry and has no trailing slash.
private final String path;
+ // the path to resources provided by the resource provider of this
+ // entry. this is the same path as the path field but with a trailing
+ // slash to be used as a prefix match resource paths to resolve
private final String prefix;
+ // the resource provider kept in this entry supporting resources at and
+ // below the path of this entry.
private final ResourceProvider provider;
- private final ResourceProviderEntry parentEntry;
-
+ // child resource provider entries sharing the same path prefix of this
+ // entry but with more path elements.
private ResourceProviderEntry[] entries;
+ /**
+ * Creates an instance of this class with the given path relative to the
+ * parent resource provider entry, encapsulating the given ResourceProvider.
+ *
+ * @param path The relative path supported by the provider
+ * @param provider The resource provider to encapsulate by this entry.
+ */
+ public ResourceProviderEntry(String path, ResourceProvider provider) {
+ this(path, provider, null);
+ }
+
+ /**
+ * Creates an instance of this class with the given path relative to the
+ * parent resource provider entry, encapsulating the given ResourceProvider,
+ * and a number of inital child entries.
+ *
+ * @param path The relative path supported by the provider
+ * @param provider The resource provider to encapsulate by this entry.
+ */
public ResourceProviderEntry(String path, ResourceProvider provider,
- ResourceProviderEntry parentEntry) {
- this(path, provider, parentEntry, null);
- }
-
- public ResourceProviderEntry(String path, ResourceProvider provider,
- ResourceProviderEntry parentEntry, ResourceProviderEntry[] entries) {
+ ResourceProviderEntry[] entries) {
if (path.endsWith("/")) {
this.path = path.substring(0, path.length() - 1);
this.prefix = path;
@@ -51,33 +81,67 @@
this.prefix = path + "/";
}
this.provider = provider;
- this.parentEntry = parentEntry;
this.entries = entries;
}
- public ResourceProviderEntry getParentEntry() {
- return parentEntry;
- }
-
+ /**
+ * Returns the resource provider contained in this entry
+ */
public ResourceProvider getResourceProvider() {
return provider;
}
+ /**
+ * Returns the child resource provider entries of this entry
+ */
public ResourceProviderEntry[] getEntries() {
return entries;
}
- public ResourceProviderEntry getResourceProvider(String path) {
+ /**
+ * Returns the resource with the given path or <code>null</code> if
+ * neither the resource provider of this entry nor the resource provider of
+ * any of the child entries can provide the resource.
+ *
+ * @param path The path to the resource to return.
+ * @return The resource for the path or <code>null</code> if no resource
+ * can be found.
+ * @throws SlingException if an error occurrs trying to access an existing
+ * resource.
+ */
+ public Resource getResource(String path) {
+ return getResource(path, path);
+ }
+
+ /**
+ * Returns the resource with the given path or <code>null</code> if
+ * neither the resource provider of this entry nor the resource provider of
+ * any of the child entries can provide the resource.
+ * <p>
+ * This method implements the {@link #getResource(String)} method
+ * recursively calling itself on any child provide entries matching the
+ * path.
+ *
+ * @param path The path to the resource to return relative to the parent
+ * resource provider entry, which called this method.
+ * @param fullPath The actual path to the resource as provided to the
+ * {@link #getResource(String)} method.
+ * @return The resource for the path or <code>null</code> if no resource
+ * can be found.
+ * @throws SlingException if an error occurrs trying to access an existing
+ * resource.
+ */
+ private Resource getResource(String path, String fullPath) {
if (path.equals(this.path)) {
- return this;
- } else if (match(path)) {
+ return getResourceProvider().getResource(fullPath);
+ } else if (path.startsWith(this.prefix)) {
if (entries != null) {
// consider relative path for further checks
path = path.substring(this.prefix.length());
for (ResourceProviderEntry entry : entries) {
- ResourceProviderEntry test = entry.getResourceProvider(path);
+ Resource test = entry.getResource(path, fullPath);
if (test != null) {
return test;
}
@@ -85,22 +149,18 @@
}
// no more specific provider, return mine
- return this;
+ return getResourceProvider().getResource(fullPath);
}
// no match for my prefix, return null
return null;
}
- public boolean match(String path) {
- return path.startsWith(prefix);
- }
-
public boolean addResourceProvider(String prefix, ResourceProvider provider) {
if (prefix.equals(this.path)) {
throw new IllegalStateException(
"ResourceProviderEntry for prefix already exists");
- } else if (match(prefix)) {
+ } else if (prefix.startsWith(this.prefix)) {
// consider relative path for further checks
prefix = prefix.substring(this.prefix.length());
@@ -114,7 +174,7 @@
} else if (entry.prefix.startsWith(prefix)
&& entry.prefix.charAt(prefix.length()) == '/') {
ResourceProviderEntry newEntry = new ResourceProviderEntry(
- prefix, provider, this);
+ prefix, provider);
newEntry.addResourceProvider(entry.path, entry.provider);
entries[i] = newEntry;
return true;
@@ -125,7 +185,7 @@
// none found, so add it here
ResourceProviderEntry entry = new ResourceProviderEntry(prefix,
- provider, this);
+ provider);
if (entries == null) {
entries = new ResourceProviderEntry[] { entry };
} else {
@@ -145,7 +205,7 @@
public boolean removeResourceProvider(String prefix) {
if (prefix.equals(path)) {
return true;
- } else if (match(prefix)) {
+ } else if (prefix.startsWith(this.prefix)) {
// consider relative path for further checks
prefix = prefix.substring(this.prefix.length());
Modified: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProviderEntry.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProviderEntry.java?rev=618734&r1=618733&r2=618734&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProviderEntry.java (original)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProviderEntry.java Tue Feb 5 10:29:33 2008
@@ -31,7 +31,7 @@
JcrResourceResolverFactoryImpl resourceResolverFactory,
Session session, ResourceProviderEntry[] entries) {
super("/", new JcrResourceProvider(resourceResolverFactory, session),
- null, entries);
+ entries);
this.session = session;
}
Modified: incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java?rev=618734&r1=618733&r2=618734&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java (original)
+++ incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java Tue Feb 5 10:29:33 2008
@@ -25,6 +25,7 @@
import junit.framework.TestCase;
import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceProvider;
public class ResourceProviderEntryTest extends TestCase {
@@ -47,14 +48,12 @@
}
public void testRootProvider() {
- assertNull(root.getResourceProvider("relpath"));
- assertEquals(root, root.getResourceProvider("/"));
- assertEquals(root, root.getResourceProvider("/rootel"));
- assertEquals(root, root.getResourceProvider("/rootel/child"));
- assertEquals(root,
- root.getResourceProvider("/apps/sling/sample/html.js"));
- assertEquals(root,
- root.getResourceProvider("/apps/sling/microsling/html.js"));
+ assertNull(root.getResource("relpath"));
+ assertEquals(root, root.getResource("/"));
+ assertEquals(root, root.getResource("/rootel"));
+ assertEquals(root, root.getResource("/rootel/child"));
+ assertEquals(root, root.getResource("/apps/sling/sample/html.js"));
+ assertEquals(root, root.getResource("/apps/sling/microsling/html.js"));
}
public void testAdd1Provider() {
@@ -62,15 +61,15 @@
ResourceProvider first = new TestResourceProvider(firstPath);
root.addResourceProvider(firstPath, first);
- assertEquals(root, root.getResourceProvider("/"));
- assertEquals(first, root.getResourceProvider("/rootel").getResourceProvider());
- assertEquals(first, root.getResourceProvider("/rootel/html.js").getResourceProvider());
- assertEquals(first, root.getResourceProvider("/rootel/child").getResourceProvider());
- assertEquals(first, root.getResourceProvider("/rootel/child/html.js").getResourceProvider());
+ assertEquals(root, root.getResource("/"));
+ assertEquals(first, root.getResource("/rootel"));
+ assertEquals(first, root.getResource("/rootel/html.js"));
+ assertEquals(first, root.getResource("/rootel/child"));
+ assertEquals(first, root.getResource("/rootel/child/html.js"));
assertEquals(rootProvider,
- root.getResourceProvider("/apps/sling/sample/html.js").getResourceProvider());
+ root.getResource("/apps/sling/sample/html.js"));
assertEquals(rootProvider,
- root.getResourceProvider("/apps/sling/microsling/html.js").getResourceProvider());
+ root.getResource("/apps/sling/microsling/html.js"));
}
public void testAdd3Providers() {
@@ -86,15 +85,14 @@
root.addResourceProvider(secondPath, second);
root.addResourceProvider(thirdPath, third);
- assertEquals(rootProvider, root.getResourceProvider("/").getResourceProvider());
- assertEquals(first, root.getResourceProvider("/rootel").getResourceProvider());
- assertEquals(first, root.getResourceProvider("/rootel/html.js").getResourceProvider());
- assertEquals(second, root.getResourceProvider("/rootel/child").getResourceProvider());
- assertEquals(second, root.getResourceProvider("/rootel/child/html.js").getResourceProvider());
- assertEquals(third,
- root.getResourceProvider("/apps/sling/sample/html.js").getResourceProvider());
+ assertEquals(rootProvider, root.getResource("/"));
+ assertEquals(first, root.getResource("/rootel"));
+ assertEquals(first, root.getResource("/rootel/html.js"));
+ assertEquals(second, root.getResource("/rootel/child"));
+ assertEquals(second, root.getResource("/rootel/child/html.js"));
+ assertEquals(third, root.getResource("/apps/sling/sample/html.js"));
assertEquals(rootProvider,
- root.getResourceProvider("/apps/sling/microsling/html.js").getResourceProvider());
+ root.getResource("/apps/sling/microsling/html.js"));
}
public void testAdd3ProvidersReverse() {
@@ -110,15 +108,14 @@
root.addResourceProvider(secondPath, second);
root.addResourceProvider(firstPath, first);
- assertEquals(rootProvider, root.getResourceProvider("/").getResourceProvider());
- assertEquals(first, root.getResourceProvider("/rootel").getResourceProvider());
- assertEquals(first, root.getResourceProvider("/rootel/html.js").getResourceProvider());
- assertEquals(second, root.getResourceProvider("/rootel/child").getResourceProvider());
- assertEquals(second, root.getResourceProvider("/rootel/child/html.js").getResourceProvider());
- assertEquals(third,
- root.getResourceProvider("/apps/sling/sample/html.js").getResourceProvider());
+ assertEquals(rootProvider, root.getResource("/"));
+ assertEquals(first, root.getResource("/rootel"));
+ assertEquals(first, root.getResource("/rootel/html.js"));
+ assertEquals(second, root.getResource("/rootel/child"));
+ assertEquals(second, root.getResource("/rootel/child/html.js"));
+ assertEquals(third, root.getResource("/apps/sling/sample/html.js"));
assertEquals(rootProvider,
- root.getResourceProvider("/apps/sling/microsling/html.js").getResourceProvider());
+ root.getResource("/apps/sling/microsling/html.js"));
}
public void testRemoveProviders() {
@@ -134,21 +131,29 @@
root.addResourceProvider(secondPath, second);
root.addResourceProvider(thirdPath, third);
- assertEquals(rootProvider, root.getResourceProvider("/").getResourceProvider());
- assertEquals(first, root.getResourceProvider("/rootel/html.js").getResourceProvider());
- assertEquals(second, root.getResourceProvider("/rootel/child/html.js").getResourceProvider());
+ assertEquals(rootProvider, root.getResource("/"));
+ assertEquals(first, root.getResource("/rootel/html.js"));
+ assertEquals(second, root.getResource("/rootel/child/html.js"));
root.removeResourceProvider(firstPath);
- assertEquals(rootProvider, root.getResourceProvider("/").getResourceProvider());
- assertEquals(rootProvider, root.getResourceProvider("/rootel/html.js").getResourceProvider());
- assertEquals(second, root.getResourceProvider("/rootel/child/html.js").getResourceProvider());
+ assertEquals(rootProvider, root.getResource("/"));
+ assertEquals(rootProvider, root.getResource("/rootel/html.js"));
+ assertEquals(second, root.getResource("/rootel/child/html.js"));
root.addResourceProvider(firstPath, first);
- assertEquals(rootProvider, root.getResourceProvider("/").getResourceProvider());
- assertEquals(first, root.getResourceProvider("/rootel/html.js").getResourceProvider());
- assertEquals(second, root.getResourceProvider("/rootel/child/html.js").getResourceProvider());
+ assertEquals(rootProvider, root.getResource("/"));
+ assertEquals(first, root.getResource("/rootel/html.js"));
+ assertEquals(second, root.getResource("/rootel/child/html.js"));
+ }
+
+ protected void assertEquals(ResourceProvider resProvider, Resource res) {
+ assertEquals(resProvider, res.getResourceProvider());
+ }
+
+ protected void assertEquals(ResourceProviderEntry resProviderEntry, Resource res) {
+ assertEquals(resProviderEntry.getResourceProvider(), res.getResourceProvider());
}
private static class TestResourceProvider implements ResourceProvider {
@@ -164,7 +169,7 @@
}
public Resource getResource(String path) {
- return null;
+ return new TestResource(path, this);
}
public String[] getRoots() {
@@ -174,5 +179,37 @@
public Iterator<Resource> listChildren(Resource parent) {
return null;
}
+ }
+
+ private static class TestResource implements Resource {
+
+ private final String path;
+ private final ResourceProvider resourceProvider;
+
+ public TestResource(String path, ResourceProvider resourceProvider) {
+ this.path = path;
+ this.resourceProvider = resourceProvider;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public ResourceMetadata getResourceMetadata() {
+ return null;
+ }
+
+ public ResourceProvider getResourceProvider() {
+ return resourceProvider;
+ }
+
+ public String getResourceType() {
+ return null;
+ }
+
+ public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
+ return null;
+ }
+
}
}