Return-Path: Delivered-To: apmail-sling-commits-archive@www.apache.org Received: (qmail 75294 invoked from network); 26 Nov 2010 10:17:14 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 26 Nov 2010 10:17:14 -0000 Received: (qmail 6039 invoked by uid 500); 26 Nov 2010 10:17:14 -0000 Delivered-To: apmail-sling-commits-archive@sling.apache.org Received: (qmail 5978 invoked by uid 500); 26 Nov 2010 10:17:12 -0000 Mailing-List: contact commits-help@sling.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@sling.apache.org Delivered-To: mailing list commits@sling.apache.org Received: (qmail 5970 invoked by uid 99); 26 Nov 2010 10:17:11 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 26 Nov 2010 10:17:11 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 26 Nov 2010 10:17:10 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id DFF3E23889E3; Fri, 26 Nov 2010 10:15:38 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1039298 - /sling/whiteboard/fmeschbe/milton/src/main/java/org/apache/sling/whiteboard/fmeschbe/miltondav/impl/ Date: Fri, 26 Nov 2010 10:15:38 -0000 To: commits@sling.apache.org From: fmeschbe@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20101126101538.DFF3E23889E3@eris.apache.org> 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 MiltonDavSlingServlet is a servlet based on Milton WebDAV - * registering as a plain servlet to serve requests controlled by the Sling Main - * Servlet. + * The AbstractMiltonDavServlet is an abstract base + * MiltonServlet used as the basis for the two Sling + * implementations: + *
+ *
{@link MiltonDavServlet}
+ *
A servlet registered directly with the OSGi Http Service to serve WebDAV + * requests outside of Sling in its own URL space
+ *
{@link MiltonDavSlingServlet}
+ *
A servlet registered with Sling (using the whiteboard pattern) to provide + * WebDAV services through the Sling request processing infrastructure
+ *
+ *

+ * 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 + * Class.forName(String) 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 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 MiltonDavServlet is the {@link AbstractMiltonDavServlet} + * extension registering with the OSGi Http Service. As such it implements an + * {@link #activate(Map) activator} method as follows: + *

    + *
  • Prepare Servlet configuration for the MiltonServlet setup
  • + *
  • Use a HttpContext implementation implementing the + * handleSecurity method calling the Sling AuthenticationSupport + * service
  • + *
  • Register with the Http Service
  • + *
+ */ @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. + *

+ * 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 config) throws LoginException { + private void activate(Map 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 SlingAuthenticationHandler is the actual + * AuthenticationHandler used by the Sling + * MiltonServlet implementations. This handler accounts for the + * fact that authentication has already been handled when the + * MiltonServlet gains control over the request. + */ public class SlingAuthenticationHandler implements AuthenticationHandler { static final String NAME = "org.apache.sling.whiteboard.fmeschbe.miltondav.impl.SlingAuthenticationHandler"; + /** + * Returns true if the current request has successfully been + * authenticated and the Sling ResourceResolver is available + * for request processing. This is generally the case, so we can assume this + * method will always return true. + */ + public boolean supports(Resource r, Request request) { + return getResourceResolver() != null; + } + + /** + * Returns the Sling ResourceResolver created during Sling + * request authentication. + *

+ * This method will only be called if the + * {@link #supports(Resource, Request)} method of this implementation has + * already been called and returned true in which case the + * result of this method is never null. + */ public Object authenticate(Resource resource, Request request) { return getResourceResolver(); } + /** + * Returns null since authentication has already completed and + * no more processing is to occurr. + */ public String getChallenge(Resource resource, Request request) { return null; } + /** + * Always return true 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 ResourceResolver 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 SlingResponseHandler is basically a + * DefaultWebDavResponseHandler but overwriting the + * {@link #respondCreated(Resource, Response, Request)} method to actually call + * respondNoContent. + */ 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