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 2010/11/26 11:15:38 UTC

svn commit: r1039298 - /sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/

Author: fmeschbe
Date: Fri Nov 26 10:15:38 2010
New Revision: 1039298

URL: http://svn.apache.org/viewvc?rev=1039298&view=rev
Log:
JavaDoc and moving the service method overwrite to the MiltonDavServlet. The MiltonDavSlingServlet does not need to close the ResourceResolver because this is done by the Sling Main Servlet.

Modified:
    sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/AbstractMiltonDavServlet.java
    sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/MiltonDavServlet.java
    sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/MiltonDavSlingServlet.java
    sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/SlingAuthenticationHandler.java
    sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/SlingResponseHandler.java

Modified: sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/AbstractMiltonDavServlet.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/AbstractMiltonDavServlet.java?rev=1039298&r1=1039297&r2=1039298&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/AbstractMiltonDavServlet.java (original)
+++ sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/AbstractMiltonDavServlet.java Fri Nov 26 10:15:38 2010
@@ -18,59 +18,34 @@
  */
 package org.apache.sling.whiteboard.fmeschbe.miltondav.impl;
 
-import java.io.IOException;
-
-import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.auth.core.AuthenticationSupport;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import com.bradmcevoy.http.MiltonServlet;
 
 /**
- * The <code>MiltonDavSlingServlet</code> is a servlet based on Milton WebDAV
- * registering as a plain servlet to serve requests controlled by the Sling Main
- * Servlet.
+ * The <code>AbstractMiltonDavServlet</code> is an abstract base
+ * <code>MiltonServlet</code> used as the basis for the two Sling
+ * implementations:
+ * <dl>
+ * <dt>{@link MiltonDavServlet}</dt>
+ * <dd>A servlet registered directly with the OSGi Http Service to serve WebDAV
+ * requests outside of Sling in its own URL space</dd>
+ * <dt>{@link MiltonDavSlingServlet}</dt>
+ * <dd>A servlet registered with Sling (using the whiteboard pattern) to provide
+ * WebDAV services through the Sling request processing infrastructure</dd>
+ * </dl>
+ * <p>
+ * This base class implementation only overwrites the
+ * {@link #instantiate(String)} method to ensure using the bundle's class loader
+ * and to not create a memory hole. The base class unfortunately uses the static
+ * <code>Class.forName(String)</code> which is well-known for this problem.
  */
 public class AbstractMiltonDavServlet extends MiltonServlet {
 
-    /** default log */
-    private final Logger log = LoggerFactory.getLogger(getClass().getSimpleName());
-
-    @Override
-    public void init(ServletConfig config) throws ServletException {
-        super.init(config);
-    }
-
-    @Override
-    public void service(ServletRequest servletRequest,
-            ServletResponse servletResponse) throws ServletException,
-            IOException {
-        try {
-            if (log.isDebugEnabled()) {
-                log.debug("{} {}", new Object[] {
-                    ((HttpServletRequest) servletRequest).getMethod(),
-                    ((HttpServletRequest) servletRequest).getRequestURI() });
-            }
-            super.service(servletRequest, servletResponse);
-        } finally {
-            Object resolver = servletRequest.getAttribute(AuthenticationSupport.REQUEST_ATTRIBUTE_RESOLVER);
-            if (resolver instanceof ResourceResolver) {
-                ((ResourceResolver) resolver).close();
-            }
-        }
-    }
-
     @SuppressWarnings("unchecked")
     @Override
     protected <T> T instantiate(String className) throws ServletException {
         try {
-            Class c = getClass().getClassLoader().loadClass(className);
+            Class<?> c = getClass().getClassLoader().loadClass(className);
             T rf = (T) c.newInstance();
             return rf;
         } catch (Throwable ex) {

Modified: sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/MiltonDavServlet.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/MiltonDavServlet.java?rev=1039298&r1=1039297&r2=1039298&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/MiltonDavServlet.java (original)
+++ sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/MiltonDavServlet.java Fri Nov 26 10:15:38 2010
@@ -23,18 +23,19 @@ import java.net.URL;
 import java.util.Map;
 
 import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Properties;
 import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.ReferencePolicy;
-import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.auth.core.AuthenticationSupport;
 import org.apache.sling.auth.core.spi.AuthenticationHandler;
 import org.apache.sling.commons.mime.MimeTypeService;
@@ -45,11 +46,35 @@ import org.osgi.service.http.NamespaceEx
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+/**
+ * The <code>MiltonDavServlet</code> is the {@link AbstractMiltonDavServlet}
+ * extension registering with the OSGi Http Service. As such it implements an
+ * {@link #activate(Map) activator} method as follows:
+ * <ul>
+ * <li>Prepare Servlet configuration for the MiltonServlet setup</li>
+ * <li>Use a HttpContext implementation implementing the
+ * <code>handleSecurity</code> method calling the Sling AuthenticationSupport
+ * service</li>
+ * <li>Register with the Http Service</li>
+ * </ul>
+ */
 @Component(metatype = true)
-@Properties( { @Property(name = "prefix", value = "/dav"),
-    @Property(name = "require.auth", boolValue = true) })
 public class MiltonDavServlet extends AbstractMiltonDavServlet {
 
+    // default location at which the service is registered
+    private static final String DEFAULT_PREFIX = "/dav";
+
+    // name of the configuration parameter providing the servlet path
+    @Property(name = "prefix", value = DEFAULT_PREFIX)
+    private static final String PROP_PREFIX = "prefix";
+
+    // whether authentication is required when using this servlet (true)
+    private static final boolean DEFAULT_REQUIRE_AUTH = true;
+
+    // name of the configuration parameter defining wether auth. is required
+    @Property(name = "require.auth", boolValue = DEFAULT_REQUIRE_AUTH)
+    private static final String PROP_REQUIRE_AUTH = "require.auth";
+
     /** default log */
     private final Logger log = LoggerFactory.getLogger(getClass().getSimpleName());
 
@@ -62,26 +87,58 @@ public class MiltonDavServlet extends Ab
     @Reference(policy = ReferencePolicy.DYNAMIC, cardinality = ReferenceCardinality.OPTIONAL_UNARY)
     private MimeTypeService mimeTypeService;
 
+    // the actual prefix under which the servlet is registered, only non-null
+    // if the servlet is actually registered with the Http Service
     private String prefix;
 
+    /**
+     * Overwrites the base class method solely to ensure the resource resolver
+     * is closed when the request terminates.
+     * <p>
+     * This is only required when registering the servlet with the OSGi
+     * HttpService directly.
+     */
+    @Override
+    public void service(ServletRequest servletRequest,
+            ServletResponse servletResponse) throws ServletException,
+            IOException {
+        try {
+            if (log.isDebugEnabled()) {
+                log.debug("{} {}", new Object[] {
+                    ((HttpServletRequest) servletRequest).getMethod(),
+                    ((HttpServletRequest) servletRequest).getRequestURI() });
+            }
+            super.service(servletRequest, servletResponse);
+        } finally {
+            Object resolver = servletRequest.getAttribute(AuthenticationSupport.REQUEST_ATTRIBUTE_RESOLVER);
+            if (resolver instanceof ResourceResolver) {
+                ((ResourceResolver) resolver).close();
+            }
+        }
+    }
+
+    // ---------- SCR integration
+
     @SuppressWarnings("unused")
     @Activate
-    private void activate(Map<String, Object> config) throws LoginException {
+    private void activate(Map<String, Object> config) {
 
-        final Object propRequireAuth = config.get("require.auth");
+        final Object propRequireAuth = config.get(PROP_REQUIRE_AUTH);
         final boolean requireAuth;
         if (propRequireAuth instanceof Boolean) {
             requireAuth = (Boolean) propRequireAuth;
+        } else if (propRequireAuth instanceof String) {
+            requireAuth = Boolean.valueOf((String) propRequireAuth);
         } else {
-            requireAuth = true;
+            requireAuth = DEFAULT_REQUIRE_AUTH;
         }
 
-        final Object propPrefix = config.get("prefix");
+        final Object propPrefix = config.get(PROP_PREFIX);
         final String prefix;
         if (propPrefix instanceof String) {
             prefix = (String) propPrefix;
         } else {
-            prefix = "/milton";
+            prefix = DEFAULT_PREFIX;
         }
         SlingDavResourceFactory.setPrefix(prefix);
 
@@ -103,6 +160,7 @@ public class MiltonDavServlet extends Ab
                 return slingAuthenticator.handleSecurity(request, response);
             }
 
+            // this context provides no resources, always call the servlet
             public URL getResource(String name) {
                 return null;
             }
@@ -117,11 +175,15 @@ public class MiltonDavServlet extends Ab
             osgiHttpService.registerServlet(prefix, this, props, context);
             this.prefix = prefix;
         } catch (NamespaceException ne) {
-            // duplicate alias
+            log.error(
+                "activate: Cannot register Milton based WebDAV servlet at "
+                    + prefix
+                    + "; another servlet is already registered at that path. Please configure a different path for this servlet",
+                ne);
         } catch (ServletException se) {
-            // error during init
-        } catch (RuntimeException e) {
-            // some other problem
+            log.error(
+                "activate: Error while initializing the Milton based WebDAV servlet",
+                se);
         }
     }
 

Modified: sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/MiltonDavSlingServlet.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/MiltonDavSlingServlet.java?rev=1039298&r1=1039297&r2=1039298&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/MiltonDavSlingServlet.java (original)
+++ sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/MiltonDavSlingServlet.java Fri Nov 26 10:15:38 2010
@@ -31,16 +31,20 @@ import org.osgi.framework.Constants;
  * registering as a plain servlet to serve requests controlled by the Sling Main
  * Servlet.
  */
-@Component(metatype = true)
+@Component(metatype = false)
 @Service(value = Servlet.class)
-@Properties( {
+@Properties({
     @Property(name = Constants.SERVICE_DESCRIPTION, value = "Sling WebDAV Servlet"),
     @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation"),
+
+    // registering with Sling (default resource type, handling all methods)
     @Property(name = "sling.servlet.resourceTypes", value = "sling/servlet/default", propertyPrivate = true),
     @Property(name = "sling.servlet.methods", value = "*", propertyPrivate = true),
-    @Property(name = "resource.factory.class", value = SlingResourceFactory.NAME),
-    @Property(name = "authentication.handler.classes", value = SlingAuthenticationHandler.NAME),
-    @Property(name = "response.handler.class", value = SlingResponseHandler.NAME) })
+
+    // setup the helper classes for the MiltonServlet
+    @Property(name = "resource.factory.class", value = SlingResourceFactory.NAME, propertyPrivate = true),
+    @Property(name = "authentication.handler.classes", value = SlingAuthenticationHandler.NAME, propertyPrivate = true),
+    @Property(name = "response.handler.class", value = SlingResponseHandler.NAME, propertyPrivate = true) })
 public class MiltonDavSlingServlet extends AbstractMiltonDavServlet {
 
 }
\ No newline at end of file

Modified: sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/SlingAuthenticationHandler.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/SlingAuthenticationHandler.java?rev=1039298&r1=1039297&r2=1039298&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/SlingAuthenticationHandler.java (original)
+++ sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/SlingAuthenticationHandler.java Fri Nov 26 10:15:38 2010
@@ -25,26 +25,60 @@ import com.bradmcevoy.http.MiltonServlet
 import com.bradmcevoy.http.Request;
 import com.bradmcevoy.http.Resource;
 
+/**
+ * The <code>SlingAuthenticationHandler</code> is the actual
+ * <code>AuthenticationHandler</code> used by the Sling
+ * <code>MiltonServlet</code> implementations. This handler accounts for the
+ * fact that authentication has already been handled when the
+ * <code>MiltonServlet</code> gains control over the request.
+ */
 public class SlingAuthenticationHandler implements AuthenticationHandler {
 
     static final String NAME = "org.apache.sling.whiteboard.fmeschbe.miltondav.impl.SlingAuthenticationHandler";
 
+    /**
+     * Returns <code>true</code> if the current request has successfully been
+     * authenticated and the Sling <code>ResourceResolver</code> is available
+     * for request processing. This is generally the case, so we can assume this
+     * method will always return <code>true</code>.
+     */
+    public boolean supports(Resource r, Request request) {
+        return getResourceResolver() != null;
+    }
+
+    /**
+     * Returns the Sling <code>ResourceResolver</code> created during Sling
+     * request authentication.
+     * <p>
+     * This method will only be called if the
+     * {@link #supports(Resource, Request)} method of this implementation has
+     * already been called and returned <code>true</code> in which case the
+     * result of this method is never <code>null</code>.
+     */
     public Object authenticate(Resource resource, Request request) {
         return getResourceResolver();
     }
 
+    /**
+     * Returns <code>null</code> since authentication has already completed and
+     * no more processing is to occurr.
+     */
     public String getChallenge(Resource resource, Request request) {
         return null;
     }
 
+    /**
+     * Always return <code>true</code> since a resource only exists after
+     * successfull authentication by the Sling authentication infrastructure.
+     */
     public boolean isCompatible(Resource resource) {
         return true;
     }
 
-    public boolean supports(Resource r, Request request) {
-        return getResourceResolver() != null;
-    }
-
+    /**
+     * Returns the Sling <code>ResourceResolver</code> from the request
+     * attribute.
+     */
     private Object getResourceResolver() {
         return MiltonServlet.request().getAttribute(
             AuthenticationSupport.REQUEST_ATTRIBUTE_RESOLVER);

Modified: sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/SlingResponseHandler.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/SlingResponseHandler.java?rev=1039298&r1=1039297&r2=1039298&view=diff
==============================================================================
--- sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/SlingResponseHandler.java (original)
+++ sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/SlingResponseHandler.java Fri Nov 26 10:15:38 2010
@@ -28,6 +28,12 @@ import com.bradmcevoy.http.webdav.Defaul
 import com.bradmcevoy.http.webdav.PropFindXmlGenerator;
 import com.bradmcevoy.http.webdav.ResourceTypeHelper;
 
+/**
+ * The <code>SlingResponseHandler</code> is basically a
+ * <code>DefaultWebDavResponseHandler</code> but overwriting the
+ * {@link #respondCreated(Resource, Response, Request)} method to actually call
+ * <code>respondNoContent</code>.
+ */
 public class SlingResponseHandler extends DefaultWebDavResponseHandler {
 
     static final String NAME = "org.apache.sling.whiteboard.fmeschbe.miltondav.impl.SlingResponseHandler";
@@ -38,33 +44,28 @@ public class SlingResponseHandler extend
 
     public SlingResponseHandler(AuthenticationService authenticationService) {
         super(authenticationService);
-        // TODO Auto-generated constructor stub
     }
 
     public SlingResponseHandler(AuthenticationService authenticationService,
             ResourceTypeHelper resourceTypeHelper) {
         super(authenticationService, resourceTypeHelper);
-        // TODO Auto-generated constructor stub
     }
 
     public SlingResponseHandler(ValueWriters valueWriters,
             AuthenticationService authenticationService) {
         super(valueWriters, authenticationService);
-        // TODO Auto-generated constructor stub
     }
 
     public SlingResponseHandler(ValueWriters valueWriters,
             AuthenticationService authenticationService,
             ResourceTypeHelper resourceTypeHelper) {
         super(valueWriters, authenticationService, resourceTypeHelper);
-        // TODO Auto-generated constructor stub
     }
 
     public SlingResponseHandler(Http11ResponseHandler wrapped,
             ResourceTypeHelper resourceTypeHelper,
             PropFindXmlGenerator propFindXmlGenerator) {
         super(wrapped, resourceTypeHelper, propFindXmlGenerator);
-        // TODO Auto-generated constructor stub
     }
 
     @Override