Author: fmeschbe
Date: Mon Jan 14 11:26:32 2008
New Revision: 611901

URL: http://svn.apache.org/viewvc?rev=611901&view=rev
Log:
Add ServletResource and its resource provider and adapt Servlet registration

Added:
    
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/resource/
    
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/resource/ServletResource.java
    
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/resource/ServletResourceProvider.java
Modified:
    
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/ServletResolverConstants.java
    
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/SlingServletResolver.java

Modified: 
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/ServletResolverConstants.java
URL: 
http://svn.apache.org/viewvc/incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/ServletResolverConstants.java?rev=611901&r1=611900&r2=611901&view=diff
==============================================================================
--- 
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/ServletResolverConstants.java
 (original)
+++ 
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/ServletResolverConstants.java
 Mon Jan 14 11:26:32 2008
@@ -22,21 +22,61 @@
 
     /**
      * 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")
+     * <p>
+     * The type of this property is a String or String[] (array of strings)
+     * denoting the resource types.
+     */
+    public static final String SLING_SERVLET_PATHS = "sling.servlet.paths";
+
+    /**
+     * 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.core.resourceTypes"). The type of this property is a String or
-     * String[] (array of strings) denoting the resource types. If this 
property
-     * is missing or empty the Servlet is ignored.
+     * is "sling.servlet.resourceTypes").
+     * <p>
+     * The type of this property is a String or String[] (array of strings)
+     * denoting the resource types. This property is ignored if the
+     * [EMAIL PROTECTED] #SLING_SERVLET_PATHS} property is set. Otherwise this 
property
+     * must be set or the servlet is ignored.
+     */
+    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 containing the request URL extensions supported by the servlet
+     * for GET requests (value is "sling.servlet.extensions").
+     * <p>
+     * The type of this property is a String or String[] (array of strings)
+     * denoting the resource types. This property is ignored if the
+     * [EMAIL PROTECTED] #SLING_SERVLET_PATHS} property is set. Otherwise this 
property or
+     * the [EMAIL PROTECTED] #SLING_SERVLET_METHODS} must be set or the 
servlet is ignored.
      */
-    public static final String SLING_RESOURCE_TYPES = 
"sling.core.resourceTypes";
+    public static final String SLING_SERVLET_EXTENSIONS = 
"sling.servlet.extensions";
+
+    /**
+     * The name of the service registration property of a Servlet registered as
+     * a service containing the request methods supported by the servlet (value
+     * is "sling.servlet.methods").
+     * <p>
+     * The type of this property is a String or String[] (array of strings)
+     * denoting the resource types. This property is ignored if the
+     * [EMAIL PROTECTED] #SLING_SERVLET_PATHS} property is set. Otherwise this 
property or
+     * the [EMAIL PROTECTED] #SLING_SERVLET_EXTENSIONS} must be set or the 
servlet is
+     * ignored.
+     */
+    public static final String SLING_SERVLET_METHODS = "sling.servlet.methods";
 
     /**
      * The name of the registered servlet used as the default servlet if no
      * other servlet or script could be selected (value is
      * "sling.core.servlet.default"). If no servlet is registered under this
-     * name, the [EMAIL PROTECTED] 
org.apache.sling.servlet.resolver.defaults.DefaultServlet} is used.
+     * name, the
+     * [EMAIL PROTECTED] 
org.apache.sling.servlet.resolver.defaults.DefaultServlet} is
+     * used.
      */
     public static final String DEFAULT_SERVLET_NAME = "sling/servlet/default";
-    
+
     public static final String ERROR_HANDLER_PATH = 
"sling/servlet/errorhandler";
 
 }

Modified: 
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/SlingServletResolver.java
URL: 
http://svn.apache.org/viewvc/incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/SlingServletResolver.java?rev=611901&r1=611900&r2=611901&view=diff
==============================================================================
--- 
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/SlingServletResolver.java
 (original)
+++ 
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/SlingServletResolver.java
 Mon Jan 14 11:26:32 2008
@@ -23,13 +23,13 @@
 import static org.apache.sling.api.SlingConstants.ERROR_STATUS;
 import static org.apache.sling.core.CoreConstants.SLING_CURRENT_SERVLET_NAME;
 import static 
org.apache.sling.servlet.resolver.ServletResolverConstants.DEFAULT_SERVLET_NAME;
-import static 
org.apache.sling.servlet.resolver.ServletResolverConstants.SLING_RESOURCE_TYPES;
 
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Dictionary;
 import java.util.HashMap;
+import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -45,6 +45,7 @@
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceProvider;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.scripting.SlingScript;
 import org.apache.sling.api.scripting.SlingScriptResolver;
@@ -56,8 +57,9 @@
 import org.apache.sling.servlet.resolver.defaults.DefaultServlet;
 import org.apache.sling.servlet.resolver.helper.PathSupport;
 import org.apache.sling.servlet.resolver.helper.SlingServletConfig;
-import org.osgi.framework.Constants;
+import org.apache.sling.servlet.resolver.resource.ServletResourceProvider;
 import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -86,6 +88,13 @@
      *               description="%resolver.path.description"
      */
     public static final String PROP_PATH = "path";
+    
+    /**
+     * @scr.property value="/apps"
+     *               label="%resolver.servletRoot.name"
+     *               description="%resolver.servletRoot.description"
+     */
+    public static final String PROP_SERVLET_ROOT = "servletRoot";
 
     private static final String REF_SERVLET = "Servlet";
 
@@ -94,13 +103,15 @@
 
     private Map<String, Servlet> servlets = new HashMap<String, Servlet>();
 
-    private Map<ServiceReference, Servlet> servletsByReference = new 
HashMap<ServiceReference, Servlet>();
+    private Map<ServiceReference, ServiceRegistration> servletsByReference = 
new HashMap<ServiceReference, ServiceRegistration>();
 
     private List<ServiceReference> pendingServlets = new 
ArrayList<ServiceReference>();
 
     private ComponentContext context;
 
     private String[] path;
+    
+    private String servletRoot;
 
     private Servlet coreDefaultServlet;
 
@@ -154,18 +165,18 @@
     }
 
     // ---------- ScriptResolver interface ------------------------------------
-    
+
     public SlingScript findScript(ResourceResolver resourceResolver, String 
name)
             throws SlingException {
-        
+
         if (name.startsWith("/")) {
             Resource resource = resourceResolver.getResource(name);
             return (resource != null)
                     ? resource.adaptTo(SlingScript.class)
                     : null;
         }
-        
-        for (int i=0; i < path.length; i++) {
+
+        for (int i = 0; i < path.length; i++) {
             String scriptPath = path[i] + name;
             Resource resource = resourceResolver.getResource(scriptPath);
             if (resource != null) {
@@ -177,11 +188,11 @@
                 }
             }
         }
-        
+
         log.info("findScript: No script {} found in path", name);
         return null;
     }
-    
+
     // ---------- ErrorHandler interface --------------------------------------
 
     public void handleError(int status, String message,
@@ -397,6 +408,14 @@
             path = new String[] { "/" };
         }
 
+        String tmpRoot = OsgiUtil.toString(properties.get(PROP_SERVLET_ROOT), 
null);
+        if (tmpRoot == null) {
+            tmpRoot = path[0];
+        } else if (!tmpRoot.startsWith("/")) {
+            tmpRoot = "/" + tmpRoot;
+        }
+        servletRoot = tmpRoot;
+        
         Collection<ServiceReference> refs;
         synchronized (this) {
 
@@ -447,15 +466,7 @@
 
     private boolean createServlet(ServletContext servletContext,
             ServiceReference reference) {
-        Object typeObject = reference.getProperty(SLING_RESOURCE_TYPES);
-        if (typeObject == null) {
-            log.info(
-                "bindServlet: Ignoring Servlet service {} without resource 
types",
-                reference.getProperty(Constants.SERVICE_ID));
-            return false;
-        }
 
-        // super:addingService
         String name = AbstractServiceReferenceConfig.getName(reference);
         if (name == null) {
             log.error(
@@ -473,6 +484,15 @@
             return false;
         }
 
+        ServletResourceProvider provider = ServletResourceProvider.create(
+            reference, servlet, servletRoot);
+        if (provider == null) {
+            log.error(
+                "createServlet: Cannot register servlet {} without path or 
resource type configuration",
+                name);
+            return false;
+        }
+
         try {
             servlet.init(new SlingServletConfig(servletContext, reference, 
name));
             log.debug("bindServlet: Servlet {} added", name);
@@ -486,19 +506,13 @@
             return false;
         }
 
-        if (typeObject instanceof String[]) {
-            String[] types = (String[]) typeObject;
-            for (String type : types) {
-                log.debug("bindServlet: Servlet {} handles type {}", name, 
type);
-                putServlet(type, servlet);
-            }
-        } else {
-            log.debug("bindServlet: Servlet {} handles type {}", name,
-                typeObject);
-            putServlet(typeObject.toString(), servlet);
-        }
+        Dictionary<String, Object> params = new Hashtable<String, Object>();
+        params.put(ResourceProvider.ROOTS, provider.getSerlvetPaths());
+
+        ServiceRegistration reg = context.getBundleContext().registerService(
+            ResourceProvider.SERVICE_NAME, servlet, params);
 
-        servletsByReference.put(reference, servlet);
+        servletsByReference.put(reference, reg);
 
         return true;
     }
@@ -510,25 +524,16 @@
     }
 
     private void destroyServlet(ServiceReference reference) {
-        Servlet servlet = servletsByReference.remove(reference);
-        if (servlet != null) {
+        ServiceRegistration registration = 
servletsByReference.remove(reference);
+        if (registration != null) {
+
+            registration.unregister();
+            
+            Servlet servlet = (Servlet) context.locateService(REF_SERVLET,
+                reference);
             String name = servlet.getServletConfig().getServletName();
             log.debug("unbindServlet: Servlet {} removed", name);
 
-            Object typeObject = reference.getProperty(SLING_RESOURCE_TYPES);
-            if (typeObject instanceof String[]) {
-                String[] types = (String[]) typeObject;
-                for (String type : types) {
-                    log.debug("unbindServlet: Servlet {} unregistered for  {}",
-                        name, type);
-                    removeServlet(type);
-                }
-            } else {
-                log.debug("unbindServlet: Servlet {} unregistered for {}",
-                    name, typeObject);
-                removeServlet((String) typeObject);
-            }
-
             try {
                 servlet.destroy();
             } catch (Throwable t) {
@@ -537,18 +542,6 @@
                         + name, t);
             }
         }
-    }
-
-    private void putServlet(String resourceType, Servlet servlet) {
-        servlets.put(resourceType, servlet);
-    }
-
-    private Servlet getServlet(String resourceType) {
-        return servlets.get(resourceType);
-    }
-
-    private void removeServlet(String resourceType) {
-        servlets.remove(resourceType);
     }
 
 }

Added: 
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/resource/ServletResource.java
URL: 
http://svn.apache.org/viewvc/incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/resource/ServletResource.java?rev=611901&view=auto
==============================================================================
--- 
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/resource/ServletResource.java
 (added)
+++ 
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/resource/ServletResource.java
 Mon Jan 14 11:26:32 2008
@@ -0,0 +1,74 @@
+/*
+ * 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.servlet.resolver.resource;
+
+import javax.servlet.Servlet;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceMetadata;
+import org.apache.sling.api.resource.ResourceProvider;
+import org.apache.sling.osgi.commons.SlingAdaptable;
+
+public class ServletResource extends SlingAdaptable implements Resource {
+
+    private final ResourceProvider resourceProvider;
+
+    private final Servlet servlet;
+
+    private final String path;
+
+    private final ResourceMetadata metadata;
+
+    public ServletResource(ResourceProvider resourceProvider, Servlet servlet,
+            String path) {
+        this.resourceProvider = resourceProvider;
+        this.servlet = servlet;
+        this.path = path;
+
+        this.metadata = new ResourceMetadata();
+        metadata.put(ResourceMetadata.RESOLUTION_PATH, path);
+    }
+
+    public ResourceMetadata getResourceMetadata() {
+        return metadata;
+    }
+
+    public ResourceProvider getResourceProvider() {
+        return resourceProvider;
+    }
+
+    public String getResourceType() {
+        // the resource type of a servlet is the servlet's path
+        return path;
+    }
+
+    public String getURI() {
+        return path;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
+        if (type == Servlet.class) {
+            return (AdapterType) servlet; // unchecked cast
+        }
+
+        return super.adaptTo(type);
+    }
+
+}

Added: 
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/resource/ServletResourceProvider.java
URL: 
http://svn.apache.org/viewvc/incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/resource/ServletResourceProvider.java?rev=611901&view=auto
==============================================================================
--- 
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/resource/ServletResourceProvider.java
 (added)
+++ 
incubator/sling/whiteboard/fmeschbe/resource/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/resource/ServletResourceProvider.java
 Mon Jan 14 11:26:32 2008
@@ -0,0 +1,120 @@
+/*
+ * 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.servlet.resolver.resource;
+
+import static 
org.apache.sling.servlet.resolver.ServletResolverConstants.SLING_SERVLET_EXTENSIONS;
+import static 
org.apache.sling.servlet.resolver.ServletResolverConstants.SLING_SERVLET_METHODS;
+import static 
org.apache.sling.servlet.resolver.ServletResolverConstants.SLING_SERVLET_PATHS;
+import static 
org.apache.sling.servlet.resolver.ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.Servlet;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceProvider;
+import org.apache.sling.osgi.commons.OsgiUtil;
+import org.osgi.framework.ServiceReference;
+
+public class ServletResourceProvider implements ResourceProvider {
+
+    private Map<String, ServletResource> servletMap;
+
+    public static ServletResourceProvider create(ServiceReference ref,
+            Servlet servlet, String servletRoot) {
+
+        // check whether explicit paths are set
+        String[] paths = 
OsgiUtil.toStringArray(ref.getProperty(SLING_SERVLET_PATHS));
+        if (paths != null && paths.length > 0) {
+            return new ServletResourceProvider(paths, servlet);
+        }
+
+        // now, we fall back to resource types, extensions and methods
+        String[] types = 
OsgiUtil.toStringArray(ref.getProperty(SLING_SERVLET_RESOURCE_TYPES));
+        if (types == null || types.length == 0) {
+            // TODO: should log, why we ignore this servlet
+            return null;
+        }
+
+        // we have types and expect extensions and/or methods
+        String[] extensions = 
OsgiUtil.toStringArray(ref.getProperty(SLING_SERVLET_EXTENSIONS));
+        String[] methods = 
OsgiUtil.toStringArray(ref.getProperty(SLING_SERVLET_METHODS));
+        if ((extensions == null || extensions.length == 0)
+            && (methods == null || methods.length == 0)) {
+            // TODO: should log, why we ignore this servlet
+            return null;
+        }
+
+        List<String> pathList = new ArrayList<String>();
+        for (String type : types) {
+            if (!type.startsWith("/")) {
+                type = servletRoot + type;
+            }
+            if (!type.endsWith("/")) {
+                type += "/";
+            }
+
+            if (extensions != null) {
+                for (String ext : extensions) {
+                    pathList.add(type + ext);
+                }
+            }
+
+            if (methods != null) {
+                for (String method : methods) {
+                    pathList.add(type + method);
+                }
+            }
+        }
+
+        paths = pathList.toArray(new String[pathList.size()]);
+        return new ServletResourceProvider(paths, servlet);
+    }
+
+    private ServletResourceProvider(String[] paths, Servlet servlet) {
+        servletMap = new HashMap<String, ServletResource>();
+        for (String path : paths) {
+            ServletResource res = new ServletResource(this, servlet, path);
+            servletMap.put(path, res);
+        }
+    }
+
+    public Resource getResource(HttpServletRequest request, String path) {
+        return getResource(path);
+    }
+
+    public Resource getResource(String path) {
+        return servletMap.get(path);
+    }
+
+    public Iterator<Resource> listChildren(Resource parent) {
+        // the resource provider only has exact paths no children
+        return null;
+    }
+
+    public String[] getSerlvetPaths() {
+        return servletMap.keySet().toArray(
+            new String[servletMap.keySet().size()]);
+    }
+}


Reply via email to