You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2010/04/08 09:25:02 UTC
svn commit: r931805 - in /sling/trunk/bundles:
api/src/main/java/org/apache/sling/api/servlets/
servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/
servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/hel...
Author: cziegeler
Date: Thu Apr 8 07:25:02 2010
New Revision: 931805
URL: http://svn.apache.org/viewvc?rev=931805&view=rev
Log:
SLING-585 : New functionality to resolve scripts by name
Added:
sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollector.java (with props)
sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/NamedScriptResourceCollector.java (with props)
Modified:
sling/trunk/bundles/api/src/main/java/org/apache/sling/api/servlets/ServletResolver.java
sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollector.java
sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/helper/LocationIteratorTest.java
Modified: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/servlets/ServletResolver.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/api/src/main/java/org/apache/sling/api/servlets/ServletResolver.java?rev=931805&r1=931804&r2=931805&view=diff
==============================================================================
--- sling/trunk/bundles/api/src/main/java/org/apache/sling/api/servlets/ServletResolver.java (original)
+++ sling/trunk/bundles/api/src/main/java/org/apache/sling/api/servlets/ServletResolver.java Thu Apr 8 07:25:02 2010
@@ -21,6 +21,8 @@ package org.apache.sling.api.servlets;
import javax.servlet.Servlet;
import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
/**
* The <code>ServletResolver</code> defines the API for a service capable of
@@ -47,7 +49,7 @@ public interface ServletResolver {
* implementing the {@link OptingServlet} interface and returning
* <code>false</code> when the
* {@link OptingServlet#accepts(SlingHttpServletRequest)} method is called.
- *
+ *
* @param request The {@link SlingHttpServletRequest} object used to drive
* selection of the servlet.
* @return The servlet whose <code>service</code> method may be called to
@@ -59,4 +61,59 @@ public interface ServletResolver {
*/
Servlet resolveServlet(SlingHttpServletRequest request);
+ /**
+ * Resolves a <code>javax.servlet.Servlet</code> whose
+ * <code>service</code> method may be used to handle a request.
+ * <p>
+ * The returned servlet must be assumed to be initialized and ready to run.
+ * That is, the <code>init</code> nor the <code>destroy</code> methods
+ * must <em>NOT</em> be called on the returned servlet.
+ * <p>
+ * This method skips all {@link OptingServlet}s as there is no
+ * request object available.
+ *
+ * Basically this method searches a script with the <code>scriptName</code>
+ * for the resource type defined by the <code>resource</code>
+ * @param resource The {@link Resource} object used to drive
+ * selection of the servlet.
+ * @param scriptName The name of the script - the script might have an
+ * extension. In this case only a script with the
+ * matching extension is used.
+ * @return The servlet whose <code>service</code> method may be called to
+ * handle the request.
+ * @throws org.apache.sling.api.SlingException Is thrown if an error occurrs
+ * while trying to find an appropriate servlet to handle the
+ * request or if no servlet could be resolved to handle the
+ * request.
+ * @since 2.1
+ */
+ Servlet resolveServlet(Resource resource, String scriptName);
+
+ /**
+ * Resolves a <code>javax.servlet.Servlet</code> whose
+ * <code>service</code> method may be used to handle a request.
+ * <p>
+ * The returned servlet must be assumed to be initialized and ready to run.
+ * That is, the <code>init</code> nor the <code>destroy</code> methods
+ * must <em>NOT</em> be called on the returned servlet.
+ * <p>
+ * This method skips all {@link OptingServlet}s as there is no
+ * request object available.
+ *
+ * Basically this method searches a script with the <code>scriptName</code>
+ * @param resolver The {@link ResourceResolver} object used to drive
+ * selection of the servlet.
+ * @param scriptName The name of the script - the script might have an
+ * extension. In this case only a script with the
+ * matching extension is used.
+ * @return The servlet whose <code>service</code> method may be called to
+ * handle the request.
+ * @throws org.apache.sling.api.SlingException Is thrown if an error occurrs
+ * while trying to find an appropriate servlet to handle the
+ * request or if no servlet could be resolved to handle the
+ * request.
+ * @since 2.1
+ */
+ Servlet resolveServlet(ResourceResolver resolver, String scriptName);
+
}
Modified: sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java?rev=931805&r1=931804&r2=931805&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java (original)
+++ sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java Thu Apr 8 07:25:02 2010
@@ -68,6 +68,8 @@ import org.apache.sling.jcr.api.SlingRep
import org.apache.sling.jcr.resource.JcrResourceResolverFactory;
import org.apache.sling.servlets.resolver.internal.defaults.DefaultErrorHandlerServlet;
import org.apache.sling.servlets.resolver.internal.defaults.DefaultServlet;
+import org.apache.sling.servlets.resolver.internal.helper.AbstractResourceCollector;
+import org.apache.sling.servlets.resolver.internal.helper.NamedScriptResourceCollector;
import org.apache.sling.servlets.resolver.internal.helper.ResourceCollector;
import org.apache.sling.servlets.resolver.internal.helper.SlingServletConfig;
import org.apache.sling.servlets.resolver.internal.resource.ServletResourceProvider;
@@ -187,7 +189,7 @@ public class SlingServletResolver implem
// a request. This field is set on demand by getDefaultErrorServlet()
private Servlet fallbackErrorServlet;
- private Map<ResourceCollector, Servlet> cache;
+ private Map<AbstractResourceCollector, Servlet> cache;
private ServiceRegistration eventHandlerReg;
@@ -263,7 +265,7 @@ public class SlingServletResolver implem
// log the servlet found
if (log.isDebugEnabled()) {
if (servlet != null) {
- log.info("Servlet {} found for resource={}", RequestUtil.getServletName(servlet), resource);
+ log.debug("Servlet {} found for resource={}", RequestUtil.getServletName(servlet), resource);
} else {
log.debug("No servlet found for resource={}", resource);
}
@@ -272,6 +274,86 @@ public class SlingServletResolver implem
return servlet;
}
+ /**
+ * @see org.apache.sling.api.servlets.ServletResolver#resolveServlet(org.apache.sling.api.resource.Resource, java.lang.String)
+ */
+ public Servlet resolveServlet(final Resource resource, final String scriptName) {
+ if ( resource == null ) {
+ throw new IllegalArgumentException("Resource must not be null");
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("resolveServlet called for resource {} with script name {}", resource, scriptName);
+ }
+
+ final Servlet servlet = resolveServlet(defaultScriptResolver, resource, scriptName);
+
+ // log the servlet found
+ if (log.isDebugEnabled()) {
+ if (servlet != null) {
+ log.debug("Servlet {} found for resource {} and script name {}", new Object[] {RequestUtil.getServletName(servlet), resource, scriptName});
+ } else {
+ log.debug("No servlet found for resource {} and script name {}", resource, scriptName);
+ }
+ }
+
+ return servlet;
+ }
+
+ /**
+ * @see org.apache.sling.api.servlets.ServletResolver#resolveServlet(org.apache.sling.api.resource.ResourceResolver, java.lang.String)
+ */
+ public Servlet resolveServlet(final ResourceResolver resolver, final String scriptName) {
+ if ( resolver == null ) {
+ throw new IllegalArgumentException("Resource resolver must not be null");
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("resolveServlet called for for script name {}", scriptName);
+ }
+
+ final Servlet servlet = resolveServlet(defaultScriptResolver, null, scriptName);
+
+ // log the servlet found
+ if (log.isDebugEnabled()) {
+ if (servlet != null) {
+ log.debug("Servlet {} found for script name {}", RequestUtil.getServletName(servlet), scriptName);
+ } else {
+ log.debug("No servlet found for script name {}", scriptName);
+ }
+ }
+
+ return servlet;
+ }
+
+ private Servlet resolveServlet(final ResourceResolver resolver,
+ final Resource resource,
+ final String scriptName) {
+ Servlet servlet = null;
+
+ // first check whether the type of a resource is the absolute
+ // path of a servlet (or script)
+ if (scriptName.charAt(0) == '/') {
+ final Resource res = resolver.getResource(scriptName);
+ if (res != null) {
+ servlet = res.adaptTo(Servlet.class);
+ }
+ if (servlet != null && log.isDebugEnabled()) {
+ log.debug("Servlet {} found using absolute resource type {}", RequestUtil.getServletName(servlet),
+ scriptName);
+ }
+ }
+
+ // the resource type is not absolute, so lets go for the deep search
+ if (servlet == null) {
+ final NamedScriptResourceCollector locationUtil = NamedScriptResourceCollector.create(scriptName, resource);
+ servlet = getServlet(locationUtil, null, resolver);
+
+ if (log.isDebugEnabled()) {
+ log.debug("resolveServlet returns servlet {}", RequestUtil.getServletName(servlet));
+ }
+ }
+ return servlet;
+
+ }
// ---------- ScriptResolver interface ------------------------------------
public SlingScript findScript(ResourceResolver resourceResolver, String name) throws SlingException {
@@ -501,7 +583,8 @@ public class SlingServletResolver implem
* @return a servlet for handling the request or <code>null</code> if no
* such servlet willing to handle the request could be found.
*/
- private Servlet getServlet(final ResourceCollector locationUtil, final SlingHttpServletRequest request,
+ private Servlet getServlet(final AbstractResourceCollector locationUtil,
+ final SlingHttpServletRequest request,
final ResourceResolver scriptResolver) {
final Servlet scriptServlet = (this.cache != null ? this.cache.get(locationUtil) : null);
if (scriptServlet != null) {
@@ -531,7 +614,7 @@ public class SlingServletResolver implem
Servlet candidate = candidateResource.adaptTo(Servlet.class);
if (candidate != null) {
final boolean isOptingServlet = candidate instanceof OptingServlet;
- boolean servletAcceptsRequest = !isOptingServlet || ((OptingServlet) candidate).accepts(request);
+ boolean servletAcceptsRequest = !isOptingServlet || (request != null && ((OptingServlet) candidate).accepts(request));
if (servletAcceptsRequest) {
if (!hasOptingServlet && !isOptingServlet && this.cache != null) {
this.cache.put(locationUtil, candidate);
@@ -749,7 +832,7 @@ public class SlingServletResolver implem
// create cache - if a cache size is configured
final int cacheSize = OsgiUtil.toInteger(properties.get(PROP_CACHE_SIZE), DEFAULT_CACHE_SIZE);
if (cacheSize > 5) {
- this.cache = new ConcurrentHashMap<ResourceCollector, Servlet>(cacheSize);
+ this.cache = new ConcurrentHashMap<AbstractResourceCollector, Servlet>(cacheSize);
}
createAllServlets(refs);
Added: sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollector.java?rev=931805&view=auto
==============================================================================
--- sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollector.java (added)
+++ sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollector.java Thu Apr 8 07:25:02 2010
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.servlets.resolver.internal.helper;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.SyntheticResource;
+
+/**
+ * The <code>ResourceCollector</code> class provides a single public method -
+ * {@link #getServlets(ResourceResolver)} - which is used to find an ordered collection
+ * of <code>Resource</code> instances which may be used to find a servlet or
+ * script to handle a request to the given resource.
+ */
+public abstract class AbstractResourceCollector {
+
+ // the most generic resource type to use. This may be null in which
+ // case the default servlet name will be used as the base name
+ protected final String baseResourceType;
+
+ // the request extension or null if the request has no extension
+ protected final String extension;
+
+ protected int hashCode;
+
+ protected final String resourceType;
+
+ protected final String resourceSuperType;
+
+ public AbstractResourceCollector(final String baseResourceType,
+ final String resourceType,
+ final String resourceSuperType,
+ final String extension) {
+ this.baseResourceType = baseResourceType;
+ this.resourceType = resourceType;
+ this.resourceSuperType = resourceSuperType;
+ this.extension = extension;
+ }
+
+ public final Collection<Resource> getServlets(ResourceResolver resolver) {
+
+ final SortedSet<Resource> resources = new TreeSet<Resource>();
+ final Iterator<String> locations = new LocationIterator(resourceType, resourceSuperType,
+ baseResourceType, resolver);
+ while (locations.hasNext()) {
+ final String location = locations.next();
+
+ // get the location resource, use a synthetic resource if there
+ // is no real location. There may still be children at this
+ // location
+ final String path;
+ if ( location.endsWith("/") ) {
+ path = location.substring(0, location.length() - 1);
+ } else {
+ path = location;
+ }
+ final Resource locationRes = getResource(resolver, path);
+ getWeightedResources(resources, locationRes);
+ }
+
+ return resources;
+ }
+
+ abstract protected void getWeightedResources(final Set<Resource> resources,
+ final Resource location);
+
+ /**
+ * Creates a {@link WeightedResource} and adds it to the set of resources.
+ * The number of resources already present in the set is used as the ordinal
+ * number for the newly created resource.
+ *
+ * @param resources The set of resource to which the
+ * {@link WeightedResource} is added.
+ * @param resource The <code>Resource</code> on which the
+ * {@link WeightedResource} is based.
+ * @param numSelectors The number of request selectors which are matched by
+ * the name of the resource.
+ * @param methodPrefixWeight The method/prefix weight assigned to the
+ * resource according to the resource name.
+ */
+ protected final void addWeightedResource(final Set<Resource> resources,
+ final Resource resource,
+ final int numSelectors,
+ final int methodPrefixWeight) {
+ final WeightedResource lr = new WeightedResource(resources.size(), resource,
+ numSelectors, methodPrefixWeight);
+ resources.add(lr);
+ }
+
+ /**
+ * Returns a resource for the given <code>path</code>.
+ * If no resource exists at the given path a
+ * <code>SyntheticResource</code> is returned.
+ *
+ * @param resolver The <code>ResourceResolver</code> used to access the
+ * resource.
+ * @param path The absolute path of the resource to return.
+ * @return The actual resource at the given <code>path</code> or a
+ * synthetic resource representing the path location.
+ */
+ protected final Resource getResource(final ResourceResolver resolver,
+ String path) {
+ Resource res = resolver.getResource(path);
+
+ if (res == null) {
+ if (!path.startsWith("/")) {
+ path = "/".concat(path);
+ }
+
+ res = new SyntheticResource(resolver, path, "$synthetic$");
+ }
+
+ return res;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( !(obj instanceof AbstractResourceCollector) ) {
+ return false;
+ }
+ if ( obj == this ) {
+ return true;
+ }
+ final AbstractResourceCollector o = (AbstractResourceCollector)obj;
+ if ( stringEquals(resourceType, o.resourceType)
+ && stringEquals(resourceSuperType, o.resourceSuperType)
+ && stringEquals(extension, o.extension)
+ && stringEquals(baseResourceType, o.baseResourceType)) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return this.hashCode;
+ }
+
+ /**
+ * Helper method to compare two strings which can possibly be <code>null</code>
+ */
+ protected boolean stringEquals(final String s1, final String s2) {
+ if ( s1 == null && s2 == null ) {
+ return true;
+ }
+ if ( s1 == null || s2 == null ) {
+ return false;
+ }
+ return s1.equals(s2);
+ }
+}
Propchange: sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollector.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollector.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange: sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollector.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/NamedScriptResourceCollector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/NamedScriptResourceCollector.java?rev=931805&view=auto
==============================================================================
--- sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/NamedScriptResourceCollector.java (added)
+++ sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/NamedScriptResourceCollector.java Thu Apr 8 07:25:02 2010
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.servlets.resolver.internal.helper;
+
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.servlets.resolver.internal.ServletResolverConstants;
+
+/**
+ * The <code>ResourceCollector</code> class provides a single public method -
+ * {@link #getServlets(ResourceResolver)} - which is used to find an ordered collection
+ * of <code>Resource</code> instances which may be used to find a servlet or
+ * script to handle a request to the given resource.
+ */
+public class NamedScriptResourceCollector extends AbstractResourceCollector {
+
+ private final String scriptName;
+
+ public static NamedScriptResourceCollector create(final String name, final Resource resource) {
+ final String resourceType;
+ final String resourceSuperType;
+ final String baseResourceType;
+ final String extension;
+ final String scriptName;
+ if ( resource != null ) {
+ resourceType = resource.getResourceType();
+ resourceSuperType = resource.getResourceSuperType();
+ baseResourceType = ServletResolverConstants.DEFAULT_SERVLET_NAME;
+ } else {
+ resourceType = "";
+ resourceSuperType = null;
+ baseResourceType = "";
+ }
+ final int pos = name.indexOf('.');
+ if ( pos == -1 ) {
+ extension = null;
+ scriptName = name;
+ } else {
+ extension = name.substring(pos);
+ scriptName = name.substring(0, pos);
+ }
+ return new NamedScriptResourceCollector(baseResourceType,
+ resourceType,
+ resourceSuperType,
+ scriptName,
+ extension);
+ }
+
+ public NamedScriptResourceCollector(final String baseResourceType,
+ final String resourceType,
+ final String resourceSuperType,
+ final String scriptName,
+ final String extension) {
+ super(baseResourceType, resourceType, resourceSuperType, extension);
+ this.scriptName = scriptName;
+ // create the hash code once
+ final String key = baseResourceType + ':' + this.scriptName + ':' +
+ this.resourceType + ':' + (this.resourceSuperType == null ? "" : this.resourceSuperType) +
+ ':' + (this.extension == null ? "" : this.extension);
+ this.hashCode = key.hashCode();
+ }
+
+ protected void getWeightedResources(final Set<Resource> resources,
+ final Resource location) {
+ final ResourceResolver resolver = location.getResourceResolver();
+ // if extension is set, we just check the exact script
+ if ( this.extension != null ) {
+ final String path = location.getPath() + '/' + this.scriptName + this.extension;
+ final Resource current = resolver.getResource(path);
+ if ( current != null ) {
+ this.addWeightedResource(resources, current, 0, WeightedResource.WEIGHT_EXTENSION);
+ }
+ } else {
+ // if the script name denotes a path we have to get the denoted resource
+ // first
+ final Resource current;
+ final String name;
+ final int pos = this.scriptName.lastIndexOf('/');
+ if ( pos == -1 ) {
+ current = location;
+ name = this.scriptName;
+ } else {
+ current = getResource(resolver, location.getPath() + '/' + this.scriptName.substring(0, pos));
+ name = this.scriptName.substring(pos + 1);
+ }
+ final Iterator<Resource> children = resolver.listChildren(current);
+ while (children.hasNext()) {
+ final Resource child = children.next();
+
+ String scriptName = ResourceUtil.getName(child);
+ final int lastDot = scriptName.lastIndexOf('.');
+ if (lastDot < 0) {
+ // no extension in the name, this is not a script
+ continue;
+ }
+
+ scriptName = scriptName.substring(0, lastDot);
+
+ if ( scriptName.equals(name) ) {
+ this.addWeightedResource(resources, child, 0, WeightedResource.WEIGHT_PREFIX);
+ continue;
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( !(obj instanceof NamedScriptResourceCollector) ) {
+ return false;
+ }
+ if ( obj == this ) {
+ return true;
+ }
+ if ( super.equals(obj) ) {
+ final NamedScriptResourceCollector o = (NamedScriptResourceCollector)obj;
+ if ( stringEquals(scriptName, o.scriptName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
Propchange: sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/NamedScriptResourceCollector.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/NamedScriptResourceCollector.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange: sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/NamedScriptResourceCollector.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollector.java?rev=931805&r1=931804&r2=931805&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollector.java (original)
+++ sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollector.java Thu Apr 8 07:25:02 2010
@@ -18,18 +18,14 @@
*/
package org.apache.sling.servlets.resolver.internal.helper;
-import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.request.RequestPathInfo;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.api.resource.SyntheticResource;
import org.apache.sling.servlets.resolver.internal.ServletResolverConstants;
import org.apache.sling.servlets.resolver.internal.resource.ServletResourceProviderFactory;
@@ -39,7 +35,7 @@ import org.apache.sling.servlets.resolve
* of <code>Resource</code> instances which may be used to find a servlet or
* script to handle a request to the given resource.
*/
-public class ResourceCollector {
+public class ResourceCollector extends AbstractResourceCollector {
/**
* The special value returned by
@@ -53,10 +49,6 @@ public class ResourceCollector {
// the request method name used to indicate the script name
private final String methodName;
- // the most generic resource type to use. This may be null in which
- // case the default servlet name will be used as the base name
- private final String baseResourceType;
-
// the request selectors as a string converted to a realtive path or
// null if the request has no selectors
private final String[] requestSelectors;
@@ -64,21 +56,12 @@ public class ResourceCollector {
// the number of request selectors of the request or 0 if none
private final int numRequestSelectors;
- // the request extension or null if the request has no extension
- private final String extension;
-
// request is GET or HEAD
private final boolean isGet;
// request is GET or HEAD and extension is html
private final boolean isHtml;
- private final int hashCode;
-
- private final String resourceType;
-
- private final String resourceSuperType;
-
private final String workspaceName;
/**
@@ -113,15 +96,15 @@ public class ResourceCollector {
* @param resource the resource to invoke, the resource type and resource super type are taken from this resource.
*/
public ResourceCollector(String methodName, String baseResourceType, Resource resource, String workspaceName) {
+ super((baseResourceType != null ? baseResourceType : ServletResolverConstants.DEFAULT_SERVLET_NAME),
+ resource.getResourceType(),
+ resource.getResourceSuperType(),
+ null);
this.methodName = methodName;
- this.baseResourceType = (baseResourceType != null ? baseResourceType : ServletResolverConstants.DEFAULT_SERVLET_NAME);
this.requestSelectors = new String[0];
this.numRequestSelectors = 0;
- this.extension = null;
this.isGet = false;
this.isHtml = false;
- this.resourceType = resource.getResourceType();
- this.resourceSuperType = resource.getResourceSuperType();
this.workspaceName = workspaceName;
// create the hash code once
@@ -145,16 +128,16 @@ public class ResourceCollector {
* is assumed.
*/
private ResourceCollector(SlingHttpServletRequest request, String workspaceName) {
+ super(ServletResolverConstants.DEFAULT_SERVLET_NAME,
+ request.getResource().getResourceType(),
+ request.getResource().getResourceSuperType(),
+ request.getRequestPathInfo().getExtension());
this.methodName = request.getMethod();
- this.baseResourceType = ServletResolverConstants.DEFAULT_SERVLET_NAME;
- this.resourceType = request.getResource().getResourceType();
- this.resourceSuperType = request.getResource().getResourceSuperType();
RequestPathInfo requestpaInfo = request.getRequestPathInfo();
requestSelectors = requestpaInfo.getSelectors();
numRequestSelectors = requestSelectors.length;
- extension = request.getRequestPathInfo().getExtension();
isGet = "GET".equals(methodName) || "HEAD".equals(methodName);
isHtml = isGet && "html".equals(extension);
@@ -167,27 +150,8 @@ public class ResourceCollector {
this.hashCode = key.hashCode();
}
- public final Collection<Resource> getServlets(ResourceResolver resolver) {
-
- SortedSet<Resource> resources = new TreeSet<Resource>();
-
- Iterator<String> locations = new LocationIterator(resourceType, resourceSuperType,
- baseResourceType, resolver);
- while (locations.hasNext()) {
- String location = locations.next();
-
- // get the location resource, use a synthetic resource if there
- // is no real location. There may still be children at this
- // location
- Resource locationRes = getResource(resolver, location);
- getWeightedResources(resources, locationRes);
- }
-
- return resources;
- }
-
- protected void getWeightedResources(Set<Resource> resources,
- Resource location) {
+ protected void getWeightedResources(final Set<Resource> resources,
+ Resource location) {
ResourceResolver resolver = location.getResourceResolver();
Resource current = location;
@@ -281,53 +245,6 @@ public class ResourceCollector {
}
}
- /**
- * Creates a {@link WeightedResource} and adds it to the set of resources.
- * The number of resources already present in the set is used as the ordinal
- * number for the newly created resource.
- *
- * @param resources The set of resource to which the
- * {@link WeightedResource} is added.
- * @param resource The <code>Resource</code> on which the
- * {@link WeightedResource} is based.
- * @param numSelectors The number of request selectors which are matched by
- * the name of the resource.
- * @param methodPrefixWeight The method/prefix weight assigned to the
- * resource according to the resource name.
- */
- protected final void addWeightedResource(Set<Resource> resources,
- Resource resource, int numSelectors, int methodPrefixWeight) {
- WeightedResource lr = new WeightedResource(resources.size(), resource,
- numSelectors, methodPrefixWeight);
- resources.add(lr);
- }
-
- /**
- * Returns a resource for the given <code>path</code>.
- * If no resource exists at the given path a
- * <code>SyntheticResource</code> is returned.
- *
- * @param resolver The <code>ResourceResolver</code> used to access the
- * resource.
- * @param path The absolute path of the resource to return.
- * @return The actual resource at the given <code>path</code> or a
- * synthetic resource representing the path location.
- */
- protected final Resource getResource(ResourceResolver resolver,
- String path) {
- Resource res = resolver.getResource(path);
-
- if (res == null) {
- if (!path.startsWith("/")) {
- path = "/".concat(path);
- }
-
- res = new SyntheticResource(resolver, path, "$synthetic$");
- }
-
- return res;
- }
-
@Override
public boolean equals(Object obj) {
if ( !(obj instanceof ResourceCollector) ) {
@@ -336,42 +253,22 @@ public class ResourceCollector {
if ( obj == this ) {
return true;
}
- final ResourceCollector o = (ResourceCollector)obj;
- if ( isGet == o.isGet
- && isHtml == o.isHtml
- && numRequestSelectors == o.numRequestSelectors
- && stringEquals(resourceType, o.resourceType)
- && stringEquals(resourceSuperType, o.resourceSuperType)
- && stringEquals(extension, o.extension)
- && stringEquals(baseResourceType, o.baseResourceType)
- && stringEquals(methodName, o.methodName)
- && stringEquals(workspaceName, o.workspaceName)) {
- // now compare selectors
- for(int i=0;i<numRequestSelectors;i++) {
- if ( !stringEquals(requestSelectors[i], o.requestSelectors[i]) ) {
- return false;
+ if ( super.equals(obj) ) {
+ final ResourceCollector o = (ResourceCollector)obj;
+ if ( isGet == o.isGet
+ && isHtml == o.isHtml
+ && numRequestSelectors == o.numRequestSelectors
+ && stringEquals(methodName, o.methodName)
+ && stringEquals(workspaceName, o.workspaceName)) {
+ // now compare selectors
+ for(int i=0;i<numRequestSelectors;i++) {
+ if ( !stringEquals(requestSelectors[i], o.requestSelectors[i]) ) {
+ return false;
+ }
}
+ return true;
}
- return true;
}
return false;
}
-
- @Override
- public int hashCode() {
- return this.hashCode;
- }
-
- /**
- * Helper method to compare two strings which can possibly be <code>null</code>
- */
- private boolean stringEquals(final String s1, final String s2) {
- if ( s1 == null && s2 == null ) {
- return true;
- }
- if ( s1 == null || s2 == null ) {
- return false;
- }
- return s1.equals(s2);
- }
}
Modified: sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/helper/LocationIteratorTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/helper/LocationIteratorTest.java?rev=931805&r1=931804&r2=931805&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/helper/LocationIteratorTest.java (original)
+++ sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/helper/LocationIteratorTest.java Thu Apr 8 07:25:02 2010
@@ -408,4 +408,61 @@ public class LocationIteratorTest extend
// 6. finished
assertFalse(li.hasNext());
}
+
+ public void testScriptNameWithoutResourceType() {
+ String root0 = "/apps";
+ String root1 = "/libs";
+ resourceResolver.setSearchPath(root0, root1);
+ LocationIterator li = new LocationIterator("",
+ null,
+ "",
+ resourceResolver);
+ assertTrue(li.hasNext());
+ assertEquals("/apps/", li.next());
+ assertTrue(li.hasNext());
+ assertEquals("/libs/", li.next());
+ assertFalse(li.hasNext());
+ }
+
+ public void testScriptNameWithResourceType() {
+ String root0 = "/apps";
+ String root1 = "/libs";
+ resourceResolver.setSearchPath(root0, root1);
+ LocationIterator li = new LocationIterator("a/b",
+ null,
+ DEFAULT_SERVLET_NAME,
+ resourceResolver);
+ assertTrue(li.hasNext());
+ assertEquals(root0 + "/a/b", li.next());
+ assertTrue(li.hasNext());
+ assertEquals(root1 + "/a/b", li.next());
+ assertTrue(li.hasNext());
+ assertEquals(root0 + "/" + DEFAULT_SERVLET_NAME, li.next());
+ assertTrue(li.hasNext());
+ assertEquals(root1 + "/" + DEFAULT_SERVLET_NAME, li.next());
+ assertFalse(li.hasNext());
+ }
+
+ public void testScriptNameWithResourceTypeAndSuperType() {
+ String root0 = "/apps";
+ String root1 = "/libs";
+ resourceResolver.setSearchPath(root0, root1);
+ LocationIterator li = new LocationIterator("a/b",
+ "c/d",
+ DEFAULT_SERVLET_NAME,
+ resourceResolver);
+ assertTrue(li.hasNext());
+ assertEquals(root0 + "/a/b", li.next());
+ assertTrue(li.hasNext());
+ assertEquals(root1 + "/a/b", li.next());
+ assertTrue(li.hasNext());
+ assertEquals(root0 + "/c/d", li.next());
+ assertTrue(li.hasNext());
+ assertEquals(root1 + "/c/d", li.next());
+ assertTrue(li.hasNext());
+ assertEquals(root0 + "/" + DEFAULT_SERVLET_NAME, li.next());
+ assertTrue(li.hasNext());
+ assertEquals(root1 + "/" + DEFAULT_SERVLET_NAME, li.next());
+ assertFalse(li.hasNext());
+ }
}