Author: cziegeler
Date: Tue Sep 9 03:26:33 2008
New Revision: 693421
URL: http://svn.apache.org/viewvc?rev=693421&view=rev
Log:
SLING-460 - Implement vanity url handling.
Modified:
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolver.java
incubator/sling/trunk/jcr/resource/src/main/resources/SLING-INF/nodetypes/resource.cnd
incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.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=693421&r1=693420&r2=693421&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 Sep 9 03:26:33 2008
@@ -18,6 +18,7 @@
*/
package org.apache.sling.jcr.resource.internal;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -26,6 +27,7 @@
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
+import javax.jcr.query.Query;
import javax.jcr.query.QueryResult;
import javax.jcr.query.RowIterator;
import javax.servlet.http.HttpServletRequest;
@@ -38,6 +40,8 @@
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
import org.apache.sling.jcr.resource.JcrResourceUtil;
import
org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl.ResourcePattern;
import org.apache.sling.jcr.resource.internal.helper.Mapping;
@@ -260,6 +264,12 @@
return rootProvider.getSession();
}
+ /**
+ * Try to get a resource for the given url
+ * @param uri The url
+ * @return The resource or null
+ * @throws SlingException
+ */
private Resource urlToResource(String uri)
throws SlingException {
// apply regexp
@@ -290,11 +300,36 @@
log.debug("Cannot resolve {} to resource", mappedUri);
}
- log.info("Could not resolve URL {} to a Resource", uri);
+ // handle vanity paths
+ final ResourcePathIterator it = new ResourcePathIterator(uri);
+ while (it.hasNext() ) {
+ final String curPath = it.next();
+ final Resource resource = searchVanityPath(curPath);
+ if ( resource != null ) {
+ final ResourceMetadata rm = resource.getResourceMetadata();
+ String rpi = uri.substring(curPath.length());
+ resource.getResourceMetadata().setResolutionPathInfo(rpi);
+
+ final String path = rm.getResolutionPath();
+ if (!uri.equals(path)) {
+ resource.getResourceMetadata().setResolutionPath(uri);
+ }
+
+ return resource;
+ }
+ }
+
+ log.debug("Could not resolve URL {} to a Resource", uri);
return null;
}
+ /**
+ * Apply the regexp patterns
+ * @param uri
+ * @param patterns
+ * @return
+ */
private String applyPattern(String uri, final ResourcePattern[] patterns) {
for(final ResourcePattern pattern : patterns) {
final Matcher matcher = pattern.pattern.matcher(uri);
@@ -316,6 +351,34 @@
return uri;
}
+ /**
+ * Search for a vanity path for this
+ * @param path
+ * @return
+ */
+ private Resource searchVanityPath(String path) {
+ final String queryString = "SELECT * FROM sling:VanityPath where
sling:vanityPath ='" + path +
+ "' ORDER BY sling:vanityOrder DESC";
+ final Iterator<Resource> i = this.findResources(queryString,
Query.SQL);
+ if ( i.hasNext() ) {
+ Resource rsrc = i.next();
+ boolean needsWrapper = false;
+ final ValueMap properties = rsrc.adaptTo(ValueMap.class);
+ if ( properties != null ) {
+ needsWrapper = properties.get("sling:redirect", false);
+ }
+ // check if this is a content node, then use the parent
+ if ( ResourceUtil.getName(rsrc).equals("jcr:content") ) {
+ rsrc = ResourceUtil.getParent(rsrc);
+ }
+ if ( needsWrapper ) {
+ rsrc = new RedirectResource(rsrc, path, rsrc.getPath());
+ }
+ return rsrc;
+ }
+ return null;
+ }
+
private Resource scanPath(final String uriPath)
throws SlingException {
Resource resource = null;
@@ -357,4 +420,67 @@
return null;
}
+ private static final class RedirectResource implements Resource {
+
+ final Resource resource;
+
+ final String target;
+
+ final String path;
+
+ public RedirectResource(final Resource rsrc,
+ final String path,
+ final String target) {
+ this.resource = rsrc;
+ this.path = path;
+ this.target = target;
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.Resource#getPath()
+ */
+ public String getPath() {
+ return this.path;
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.Resource#getResourceMetadata()
+ */
+ public ResourceMetadata getResourceMetadata() {
+ return this.resource.getResourceMetadata();
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.Resource#getResourceResolver()
+ */
+ public ResourceResolver getResourceResolver() {
+ return this.resource.getResourceResolver();
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.Resource#getResourceSuperType()
+ */
+ public String getResourceSuperType() {
+ return null;
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.Resource#getResourceType()
+ */
+ public String getResourceType() {
+ return "sling:redirect";
+ }
+
+ /**
+ * @see org.apache.sling.api.adapter.Adaptable#adaptTo(java.lang.Class)
+ */
+ @SuppressWarnings("unchecked")
+ public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
+ if ( type == ValueMap.class ) {
+ return (AdapterType) new
ValueMapDecorator(Collections.singletonMap("sling:target",
(Object)this.target));
+ }
+ return null;
+ }
+
+ }
}
Modified:
incubator/sling/trunk/jcr/resource/src/main/resources/SLING-INF/nodetypes/resource.cnd
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/resources/SLING-INF/nodetypes/resource.cnd?rev=693421&r1=693420&r2=693421&view=diff
==============================================================================
---
incubator/sling/trunk/jcr/resource/src/main/resources/SLING-INF/nodetypes/resource.cnd
(original)
+++
incubator/sling/trunk/jcr/resource/src/main/resources/SLING-INF/nodetypes/resource.cnd
Tue Sep 9 03:26:33 2008
@@ -36,4 +36,11 @@
// as a child of nt:folder and allows to add unstructured content
[sling:Folder] > nt:hierarchyNode, nt:unstructured
orderable
- + * (nt:base) = sling:Folder version
\ No newline at end of file
+ + * (nt:base) = sling:Folder version
+
+//-----------------------------------------------------------------------------
+// Mixin node type for defining vanity resource path.
+[sling:VanityPath]
+ - sling:vanityPath (string)
+ - sling:redirect (boolean)
+ - sling:vanityOrder (long)
\ No newline at end of file
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=693421&r1=693420&r2=693421&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
Tue Sep 9 03:26:33 2008
@@ -39,6 +39,7 @@
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.commons.testing.jcr.RepositoryTestBase;
+import org.apache.sling.commons.testing.jcr.RepositoryUtil;
import org.apache.sling.jcr.resource.JcrResourceConstants;
import org.apache.sling.jcr.resource.internal.helper.Mapping;
import org.apache.sling.jcr.resource.internal.helper.starresource.StarResource;
@@ -53,7 +54,8 @@
protected void setUp() throws Exception {
super.setUp();
- getSession();
+ assertTrue(RepositoryUtil.registerNodeType(getSession(),
+
this.getClass().getResourceAsStream("/SLING-INF/nodetypes/resource.cnd")));
JcrResourceResolverFactoryImpl resFac = new
JcrResourceResolverFactoryImpl();