incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cziege...@apache.org
Subject svn commit: r765086 - in /incubator/sling/trunk/bundles/servlets/resolver/src: main/java/org/apache/sling/servlets/resolver/internal/ main/java/org/apache/sling/servlets/resolver/internal/resource/ test/java/org/apache/sling/servlets/resolver/internal/...
Date Wed, 15 Apr 2009 08:34:58 GMT
Author: cziegeler
Date: Wed Apr 15 08:34:57 2009
New Revision: 765086

URL: http://svn.apache.org/viewvc?rev=765086&view=rev
Log:
SLING-910 : Add new configuration property "sling.servlet.prefix" for a servlet which specifies
the prefix path for mounting the servlet. This can either be an absolute path or an index
in the search path array of the resource reslver.

Modified:
    incubator/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/ServletResolverConstants.java
    incubator/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
    incubator/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderFactory.java
    incubator/sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/SlingServletResolverTest.java
    incubator/sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderCreateTest.java

Modified: incubator/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/ServletResolverConstants.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/ServletResolverConstants.java?rev=765086&r1=765085&r2=765086&view=diff
==============================================================================
--- incubator/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/ServletResolverConstants.java
(original)
+++ incubator/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/ServletResolverConstants.java
Wed Apr 15 08:34:57 2009
@@ -21,9 +21,9 @@
 public class ServletResolverConstants {
 
     /**
-     * The name of the service registration property of a Servlet registered as
+     * The name of the service registration property of a servlet registered as
      * a service providing the absolute paths under which the servlet is
-     * accessible as a Resource (value is "sling.servlet.paths")
+     * accessible as a resource (value is "sling.servlet.paths")
      * <p>
      * The type of this property is a String or String[] (array of strings)
      * denoting the resource types.
@@ -31,7 +31,7 @@
     public static final String SLING_SERVLET_PATHS = "sling.servlet.paths";
 
     /**
-     * The name of the service registration property of a Servlet registered as
+     * The name of the service registration property of a servlet registered as
      * a service containing the resource type(s) supported by the servlet (value
      * is "sling.servlet.resourceTypes").
      * <p>
@@ -43,6 +43,26 @@
     public static final String SLING_SERVLET_RESOURCE_TYPES = "sling.servlet.resourceTypes";
 
     /**
+     * The name of the service registration property of a servlet registered as
+     * a service providing the prefix/index to be used to register this servlet.
+     * If the value of this property is a number, it defines the index of the search
+     * path entries from the resource resolver. The defined search path is used as
+     * a prefix to mount this servlet. The number can be -1 which always points to the
+     * last search entry. If the specified value is higher than than the highest index
+     * of the search paths, the last entry is used. The index starts with 0.
+     * If the value of this property is a string and parseable as a number, the above
+     * logic is used.
+     * If the value of this property is a string starting with "/", this value is applied
+     * as a prefix, regardless of the configured search paths!
+     * If the value is anything else, it is ignored.
+     * If this property is not specified, it defaults to the default configuration of the
+     * sling servlet resolver.
+     * <p>
+     * The type of this property is either String or a Number.
+     */
+    public static final String SLING_SERVLET_PREFIX = "sling.servlet.prefix";
+
+    /**
      * The name of the service registration property of a Servlet registered as
      * a service containing the request URL selectors supported by the servlet
      * (value is "sling.servlet.selectors"). The selectors must be configured as

Modified: incubator/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java?rev=765086&r1=765085&r2=765086&view=diff
==============================================================================
--- incubator/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
(original)
+++ incubator/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
Wed Apr 15 08:34:57 2009
@@ -52,10 +52,10 @@
 import org.apache.sling.api.scripting.SlingScriptResolver;
 import org.apache.sling.api.servlets.OptingServlet;
 import org.apache.sling.api.servlets.ServletResolver;
-import org.apache.sling.commons.osgi.OsgiUtil;
 import org.apache.sling.engine.RequestUtil;
 import org.apache.sling.engine.servlets.AbstractServiceReferenceConfig;
 import org.apache.sling.engine.servlets.ErrorHandler;
+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.ResourceCollector;
@@ -71,7 +71,7 @@
 
 /**
  * The <code>SlingServletResolver</code> TODO
- * 
+ *
  * @scr.component name="org.apache.sling.servlets.resolver.SlingServletResolver"
  *                label="%servletresolver.name"
  *                description="%servletresolver.description"
@@ -100,6 +100,9 @@
     /** @scr.reference */
     private ServletContext servletContext;
 
+    /** @scr.reference */
+    private JcrResourceResolverFactory resourceResolverFactory;
+
     private Map<ServiceReference, ServiceRegistration> servletsByReference = new HashMap<ServiceReference,
ServiceRegistration>();
 
     private List<ServiceReference> pendingServlets = new ArrayList<ServiceReference>();
@@ -133,7 +136,7 @@
         if(log.isDebugEnabled()) {
         	log.debug("resolveServlet called for Resource {}", request.getResource());
         }
-        
+
         // first check whether the type of a resource is the absolute
         // path of a servlet (or script)
         if (type.charAt(0) == '/') {
@@ -150,7 +153,7 @@
         if (servlet == null) {
             ResourceCollector locationUtil = ResourceCollector.create(request);
             servlet = getServlet(locationUtil, request, resource);
-            
+
             if(log.isDebugEnabled()) {
             	log.debug("getServlet returns Servlet {}", RequestUtil.getServletName(servlet));
             }
@@ -357,7 +360,7 @@
      * because the error occurred before the resource could be set (e.g. during
      * resource resolution) a synthetic resource is returned whose type is
      * {@link ServletResolverConstants#ERROR_HANDLER_PATH}.
-     * 
+     *
      * @param request The request whose resource is to be returned.
      */
     private Resource getErrorResource(SlingHttpServletRequest request) {
@@ -377,7 +380,7 @@
      * actually willing to handle the request in case the servlet is an
      * <code>OptingServlet</code>. The first servlet willing to handle the
      * request is used.
-     * 
+     *
      * @param locationUtil The helper used to find appropriate servlets ordered
      *            by matching priority.
      * @param request The request used to give to any <code>OptingServlet</code>
@@ -394,7 +397,7 @@
     private Servlet getServlet(ResourceCollector locationUtil,
             SlingHttpServletRequest request, Resource resource) {
         Collection<Resource> candidates = locationUtil.getServlets(resource);
-        
+
     	if(log.isDebugEnabled()) {
     		if(candidates.isEmpty()) {
         		log.debug("No Servlet candidates found");
@@ -405,10 +408,10 @@
                 }
     		}
     	}
-    	
+
         for (Resource candidateResource : candidates) {
         	if(log.isDebugEnabled()) {
-        		log.debug("Checking if candidate Resource {} adapts to Servlet and accepts request",

+        		log.debug("Checking if candidate Resource {} adapts to Servlet and accepts request",
         				candidateResource.getPath());
         	}
             Servlet candidate = candidateResource.adaptTo(Servlet.class);
@@ -417,14 +420,13 @@
                     || ((OptingServlet) candidate).accepts(request);
                 if (servletAcceptsRequest) {
                     return candidate;
-                } else {
-                	if(log.isDebugEnabled()) {
-                		log.debug("Candidate {} does not accept request, ignored", candidateResource.getPath());
-                	}
                 }
+            	if(log.isDebugEnabled()) {
+            		log.debug("Candidate {} does not accept request, ignored", candidateResource.getPath());
+            	}
             } else {
                 if(log.isDebugEnabled()) {
-                	log.debug("Candidate {} does not adapt to a Servlet, ignored", candidateResource.getPath());

+                	log.debug("Candidate {} does not adapt to a Servlet, ignored", candidateResource.getPath());
                 }
             }
         }
@@ -508,8 +510,10 @@
 
         // from configuration if available
         Dictionary<?, ?> properties = context.getProperties();
-        String servletRoot = OsgiUtil.toString(
-            properties.get(PROP_SERVLET_ROOT), DEFAULT_SERVLET_ROOT);
+        Object servletRoot = properties.get(PROP_SERVLET_ROOT);
+        if ( servletRoot == null ) {
+            servletRoot = DEFAULT_SERVLET_ROOT;
+        }
 
         Collection<ServiceReference> refs;
         synchronized (this) {
@@ -518,7 +522,7 @@
             pendingServlets = new ArrayList<ServiceReference>();
 
             servletResourceProviderFactory = new ServletResourceProviderFactory(
-                servletRoot);
+                servletRoot, this.resourceResolverFactory.getResourceResolver(null).getSearchPath());
 
             // register servlets immediately from now on
             this.context = context;
@@ -535,7 +539,7 @@
         synchronized (this) {
             refs = new ArrayList<ServiceReference>(servletsByReference.keySet());
         }
-        
+
         // destroy all servlets
         destroyAllServlets(refs);
         this.context = null;
@@ -599,7 +603,7 @@
 
         // assign the servlet to the provider
         provider.setServlet(servlet);
-        
+
         // initialize now
         try {
             servlet.init(new SlingServletConfig(servletContext, reference, name));
@@ -659,4 +663,14 @@
             }
         }
     }
+
+    protected void bindResourceResolverFactory(JcrResourceResolverFactory factory) {
+        this.resourceResolverFactory = factory;
+    }
+
+    protected void unbindResourceResolverFactory(JcrResourceResolverFactory factory) {
+        if ( this.resourceResolverFactory == factory) {
+            this.resourceResolverFactory = null;
+        }
+    }
 }

Modified: incubator/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderFactory.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderFactory.java?rev=765086&r1=765085&r2=765086&view=diff
==============================================================================
--- incubator/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderFactory.java
(original)
+++ incubator/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderFactory.java
Wed Apr 15 08:34:57 2009
@@ -21,6 +21,7 @@
 import static org.apache.sling.servlets.resolver.internal.ServletResolverConstants.SLING_SERVLET_EXTENSIONS;
 import static org.apache.sling.servlets.resolver.internal.ServletResolverConstants.SLING_SERVLET_METHODS;
 import static org.apache.sling.servlets.resolver.internal.ServletResolverConstants.SLING_SERVLET_PATHS;
+import static org.apache.sling.servlets.resolver.internal.ServletResolverConstants.SLING_SERVLET_PREFIX;
 import static org.apache.sling.servlets.resolver.internal.ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES;
 import static org.apache.sling.servlets.resolver.internal.ServletResolverConstants.SLING_SERVLET_SELECTORS;
 
@@ -57,6 +58,16 @@
      */
     private final String servletRoot;
 
+    /**
+     * The index of the search path to be used as servlet root path
+     */
+    private final int servletRootIndex;
+
+    /**
+     * The search paths
+     */
+    private final String[] searchPaths;
+
     static String ensureServletNameExtension(String servletPath) {
         if (servletPath.endsWith(SERVLET_PATH_EXTENSION)) {
             return servletPath;
@@ -65,17 +76,44 @@
         return servletPath.concat(SERVLET_PATH_EXTENSION);
     }
 
-    public ServletResourceProviderFactory(String servletRoot) {
-
-        // ensure the root starts and ends with a slash
-        if (!servletRoot.startsWith("/")) {
-            servletRoot = "/" + servletRoot;
-        }
-        if (!servletRoot.endsWith("/")) {
-            servletRoot += "/";
+    /**
+     * Constructor
+     * @param servletRoot The default value for the servlet root
+     */
+    public ServletResourceProviderFactory(Object servletRoot, String[] paths) {
+        this.searchPaths = paths;
+        String value = servletRoot.toString();
+        // check if servlet root specifies a number
+        boolean isNumber = false;
+        int index = -1;
+        if ( servletRoot instanceof Number ) {
+            isNumber = true;
+            index = ((Number)servletRoot).intValue();
+        } else {
+            if (!value.startsWith("/") ) {
+                try {
+                    index = Integer.valueOf(value);
+                    isNumber = true;
+                } catch (NumberFormatException nfe) {
+                    // ignore
+                }
+            }
         }
+        if ( !isNumber ) {
+            // ensure the root starts and ends with a slash
+            if (!value.startsWith("/")) {
+                value = "/" + value;
+            }
+            if (!value.endsWith("/")) {
+                value += "/";
+            }
 
-        this.servletRoot = servletRoot;
+            this.servletRoot = value;
+            this.servletRootIndex = -1;
+        } else {
+            this.servletRoot = null;
+            this.servletRootIndex = index;
+        }
     }
 
     public ServletResourceProvider create(ServiceReference ref) {
@@ -101,16 +139,65 @@
             log.debug("create({}): Registering servlet for paths {}",
                 getServiceIdentifier(ref), pathSet);
         }
-        
+
         return new ServletResourceProvider(pathSet);
     }
 
+    /**
+     * Get the mount prefix.
+     */
+    private String getPrefix(final ServiceReference ref) {
+        Object value = ref.getProperty(SLING_SERVLET_PREFIX);
+        if ( value == null ) {
+            if ( this.servletRoot != null ) {
+                return this.servletRoot;
+            }
+            value = this.servletRootIndex;
+        }
+        int index = -1;
+        if ( value instanceof Number ) {
+            index = ((Number)value).intValue();
+        } else {
+            String s = value.toString();
+            if ( !s.startsWith("/") ) {
+                boolean isNumber = false;
+                try {
+                    index = Integer.valueOf(s);
+                    isNumber = true;
+                } catch (NumberFormatException nfe) {
+                    // ignore
+                }
+                if ( !isNumber ) {
+                    if (log.isDebugEnabled()) {
+                        log.debug("getPrefix({}): Configuration property is ignored {}",
+                            getServiceIdentifier(ref), value);
+                    }
+                    if ( this.servletRoot != null ) {
+                        return this.servletRoot;
+                    }
+                    index = this.servletRootIndex;
+                }
+            } else {
+                return s;
+            }
+        }
+        if ( index == -1 || index >= this.searchPaths.length ) {
+            index = this.searchPaths.length - 1;
+        }
+        return this.searchPaths[index];
+    }
+
+    /**
+     * Add a servlet by path.
+     * @param pathSet
+     * @param ref
+     */
     private void addByPath(Set<String> pathSet, ServiceReference ref) {
         String[] paths = OsgiUtil.toStringArray(ref.getProperty(SLING_SERVLET_PATHS));
         if (paths != null && paths.length > 0) {
             for (String path : paths) {
                 if (!path.startsWith("/")) {
-                    path = servletRoot.concat(path);
+                    path = getPrefix(ref).concat(path);
                 }
 
                 // add the unmodified path
@@ -122,6 +209,11 @@
         }
     }
 
+    /**
+     * Add a servlet by type
+     * @param pathSet
+     * @param ref
+     */
     private void addByType(Set<String> pathSet, ServiceReference ref) {
         String[] types = OsgiUtil.toStringArray(ref.getProperty(SLING_SERVLET_RESOURCE_TYPES));
         if (types == null || types.length == 0) {
@@ -144,7 +236,7 @@
         // handle the methods property specially (SLING-430)
         String[] methods = OsgiUtil.toStringArray(ref.getProperty(SLING_SERVLET_METHODS));
         if (methods == null || methods.length == 0) {
-            
+
             // SLING-512 only, set default methods if no extensions are declared
             if (extensions == null || extensions.length == 0) {
                 if (log.isInfoEnabled()) {
@@ -154,7 +246,7 @@
                 }
                 methods = DEFAULT_SERVLET_METHODS;
             }
-            
+
         } else if (methods.length == 1 && ALL_METHODS.equals(methods[0])) {
             if (log.isInfoEnabled()) {
                 log.info("addByType({}): Assuming all methods for '*'",
@@ -170,7 +262,7 @@
 
             // make absolute if relative
             if (!type.startsWith("/")) {
-                type = servletRoot + type;
+                type = this.getPrefix(ref) + type;
             }
 
             // ensure trailing slash for full path building

Modified: incubator/sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/SlingServletResolverTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/SlingServletResolverTest.java?rev=765086&r1=765085&r2=765086&view=diff
==============================================================================
--- incubator/sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/SlingServletResolverTest.java
(original)
+++ incubator/sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/SlingServletResolverTest.java
Wed Apr 15 08:34:57 2009
@@ -21,6 +21,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.jcr.Session;
 import javax.servlet.Servlet;
 import javax.servlet.http.HttpServlet;
 
@@ -28,6 +29,7 @@
 
 import org.apache.sling.api.SlingHttpServletRequest;
 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.servlets.OptingServlet;
 import org.apache.sling.commons.testing.osgi.MockBundle;
@@ -37,6 +39,7 @@
 import org.apache.sling.commons.testing.sling.MockResourceResolver;
 import org.apache.sling.commons.testing.sling.MockSlingHttpServletRequest;
 import org.apache.sling.engine.EngineConstants;
+import org.apache.sling.jcr.resource.JcrResourceResolverFactory;
 import org.apache.sling.servlets.resolver.internal.resource.MockServletResource;
 import org.osgi.framework.Constants;
 
@@ -55,8 +58,20 @@
 
     protected void setUp() throws Exception {
         super.setUp();
+        mockResourceResolver = new MockResourceResolver();
+        mockResourceResolver.setSearchPath("/");
+
+        final JcrResourceResolverFactory factory = new JcrResourceResolverFactory() {
+
+            public ResourceResolver getResourceResolver(Session session) {
+                return mockResourceResolver;
+            }
+        };
+
         servlet = new MockSlingRequestHandlerServlet();
         servletResolver = new SlingServletResolver();
+        servletResolver.bindResourceResolverFactory(factory);
+
         MockBundle bundle = new MockBundle(1L);
         MockComponentContext mockComponentContext = new MockComponentContext(
             bundle, SlingServletResolverTest.this.servlet);
@@ -73,8 +88,6 @@
 
         servletResolver.bindServlet(serviceReference);
         servletResolver.activate(mockComponentContext);
-        mockResourceResolver = new MockResourceResolver();
-        mockResourceResolver.setSearchPath("/");
 
         String path = "/"
             + MockSlingHttpServletRequest.RESOURCE_TYPE
@@ -115,7 +128,7 @@
 
     /**
      * This sample servlet will only handle secure requests.
-     * 
+     *
      * @see org.apache.sling.api.servlets.OptingServlet#accepts
      */
     private static class MockSlingRequestHandlerServlet extends HttpServlet

Modified: incubator/sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderCreateTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderCreateTest.java?rev=765086&r1=765085&r2=765086&view=diff
==============================================================================
--- incubator/sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderCreateTest.java
(original)
+++ incubator/sling/trunk/bundles/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderCreateTest.java
Wed Apr 15 08:34:57 2009
@@ -48,7 +48,7 @@
     private static final String RES_TYPE_PATH = JcrResourceUtil.resourceTypeToPath(RES_TYPE);
 
     private ServletResourceProviderFactory factory = new ServletResourceProviderFactory(
-        ROOT);
+        ROOT, new String[] {"/apps/"});
 
     public void testCreateMethodsDefault() {
         MockServiceReference msr = new MockServiceReference(null);



Mime
View raw message