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/11/26 22:27:26 UTC

svn commit: r720984 - in /incubator/sling/whiteboard/fmeschbe/servlet_resolver: ./ src/main/java/org/apache/sling/servlets/resolver/helper/ src/test/java/org/apache/sling/servlets/resolver/helper/

Author: fmeschbe
Date: Wed Nov 26 13:27:26 2008
New Revision: 720984

URL: http://svn.apache.org/viewvc?rev=720984&view=rev
Log:
Prototype new servlet resolution

Removed:
    incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/main/java/org/apache/sling/servlets/resolver/helper/ResourceCollectorGet.java
    incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/test/java/org/apache/sling/servlets/resolver/helper/ResourceCollectorGetCalculatePrefixWeightTest.java
Modified:
    incubator/sling/whiteboard/fmeschbe/servlet_resolver/pom.xml
    incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/main/java/org/apache/sling/servlets/resolver/helper/ResourceCollector.java
    incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/main/java/org/apache/sling/servlets/resolver/helper/WeightedResource.java
    incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/test/java/org/apache/sling/servlets/resolver/helper/ResourceCollectorGetServletsTest.java
    incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/test/java/org/apache/sling/servlets/resolver/helper/ScriptSelectionTest.java

Modified: incubator/sling/whiteboard/fmeschbe/servlet_resolver/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/whiteboard/fmeschbe/servlet_resolver/pom.xml?rev=720984&r1=720983&r2=720984&view=diff
==============================================================================
--- incubator/sling/whiteboard/fmeschbe/servlet_resolver/pom.xml (original)
+++ incubator/sling/whiteboard/fmeschbe/servlet_resolver/pom.xml Wed Nov 26 13:27:26 2008
@@ -29,7 +29,7 @@
 
     <artifactId>org.apache.sling.servlets.resolver</artifactId>
     <packaging>bundle</packaging>
-    <version>2.0.5-incubator-SNAPSHOT</version>
+    <version>2.0.5-fmeschbe-incubator-SNAPSHOT</version>
 
     <name>Sling - Servlet Resolver</name>
     <description>

Modified: incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/main/java/org/apache/sling/servlets/resolver/helper/ResourceCollector.java
URL: http://svn.apache.org/viewvc/incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/main/java/org/apache/sling/servlets/resolver/helper/ResourceCollector.java?rev=720984&r1=720983&r2=720984&view=diff
==============================================================================
--- incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/main/java/org/apache/sling/servlets/resolver/helper/ResourceCollector.java (original)
+++ incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/main/java/org/apache/sling/servlets/resolver/helper/ResourceCollector.java Wed Nov 26 13:27:26 2008
@@ -25,12 +25,15 @@
 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.api.servlets.HttpConstants;
 import org.apache.sling.servlets.resolver.resource.ServletResourceProviderFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * The <code>ResourceCollector</code> class provides a single public method -
@@ -40,6 +43,18 @@
  */
 public class ResourceCollector {
 
+    /**
+     * The special value returned by
+     * {@link #calculatePrefixMethodWeight(Resource, String, boolean)} if the
+     * resource is not suitable to handle the request according to the location
+     * prefix, request selectors and request extension (value is
+     * <code>Integer.MIN_VALUE</code>).
+     */
+    protected static final int WEIGHT_NO_MATCH = Integer.MIN_VALUE;
+
+    /** default log */
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
     // the request method name used to indicate the script name
     private final String methodName;
 
@@ -47,6 +62,22 @@
     // 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;
+
+    // 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;
+
     /**
      * Creates a <code>ResourceCollector</code> for the given
      * <code>request</code>. If the request is a GET or HEAD request, a
@@ -61,12 +92,7 @@
      *         suitable for handling the <code>request</code>.
      */
     public static ResourceCollector create(SlingHttpServletRequest request) {
-        if (HttpConstants.METHOD_GET.equals(request.getMethod())
-            || HttpConstants.METHOD_HEAD.equals(request.getMethod())) {
-            return new ResourceCollectorGet(request);
-        }
-
-        return new ResourceCollector(request.getMethod(), null);
+        return new ResourceCollector(request);
     }
 
     /**
@@ -84,6 +110,37 @@
     public ResourceCollector(String methodName, String baseResourceType) {
         this.methodName = methodName;
         this.baseResourceType = baseResourceType;
+        this.requestSelectors = new String[0];
+        this.numRequestSelectors = 0;
+        this.extension = null;
+        this.isGet = false;
+        this.isHtml = false;
+    }
+
+    /**
+     * Creates a <code>ResourceCollector</code> finding servlets and scripts
+     * for the given <code>methodName</code>.
+     * 
+     * @param methodName The <code>methodName</code> used to find scripts for.
+     *            This must not be <code>null</code>.
+     * @param baseResourceType The basic resource type to use as a final
+     *            resource super type. If this is <code>null</code> the
+     *            default value
+     *            {@link org.apache.sling.servlets.resolver.ServletResolverConstants#DEFAULT_SERVLET_NAME}
+     *            is assumed.
+     */
+    private ResourceCollector(SlingHttpServletRequest request) {
+        this.methodName = request.getMethod();
+        this.baseResourceType = null;
+
+        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);
     }
 
     public final Collection<Resource> getServlets(Resource resource) {
@@ -92,7 +149,7 @@
 
         ResourceResolver resolver = resource.getResourceResolver();
         Iterator<String> locations = new LocationIterator(resource,
-            getBaseResourceType());
+            baseResourceType);
         while (locations.hasNext()) {
             String location = locations.next();
 
@@ -106,35 +163,82 @@
         return resources;
     }
 
-    /**
-     * Returns all resources inside the <code>location</code> whose base name
-     * equals the {@link #getMethodName()} and which just have a single
-     * extension after the base name. In addition, the special resource at
-     * <code>location.getPath + ".servlet"</code> is checked to find servlets
-     * which are registered with no specific method name.
-     * 
-     * @param resources The collection into which any resources found are added.
-     * @param location The location in the resource tree where the servlets and
-     *            scripts are to be found.
-     */
     protected void getWeightedResources(Set<Resource> resources,
             Resource location) {
 
-        // now list the children and check them
-        Iterator<Resource> children = location.getResourceResolver().listChildren(
-            location);
-        while (children.hasNext()) {
-            Resource child = children.next();
-
-            String name = ResourceUtil.getName(child.getPath());
-            String[] parts = name.split("\\.");
-
-            // require method name plus script extension
-            if (parts.length == 2 && getMethodName().equals(parts[0])) {
-                addWeightedResource(resources, child, 0,
-                    WeightedResource.WEIGHT_NONE);
+        ResourceResolver resolver = location.getResourceResolver();
+        Resource current = location;
+        String parentName = ResourceUtil.getName(current);
+
+        int selIdx = 0;
+        String selector;
+        do {
+            selector = (selIdx < numRequestSelectors)
+                    ? requestSelectors[selIdx]
+                    : null;
+
+            Iterator<Resource> children = resolver.listChildren(current);
+            while (children.hasNext()) {
+                Resource child = children.next();
+
+                String scriptName = ResourceUtil.getName(child);
+                int lastDot = scriptName.lastIndexOf('.');
+                if (lastDot < 0) {
+                    // no extension in the name, this is not a script
+                    continue;
+                }
+
+                scriptName = scriptName.substring(0, lastDot);
+
+                if (isGet) {
+
+                    if (selector != null
+                        && scriptName.equals(selector + "." + extension)) {
+                        addWeightedResource(resources, child, selIdx + 1,
+                            WeightedResource.WEIGHT_EXTENSION);
+                        continue;
+                    }
+
+                    if (scriptName.equals(parentName + "." + extension)) {
+                        addWeightedResource(resources, child, selIdx,
+                            WeightedResource.WEIGHT_EXTENSION
+                                + WeightedResource.WEIGHT_PREFIX);
+                        continue;
+                    }
+
+                    if (scriptName.equals(extension)) {
+                        addWeightedResource(resources, child, selIdx,
+                            WeightedResource.WEIGHT_EXTENSION);
+                        continue;
+                    }
+
+                    if (isHtml) {
+                        if (selector != null && scriptName.equals(selector)) {
+                            addWeightedResource(resources, child, selIdx + 1,
+                                WeightedResource.WEIGHT_NONE);
+                            continue;
+                        }
+                        if (scriptName.equals(parentName)) {
+                            addWeightedResource(resources, child, selIdx,
+                                WeightedResource.WEIGHT_PREFIX);
+                            continue;
+                        }
+                    }
+                }
+
+                if (scriptName.equals(methodName)) {
+                    addWeightedResource(resources, child, selIdx,
+                        WeightedResource.WEIGHT_NONE);
+                    continue;
+                }
             }
-        }
+
+            if (selector != null) {
+                current = resolver.getResource(current, selector);
+                parentName = selector;
+                selIdx++;
+            }
+        } while (selector != null && current != null);
 
         // special treatment for servlets registered with neither a method
         // name nor extensions and selectors
@@ -148,20 +252,6 @@
     }
 
     /**
-     * Returns the basic resource type assigned to this instance
-     */
-    public final String getBaseResourceType() {
-        return baseResourceType;
-    }
-
-    /**
-     * Returns the method name assigned to this instance
-     */
-    public final String getMethodName() {
-        return methodName;
-    }
-
-    /**
      * 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.

Modified: incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/main/java/org/apache/sling/servlets/resolver/helper/WeightedResource.java
URL: http://svn.apache.org/viewvc/incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/main/java/org/apache/sling/servlets/resolver/helper/WeightedResource.java?rev=720984&r1=720983&r2=720984&view=diff
==============================================================================
--- incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/main/java/org/apache/sling/servlets/resolver/helper/WeightedResource.java (original)
+++ incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/main/java/org/apache/sling/servlets/resolver/helper/WeightedResource.java Wed Nov 26 13:27:26 2008
@@ -44,26 +44,27 @@
         Comparable<WeightedResource> {
 
     /**
-     * Weight value assigned to an instance just bearing request method name.
+     * Weight value assigned to an instance just bearing request method name
+     * (value is 0).
      */
     static final int WEIGHT_NONE = 0;
 
     /**
      * Weight value assigned to an instance if the the resource name neither
      * contains the parent resource name as a prefix, nor the request method
-     * name nor the request extension.
+     * name nor the request extension (value is -1).
      */
     static final int WEIGHT_LAST_RESSORT = -1;
 
     /**
      * Weight value added to method/prefix weight if the resource name contains
-     * the the name of the parent resource as its prefix.
+     * the the name of the parent resource as its prefix (value is 1).
      */
     static final int WEIGHT_PREFIX = 1;
 
     /**
      * Weight value added to method/prefix weight if the resource name contains
-     * the request extension.
+     * the request extension (value is 2).
      */
     static final int WEIGHT_EXTENSION = 2;
 

Modified: incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/test/java/org/apache/sling/servlets/resolver/helper/ResourceCollectorGetServletsTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/test/java/org/apache/sling/servlets/resolver/helper/ResourceCollectorGetServletsTest.java?rev=720984&r1=720983&r2=720984&view=diff
==============================================================================
--- incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/test/java/org/apache/sling/servlets/resolver/helper/ResourceCollectorGetServletsTest.java (original)
+++ incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/test/java/org/apache/sling/servlets/resolver/helper/ResourceCollectorGetServletsTest.java Wed Nov 26 13:27:26 2008
@@ -48,9 +48,11 @@
                 "/print/a4.esp", // 5
                 "/print.html.esp", // 6
                 "/print/a4.html.esp", // 7
+                "/print", // resource to enable walking the tree
+                "/print", // resource to enable walking the tree
         };
         
-        int[] baseIdxs = { 0, 1, 1, 0, 0, 1, 0, 1 };
+        int[] baseIdxs = { 0, 1, 1, 0, 0, 1, 0, 1, 0, 1 };
         int[] indices  = { 7, 5, 6, 4, 2, 3, 0, 1 };
         
         effectiveTest(names, baseIdxs, indices);
@@ -65,9 +67,11 @@
                 "/print/other.esp", // 5
                 "/print.html.esp", // 6
                 "/print/a4.html.esp", // 7
+                "/print", // resource to enable walking the tree
+                "/print", // resource to enable walking the tree
         };
         
-        int[] baseIdxs = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
+        int[] baseIdxs = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
         int[] indices = { 7, 6, 3, 2, 0, 1 };
         
         effectiveTest(names, baseIdxs, indices);
@@ -83,9 +87,11 @@
                 "/print.other.esp", // 6
                 "/print.html.esp", // 7
                 "/print/a4.html.esp", // 8
+                "/print", // resource to enable walking the tree
+                "/print", // resource to enable walking the tree
         };
         
-        int[] baseIdxs = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
+        int[] baseIdxs = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
         int[] indices = { 8, 7, 2, 3, 0, 1 };
         
         effectiveTest(names, baseIdxs, indices);
@@ -102,9 +108,11 @@
                 "/print.other.esp", // 7
                 "/print.html.esp", // 8
                 "/print/a4.html.esp", // 9
+                "/print", // resource to enable walking the tree
+                "/print", // resource to enable walking the tree
         };
         
-        int[] baseIdxs = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
+        int[] baseIdxs = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
         int[] indices = { 9, 8, 3, 4, 1, 2, 0 };
         
         effectiveTest(names, baseIdxs, indices);
@@ -122,9 +130,11 @@
                 "/print.other.esp", // 8
                 "/print.html.esp", // 9
                 "/print/a4.html.esp", // 10
+                "/print", // resource to enable walking the tree
+                "/print", // resource to enable walking the tree
         };
         
-        int[] baseIdxs = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 };
+        int[] baseIdxs = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1 };
         int[] indices = { 10, 9, 3, 4, 1, 2, 0 };
         
         effectiveTest(names, baseIdxs, indices);

Modified: incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/test/java/org/apache/sling/servlets/resolver/helper/ScriptSelectionTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/test/java/org/apache/sling/servlets/resolver/helper/ScriptSelectionTest.java?rev=720984&r1=720983&r2=720984&view=diff
==============================================================================
--- incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/test/java/org/apache/sling/servlets/resolver/helper/ScriptSelectionTest.java (original)
+++ incubator/sling/whiteboard/fmeschbe/servlet_resolver/src/test/java/org/apache/sling/servlets/resolver/helper/ScriptSelectionTest.java Wed Nov 26 13:27:26 2008
@@ -23,7 +23,6 @@
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.commons.testing.sling.MockResource;
 import org.apache.sling.commons.testing.sling.MockSlingHttpServletRequest;
-import org.apache.sling.servlets.resolver.helper.ResourceCollector;
 
 /** Various tests that explain and demonstrate how scripts are 
  *  selected. See the assertScript methods for how to interpret
@@ -36,9 +35,15 @@
             "/apps/foo/bar/html.esp",
             "/apps/foo/bar/POST.esp",
             "/apps/foo/bar/print.esp",
+            "/apps/foo/bar/print",
             "/apps/foo/bar/print/POST.esp",
             "/apps/foo/bar/xml.esp",
-            "/apps/foo/bar/print.xml.esp"
+            "/apps/foo/bar/print.xml.esp",
+            "/apps/foo/bar/print/DELETE.esp",
+            "/apps/foo/bar/DELETE.esp",
+            "/apps/foo/bar/SPURIOUS.esp",
+            "/apps/foo/bar/UNKNOWN.esp"
+
     };
     
     /** Given a list of available scripts and the request method, selectors 
@@ -131,6 +136,7 @@
     
     public void testMultipleSelectorsA() {
         final String [] scripts = {
+                "/apps/foo/bar/print",
                 "/apps/foo/bar/print/a4.esp",
                 "/apps/foo/bar/print.a4.esp",
                 "/apps/foo/bar/html.print.a4.esp",
@@ -177,6 +183,7 @@
                 "/apps/foo/bar/print.esp",
                 "/apps/foo/bar/a4.esp",
                 "/apps/foo/bar/bar.a4.esp",
+                "/apps/foo/bar/print",
                 "/apps/foo/bar/print/a4.esp",
                 "/apps/foo/bar/html.esp"
             };
@@ -225,7 +232,17 @@
     }
     
     public void testHtmlPostSelectors() {
-        assertScript("POST", "print.a4", "html", SET_A, "/apps/foo/bar/POST.esp");
+        assertScript("POST", "print.a4", "html", SET_A, "/apps/foo/bar/print/POST.esp");
+        assertScript("POST", "print", "html", SET_A, "/apps/foo/bar/print/POST.esp");
+        assertScript("POST", "a4.print", "html", SET_A, "/apps/foo/bar/POST.esp");
+        assertScript("POST", null, "html", SET_A, "/apps/foo/bar/POST.esp");
+    }
+    
+    public void testHtmlMethodSelectors() {
+        assertScript("DELETE", "print.a4", "html", SET_A, "/apps/foo/bar/print/DELETE.esp");
+        assertScript("SPURIOUS", "print", "html", SET_A, "/apps/foo/bar/SPURIOUS.esp");
+        assertScript("UNKNOWN", "a4.print", "html", SET_A, "/apps/foo/bar/UNKNOWN.esp");
+        assertScript("UNKNOWN", null, "html", SET_A, "/apps/foo/bar/UNKNOWN.esp");
     }
     
     public void testHtmlPostSelectorsAreIgnored() {