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/09/07 10:45:37 UTC

svn commit: r993280 [1/2] - in /sling/trunk/bundles/engine: ./ src/main/java/org/apache/sling/engine/ src/main/java/org/apache/sling/engine/impl/ src/main/java/org/apache/sling/engine/impl/filter/ src/main/java/org/apache/sling/engine/impl/request/

Author: fmeschbe
Date: Tue Sep  7 08:45:36 2010
New Revision: 993280

URL: http://svn.apache.org/viewvc?rev=993280&view=rev
Log:
SLING-1603 Refactor SlingMainServlet and provide SlingRequestProcessor API; increase o.a.s.engine export version to 2.1 (new API provided)
SLING-1213 Provide Servlet API 2.4 filter scopes

Added:
    sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/SlingRequestProcessor.java   (with props)
    sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/DefaultErrorHandler.java   (with props)
    sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpContext.java   (with props)
    sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java   (with props)
    sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/filter/ServletFilterManager.java   (with props)
Modified:
    sling/trunk/bundles/engine/pom.xml
    sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/EngineConstants.java
    sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpServletRequestImpl.java
    sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpServletResponseImpl.java
    sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingMainServlet.java
    sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/WebConsoleConfigPrinter.java
    sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/filter/RequestSlingFilterChain.java
    sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/filter/SlingFilterChainHelper.java
    sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java
    sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/SlingRequestDispatcher.java

Modified: sling/trunk/bundles/engine/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/engine/pom.xml?rev=993280&r1=993279&r2=993280&view=diff
==============================================================================
--- sling/trunk/bundles/engine/pom.xml (original)
+++ sling/trunk/bundles/engine/pom.xml Tue Sep  7 08:45:36 2010
@@ -60,7 +60,7 @@
                 <configuration>
                     <instructions>
                         <Export-Package>
-                            org.apache.sling.engine;version=2.0.6,
+                            org.apache.sling.engine;version=2.1,
                             org.apache.sling.engine.servlets;version=2.0.6
                         </Export-Package>
                         <Private-Package>
@@ -167,5 +167,11 @@
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr.annotations</artifactId>
+            <version>1.3.0</version>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
 </project>

Modified: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/EngineConstants.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/EngineConstants.java?rev=993280&r1=993279&r2=993280&view=diff
==============================================================================
--- sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/EngineConstants.java (original)
+++ sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/EngineConstants.java Tue Sep  7 08:45:36 2010
@@ -19,14 +19,11 @@
 package org.apache.sling.engine;
 
 /**
- * The <code>CoreConstants</code> interface provides some symbolic constants
- * for well known constant strings in Sling. Even though these constants will
- * never change, it is recommended that applications refer to the symbolic
- * constants instead of code the strings themselves.
- *
- * @deprecated All constants have alternatives to use
+ * The <code>CoreConstants</code> interface provides some symbolic constants for
+ * well known constant strings in Sling. Even though these constants will never
+ * change, it is recommended that applications refer to the symbolic constants
+ * instead of code the strings themselves.
  */
-@Deprecated
 public class EngineConstants {
 
     /**
@@ -39,7 +36,8 @@ public class EngineConstants {
      * <code>BundleContext.getProperty(String)</code> method.
      *
      * @see #SLING_HOME_URL
-     * @deprecated Use {@link org.apache.sling.settings.SlingSettingsService#SLING_HOME}
+     * @deprecated Use
+     *             {@link org.apache.sling.settings.SlingSettingsService#SLING_HOME}
      */
     @Deprecated
     public static final String SLING_HOME = "sling.home";
@@ -49,14 +47,15 @@ public class EngineConstants {
      * an URL (value is "sling.home.url").
      * <p>
      * The value of this property is assigned the value of
-     * <code>new File(${sling.home}).toURI().toString()</code> before
-     * resolving the property variables.
+     * <code>new File(${sling.home}).toURI().toString()</code> before resolving
+     * the property variables.
      * <p>
      * This property is available calling the
      * <code>BundleContext.getProperty(String)</code> method.
      *
      * @see #SLING_HOME
-     * @deprecated Use {@link org.apache.sling.settings.SlingSettingsService#SLING_HOME_URL}
+     * @deprecated Use
+     *             {@link org.apache.sling.settings.SlingSettingsService#SLING_HOME_URL}
      */
     @Deprecated
     public static final String SLING_HOME_URL = "sling.home.url";
@@ -65,9 +64,11 @@ public class EngineConstants {
      * The name of the request attribute providing the name of the currently
      * executing servlet (value is "sling.core.current.servletName"). This
      * attribute is set immediately before calling the
-     * <code>Servlet.service()</code> method and reset to any previously
-     * stored value after the service method returns.
-     * @deprecated Use {@link org.apache.sling.api.SlingConstants#SLING_CURRENT_SERVLET_NAME}
+     * <code>Servlet.service()</code> method and reset to any previously stored
+     * value after the service method returns.
+     *
+     * @deprecated Use
+     *             {@link org.apache.sling.api.SlingConstants#SLING_CURRENT_SERVLET_NAME}
      */
     @Deprecated
     public static final String SLING_CURRENT_SERVLET_NAME = "sling.core.current.servletName";
@@ -76,9 +77,9 @@ public class EngineConstants {
      * The name of the service registration property of a Servlet registered as
      * a service containing the name of the servlet (value is
      * "sling.core.servletName"). If this property is missing or empty, the
-     * <code>component.name</code> property or the <code>service.pid</code>
-     * is used. If none of the three properties is defined, the Servlet is
-     * ignored.
+     * <code>component.name</code> property or the <code>service.pid</code> is
+     * used. If none of the three properties is defined, the Servlet is ignored.
+     *
      * @deprecated
      */
     @Deprecated
@@ -86,18 +87,141 @@ public class EngineConstants {
 
     /**
      * The <code>javax.jcr.Session</code> request attribute used to be set by
-     * the <i>SlingAuthenticator</i> upon successfull authentication. With
-     * the implementation of a separate Commons Authentication bundle, this
-     * request attribute is not supported any longer (though it may currently
-     * still be provided for backwards compatibility).
-     * <p>
-     * Applications using this request attribute have to be modified to call
-     * the <code>SlingHttpServletRequest.getResourceResolver()</code> method
-     * to get the request's resource resolver.
+     * the <i>SlingAuthenticator</i> upon successfull authentication. with the
+     * release of the Authentication Core 1.0.0 bundle, this request attribute
+     * is not set any more.
+     * <p>
+     * Applications requiring access to the JCR Session must be modified to get
+     * the Resource Resolver from the Sling request (
+     * <code>SlingHttpServletRequest.getResourceResolver()</code>) and adapt it
+     * to the JCR Session.
      *
      * @deprecated as of bundle version 2.1
      */
     @Deprecated
     public static final String SESSION = "javax.jcr.Session";
 
+    /**
+     * The name of the service to be used for registering filters with the
+     * {@link SlingRequestProcessor}.
+     *
+     * @since 2.1, Sling Engine 2.2
+     */
+    public static final String FILTER_NAME = "javax.servlet.Filter";
+
+    /**
+     * The name of the service registration property of a
+     * <code>java.servlet.Filter</code> service to be used as a filter by the
+     * {@link SlingRequestProcessor}.
+     * <p>
+     * The specification of the <code>filter.scope</code> service registration
+     * property is required for a <code>javax.servlet.Filter</code> service to
+     * be used as a filter by the Sling Engine.
+     * <p>
+     * The <code>filter.scope</code> registration property is expected to be a
+     * scalar String, an array of Strings or a Vector of Strings. Case of the
+     * value is ignored.
+     *
+     * @see #FILTER_SCOPE_COMPONENT
+     * @see #FILTER_SCOPE_ERROR
+     * @see #FILTER_SCOPE_FORWARD
+     * @see #FILTER_SCOPE_INCLUDE
+     * @see #FILTER_SCOPE_REQUEST
+     * @since 2.1, Sling Engine 2.2
+     */
+    public static final String FILTER_SCOPE = "filter.scope";
+
+    /**
+     * Filter scope value identifying a component level filter.
+     * <p>
+     * Component level filters are called once at the beginning of each request
+     * (after the {@link #FILTER_SCOPE_REQUEST} filters) and for each resource
+     * being included or forwarded. The order of calling the filters is defined
+     * by the <code>service.ranking</code> (or {@link #FILTER_ORDER}) property
+     * and the service registration ID.
+     *
+     * @see #FILTER_SCOPE
+     * @since 2.1, Sling Engine 2.2
+     */
+    public static final String FILTER_SCOPE_COMPONENT = "COMPONENT";
+
+    /**
+     * Filter scope value identifying an error level filter.
+     * <p>
+     * Error level filters are called before calling the
+     * {@link org.apache.sling.engine.servlets.ErrorHandler} due to either a
+     * <code>HttpServletResponse.sendError</code> call or due to an uncaught
+     * <code>Throwable</code>. The order of calling the filters is defined by
+     * the <code>service.ranking</code> (or {@link #FILTER_ORDER}) property and
+     * the service registration ID.
+     *
+     * @see #FILTER_SCOPE
+     * @since 2.1, Sling Engine 2.2
+     */
+    public static final String FILTER_SCOPE_ERROR = "ERROR";
+
+    /**
+     * Filter scope value identifying an include level filter.
+     * <p>
+     * Include level filters are called before the script handling an included
+     * resource is called. A resource is considered included if it rendered as a
+     * result of calling <code>RequestDispatcher.include</code>. This may also
+     * be induced by any JSP tags causing the
+     * <code>RequestDispatcher.include</code> method being called, e.g.
+     * <code>&lt;sling:include&gt;</code>. The order of calling the filters is
+     * defined by the <code>service.ranking</code> (or {@link #FILTER_ORDER})
+     * property and the service registration ID.
+     *
+     * @see #FILTER_SCOPE
+     * @since 2.1, Sling Engine 2.2
+     */
+    public static final String FILTER_SCOPE_INCLUDE = "INCLUDE";
+
+    /**
+     * Filter scope value identifying a forward level filter.
+     * <p>
+     * Forward level filters are called before the script handling a forwarded
+     * resource is called. A resource is considered forwarded if it rendered as
+     * a result of calling <code>RequestDispatcher.forward</code>. This may also
+     * be induced by any JSP tags causing the
+     * <code>RequestDispatcher.forward</code> method being called, e.g.
+     * <code>&lt;sling:forward&gt;</code>. The order of calling the filters is
+     * defined by the <code>service.ranking</code> (or {@link #FILTER_ORDER})
+     * property and the service registration ID.
+     *
+     * @see #FILTER_SCOPE
+     * @since 2.1, Sling Engine 2.2
+     */
+    public static final String FILTER_SCOPE_FORWARD = "FORWARD";
+
+    /**
+     * Filter scope value identifying a request level filter.
+     * <p>
+     * Request level filters are called once at the beginning of each request.
+     * The order of calling the filters is defined by the
+     * <code>service.ranking</code> (or {@link #FILTER_ORDER}) property and the
+     * service registration ID.
+     *
+     * @see #FILTER_SCOPE
+     * @since 2.1, Sling Engine 2.2
+     */
+    public static final String FILTER_SCOPE_REQUEST = "REQUEST";
+
+    /**
+     * The name of the service registration property previously used to place an
+     * order amongst filters. Starting with the Sling Engine 2.2, filters should
+     * be registered with a standard <code>service.ranking</code> service
+     * property to implement filter ordering.
+     * <p>
+     * If a service is registered with both a <code>service.ranking</code> and a
+     * <code>filter.order</code> property, the <code>service.ranking</code>
+     * property is used for ordering. If only a <code>filter.order</code>
+     * property is used it is currently still used.
+     *
+     * @since 2.1, Sling Engine 2.2
+     * @deprecated Use <code>"service.ranking"</code>
+     *             (org.osgi.framework.Constants.SERVICE_RANKING) instead
+     */
+    @Deprecated
+    public static final String FILTER_ORDER = "filter.order";
 }

Added: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/SlingRequestProcessor.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/SlingRequestProcessor.java?rev=993280&view=auto
==============================================================================
--- sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/SlingRequestProcessor.java (added)
+++ sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/SlingRequestProcessor.java Tue Sep  7 08:45:36 2010
@@ -0,0 +1,59 @@
+/*
+ * 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.engine;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.api.resource.ResourceResolver;
+
+/**
+ * The <code>SlingRequestProcessor</code> interface defines the service which
+ * may be called to handle HTTP requests.
+ * <p>
+ * This interface is implemented by this bundle and is not intended to be
+ * implemented by bundles other than this.
+ */
+public interface SlingRequestProcessor {
+
+    /**
+     * Process an HTTP request through the Sling request processing engine.
+     * <p>
+     * This method does <b>not</b> close the provided resource resolver !
+     *
+     * @param request Usually a "synthetic" request, i.e. not supplied by
+     *            servlet container
+     * @param resource Usually a "synthetic" response, i.e. not supplied by
+     *            servlet container
+     * @param resourceResolver The <code>ResourceResolver</code> used for the
+     *            Sling request processing.
+     * @throws NullPointerException if either of the parameters is
+     *             <code>null</code>
+     * @throws IOException if an error occurrs reading from the request input or
+     *             writing the response
+     * @throws ServletException if another servlet related problem occurrs
+     */
+    void processRequest(HttpServletRequest request,
+            HttpServletResponse resource, ResourceResolver resourceResolver)
+            throws ServletException, IOException;
+
+}

Propchange: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/SlingRequestProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/SlingRequestProcessor.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/DefaultErrorHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/DefaultErrorHandler.java?rev=993280&view=auto
==============================================================================
--- sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/DefaultErrorHandler.java (added)
+++ sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/DefaultErrorHandler.java Tue Sep  7 08:45:36 2010
@@ -0,0 +1,165 @@
+/*
+ * 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.engine.impl;
+
+import static org.apache.sling.api.SlingConstants.ERROR_REQUEST_URI;
+import static org.apache.sling.api.SlingConstants.ERROR_SERVLET_NAME;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.api.request.RequestProgressTracker;
+import org.apache.sling.api.request.ResponseUtil;
+import org.apache.sling.engine.servlets.ErrorHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>DefaultErrorHandler</code> is used by the
+ * {@link SlingRequestProcessorImpl} as long as no {@link ErrorHandler} service
+ * is registered.
+ */
+public class DefaultErrorHandler implements ErrorHandler {
+
+    /** default log */
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private String serverInfo = SlingMainServlet.PRODUCT_NAME;
+
+    void setServerInfo(final String serverInfo) {
+        this.serverInfo = (serverInfo != null)
+                ? serverInfo
+                : SlingMainServlet.PRODUCT_NAME;
+    }
+
+    // ---------- ErrorHandler interface (default implementation) --------------
+
+    /**
+     * Backend implementation of the HttpServletResponse.sendError methods.
+     * <p>
+     * This implementation resets the response before sending back a
+     * standardized response which just conveys the status, the message (either
+     * provided or a message derived from the status code), and server
+     * information.
+     * <p>
+     * This method logs error and does not write back and response data if the
+     * response has already been committed.
+     */
+    public void handleError(int status, String message,
+            SlingHttpServletRequest request, SlingHttpServletResponse response)
+            throws IOException {
+
+        if (message == null) {
+            message = "HTTP ERROR:" + String.valueOf(status);
+        } else {
+            message = "HTTP ERROR:" + status + " - " + message;
+        }
+
+        sendError(status, message, null, request, response);
+    }
+
+    /**
+     * Backend implementation of handling uncaught throwables.
+     * <p>
+     * This implementation resets the response before sending back a
+     * standardized response which just conveys the status as 500/INTERNAL
+     * SERVER ERROR, the message from the throwable, the stacktrace, and server
+     * information.
+     * <p>
+     * This method logs error and does not write back and response data if the
+     * response has already been committed.
+     */
+    public void handleError(Throwable throwable,
+            SlingHttpServletRequest request, SlingHttpServletResponse response)
+            throws IOException {
+        sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+            throwable.getMessage(), throwable, request, response);
+    }
+
+    private void sendError(int status, String message, Throwable throwable,
+            HttpServletRequest request, HttpServletResponse response)
+            throws IOException {
+
+        if (response.isCommitted()) {
+            log.error(
+                "handleError: Response already committed; cannot send error "
+                    + status + message, throwable);
+        } else {
+
+            // error situation
+            String servletName = (String) request.getAttribute(ERROR_SERVLET_NAME);
+            String requestURI = (String) request.getAttribute(ERROR_REQUEST_URI);
+            if (requestURI == null) {
+                requestURI = request.getRequestURI();
+            }
+
+            // reset anything in the response first
+            response.reset();
+
+            // set the status, content type and encoding
+            response.setStatus(status);
+            response.setContentType("text/html; charset=UTF-8");
+
+            PrintWriter pw = response.getWriter();
+            pw.println("<html><head><title>");
+            pw.println(ResponseUtil.escapeXml(message));
+            pw.println("</title></head><body><h1>");
+            if (throwable != null) {
+                pw.println(ResponseUtil.escapeXml(throwable.toString()));
+            } else if (message != null) {
+                pw.println(ResponseUtil.escapeXml(message));
+            } else {
+                pw.println("Internal error (no Exception to report)");
+            }
+            pw.println("</h1><p>");
+            pw.println("RequestURI="
+                + ResponseUtil.escapeXml(request.getRequestURI()));
+            if (servletName != null) {
+                pw.println("</p>Servlet=" + servletName + "<p>");
+            }
+            pw.println("</p>");
+
+            if (throwable != null) {
+                pw.println("<h3>Exception stacktrace:</h3>");
+                pw.println("<pre>");
+                throwable.printStackTrace(pw);
+                pw.println("</pre>");
+
+                RequestProgressTracker tracker = ((SlingHttpServletRequest) request).getRequestProgressTracker();
+                pw.println("<h3>Request Progress:</h3>");
+                pw.println("<pre>");
+                tracker.dump(pw);
+                pw.println("</pre>");
+            }
+
+            pw.println("<hr /><address>");
+            pw.println(serverInfo);
+            pw.println("</address></body></html>");
+
+            // commit the response
+            response.flushBuffer();
+
+        }
+    }
+}

Propchange: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/DefaultErrorHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/DefaultErrorHandler.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpContext.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpContext.java?rev=993280&view=auto
==============================================================================
--- sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpContext.java (added)
+++ sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpContext.java Tue Sep  7 08:45:36 2010
@@ -0,0 +1,162 @@
+/*
+ * 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.engine.impl;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.auth.core.AuthenticationSupport;
+import org.apache.sling.commons.mime.MimeTypeService;
+import org.apache.sling.engine.impl.parameters.ParameterSupport;
+import org.osgi.service.http.HttpContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>SlingHttpContext</code> implements the OSGi HttpContext used to
+ * register the {@link SlingMainServlet} with the OSGi HttpService.
+ */
+class SlingHttpContext implements HttpContext {
+
+    /** default log */
+    private static final Logger log = LoggerFactory.getLogger(SlingHttpContext.class);
+
+    /**
+     * Resolves MIME types
+     *
+     * @see #getMimeType(String)
+     */
+    private MimeTypeService mimeTypeService;
+
+    /**
+     * Handles security
+     *
+     * @see #handleSecurity(HttpServletRequest, HttpServletResponse)
+     */
+    private AuthenticationSupport authenticationSupport;
+
+    public void setMimeTypeService(MimeTypeService mimeTypeService) {
+        this.mimeTypeService = mimeTypeService;
+    }
+
+    public void unsetMimeTypeService(MimeTypeService mimeTypeService) {
+        if (this.mimeTypeService == mimeTypeService) {
+            this.mimeTypeService = null;
+        }
+    }
+
+    public void setAuthenticationSupport(
+            AuthenticationSupport authenticationSupport) {
+        this.authenticationSupport = authenticationSupport;
+    }
+
+    public void unsetAuthenticationSupport(
+            AuthenticationSupport authenticationSupport) {
+        if (this.authenticationSupport == authenticationSupport) {
+            this.authenticationSupport = null;
+        }
+    }
+
+    // ---------- HttpContext interface ----------------------------------------
+
+    /**
+     * Returns the MIME type as resolved by the <code>MimeTypeService</code> or
+     * <code>null</code> if the service is not available.
+     */
+    public String getMimeType(String name) {
+        MimeTypeService mtservice = mimeTypeService;
+        if (mtservice != null) {
+            return mtservice.getMimeType(name);
+        }
+
+        log.debug(
+            "getMimeType: MimeTypeService not available, cannot resolve mime type for {}",
+            name);
+        return null;
+    }
+
+    /**
+     * Always returns <code>null</code> because resources are all provided
+     * through the {@link SlingMainServlet}.
+     */
+    public URL getResource(String name) {
+        return null;
+    }
+
+    /**
+     * Tries to authenticate the request using the
+     * <code>SlingAuthenticator</code>. If the authenticator or the Repository
+     * is missing this method returns <code>false</code> and sends a 503/SERVICE
+     * UNAVAILABLE status back to the client.
+     */
+    public boolean handleSecurity(HttpServletRequest request,
+            HttpServletResponse response) throws IOException {
+
+        final AuthenticationSupport authenticator = this.authenticationSupport;
+        if (authenticator != null) {
+
+            // SLING-559: ensure correct parameter handling according to
+            // ParameterSupport
+            request = new HttpServletRequestWrapper(request) {
+                @Override
+                public String getParameter(String name) {
+                    return getParameterSupport().getParameter(name);
+                }
+
+                @Override
+                public Map<String, String[]> getParameterMap() {
+                    return getParameterSupport().getParameterMap();
+                }
+
+                @Override
+                public Enumeration<String> getParameterNames() {
+                    return getParameterSupport().getParameterNames();
+                }
+
+                @Override
+                public String[] getParameterValues(String name) {
+                    return getParameterSupport().getParameterValues(name);
+                }
+
+                private ParameterSupport getParameterSupport() {
+                    return ParameterSupport.getInstance(getRequest());
+                }
+            };
+
+            return authenticator.handleSecurity(request, response);
+
+        }
+
+        log.error("handleSecurity: AuthenticationSupport service missing. Cannot authenticate request.");
+
+        // send 503/SERVICE UNAVAILABLE, flush to ensure delivery
+        response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,
+            "AuthenticationSupport service missing. Cannot authenticate request.");
+        response.flushBuffer();
+
+        // terminate this request now
+        return false;
+    }
+}

Propchange: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpContext.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Modified: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpServletRequestImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpServletRequestImpl.java?rev=993280&r1=993279&r2=993280&view=diff
==============================================================================
--- sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpServletRequestImpl.java (original)
+++ sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpServletRequestImpl.java Tue Sep  7 08:45:36 2010
@@ -38,7 +38,6 @@ import javax.servlet.http.HttpServletReq
 import javax.servlet.http.HttpServletRequestWrapper;
 
 import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.adapter.AdapterManager;
 import org.apache.sling.api.request.RequestDispatcherOptions;
 import org.apache.sling.api.request.RequestParameter;
 import org.apache.sling.api.request.RequestParameterMap;
@@ -68,7 +67,7 @@ public class SlingHttpServletRequestImpl
             HttpServletRequest servletRequest) {
         super(servletRequest);
         this.requestData = requestData;
-        
+
         // prepare the pathInfo property
         String pathInfo = servletRequest.getServletPath();
         if (servletRequest.getPathInfo() != null) {
@@ -86,17 +85,11 @@ public class SlingHttpServletRequestImpl
     }
 
     //---------- Adaptable interface
-    
+
     public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
-        AdapterManager adapterManager = getRequestData().getAdapterManager();
-        if (adapterManager != null) {
-            return adapterManager.getAdapter(this, type);
-        }
-        
-        // no adapter manager, nothing to adapt to
-        return null;
+        return getRequestData().adaptTo(this, type);
     }
-    
+
     //---------- SlingHttpServletRequest interface
 
     ParameterSupport getParameterSupport() {
@@ -242,7 +235,7 @@ public class SlingHttpServletRequestImpl
     public String getResponseContentType() {
         if(responseContentType == null) {
             final String ext = getRequestPathInfo().getExtension();
-            responseContentType = requestData.getSlingMainServlet().getServletContext().getMimeType("dummy." + ext);
+            responseContentType = requestData.getMimeType("dummy." + ext);
         }
         return responseContentType;
     }
@@ -306,7 +299,7 @@ public class SlingHttpServletRequestImpl
     public String getServletPath() {
         return "";
     }
-    
+
     /**
      * Returns the part of the request URL without the leading servlet context
      * path.
@@ -315,7 +308,7 @@ public class SlingHttpServletRequestImpl
     public String getPathInfo() {
         return pathInfo;
     }
-    
+
     /**
      * A <code>UserPrincipal</code> ...
      */

Modified: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpServletResponseImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpServletResponseImpl.java?rev=993280&r1=993279&r2=993280&view=diff
==============================================================================
--- sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpServletResponseImpl.java (original)
+++ sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingHttpServletResponseImpl.java Tue Sep  7 08:45:36 2010
@@ -35,9 +35,7 @@ import javax.servlet.http.HttpServletRes
 import javax.servlet.http.HttpServletResponseWrapper;
 
 import org.apache.sling.api.SlingHttpServletResponse;
-import org.apache.sling.api.adapter.AdapterManager;
 import org.apache.sling.engine.impl.request.RequestData;
-import org.apache.sling.engine.servlets.ErrorHandler;
 
 /**
  * The <code>SlingHttpServletResponseImpl</code> TODO
@@ -123,13 +121,7 @@ public class SlingHttpServletResponseImp
     //---------- Adaptable interface
 
     public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
-        AdapterManager adapterManager = getRequestData().getAdapterManager();
-        if (adapterManager != null) {
-            return adapterManager.getAdapter(this, type);
-        }
-
-        // no adapter manager, nothing to adapt to
-        return null;
+        return getRequestData().adaptTo(this, type);
     }
 
     //---------- SlingHttpServletResponse interface
@@ -249,7 +241,7 @@ public class SlingHttpServletResponseImp
         checkCommitted();
 
         this.status = status;
-        ErrorHandler eh = getRequestData().getSlingMainServlet().getErrorHandler();
+        SlingRequestProcessorImpl eh = getRequestData().getSlingRequestProcessor();
         eh.handleError(status, message, requestData.getSlingRequest(), this);
     }
 

Modified: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingMainServlet.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingMainServlet.java?rev=993280&r1=993279&r2=993280&view=diff
==============================================================================
--- sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingMainServlet.java (original)
+++ sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingMainServlet.java Tue Sep  7 08:45:36 2010
@@ -18,96 +18,83 @@
  */
 package org.apache.sling.engine.impl;
 
-import static org.apache.sling.api.SlingConstants.ERROR_REQUEST_URI;
-import static org.apache.sling.api.SlingConstants.ERROR_SERVLET_NAME;
-
 import java.io.IOException;
-import java.io.PrintWriter;
 import java.net.SocketException;
-import java.net.URL;
-import java.security.AccessControlException;
-import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
 import javax.servlet.GenericServlet;
-import javax.servlet.Servlet;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.sling.api.SlingException;
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.felix.scr.annotations.Component;
+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.felix.scr.annotations.References;
 import org.apache.sling.api.adapter.AdapterManager;
-import org.apache.sling.api.request.RequestPathInfo;
-import org.apache.sling.api.request.RequestProgressTracker;
-import org.apache.sling.api.request.ResponseUtil;
 import org.apache.sling.api.request.SlingRequestEvent;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceNotFoundException;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.servlets.ServletResolver;
 import org.apache.sling.auth.core.AuthenticationSupport;
 import org.apache.sling.commons.mime.MimeTypeService;
 import org.apache.sling.commons.osgi.OsgiUtil;
-import org.apache.sling.engine.impl.filter.RequestSlingFilterChain;
-import org.apache.sling.engine.impl.filter.SlingComponentFilterChain;
-import org.apache.sling.engine.impl.filter.SlingFilterChainHelper;
+import org.apache.sling.engine.impl.filter.ServletFilterManager;
 import org.apache.sling.engine.impl.helper.RequestListenerManager;
-import org.apache.sling.engine.impl.helper.SlingFilterConfig;
 import org.apache.sling.engine.impl.helper.SlingServletContext;
 import org.apache.sling.engine.impl.log.RequestLogger;
-import org.apache.sling.engine.impl.parameters.ParameterSupport;
-import org.apache.sling.engine.impl.request.ContentData;
 import org.apache.sling.engine.impl.request.RequestData;
 import org.apache.sling.engine.servlets.ErrorHandler;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
 import org.osgi.framework.Version;
 import org.osgi.service.component.ComponentContext;
-import org.osgi.service.http.HttpContext;
 import org.osgi.service.http.HttpService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * The <code>SlingMainServlet</code> TODO
- *
- * @scr.component immediate="true" label="%sling.name"
- *                description="%sling.description"
- * @scr.property name="service.vendor" value="The Apache Software Foundation"
- * @scr.property name="service.description" value="Sling Servlet"
- * @scr.reference name="Filter" interface="javax.servlet.Filter"
- *                cardinality="0..n" policy="dynamic"
  */
 @SuppressWarnings("serial")
-public class SlingMainServlet extends GenericServlet implements ErrorHandler,
-        HttpContext {
+@Component(immediate = true, label = "%sling.name", description = "%sling.description")
+@Properties( {
+    @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation"),
+    @Property(name = Constants.SERVICE_DESCRIPTION, value = "Sling Servlet")
+
+})
+@References( {
+    @Reference(name = "ErrorHandler", referenceInterface = ErrorHandler.class, cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC, bind = "setErrorHandler", unbind = "unsetErrorHandler"),
+    @Reference(name = "RequestLogger", referenceInterface = RequestLogger.class, cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC, bind = "setRequestLogger", unbind = "unsetRequestLogger"),
+    @Reference(name = "ServletResolver", referenceInterface = ServletResolver.class, cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC, bind = "setServletResolver", unbind = "unsetServletResolver"),
+    @Reference(name = "MimeTypeService", referenceInterface = MimeTypeService.class, cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC, bind = "setMimeTypeService", unbind = "unsetMimeTypeService"),
+    @Reference(name = "AuthenticationSupport", referenceInterface = AuthenticationSupport.class, cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC, bind = "setAuthenticationSupport", unbind = "unsetAuthenticationSupport") })
+public class SlingMainServlet extends GenericServlet {
 
-    /** @scr.property valueRef="RequestData.DEFAULT_MAX_CALL_COUNTER" */
+    @Property(intValue=RequestData.DEFAULT_MAX_CALL_COUNTER)
     public static final String PROP_MAX_CALL_COUNTER = "sling.max.calls";
 
-    /** @scr.property valueRef="RequestData.DEFAULT_MAX_INCLUSION_COUNTER" */
+    @Property(intValue=RequestData.DEFAULT_MAX_INCLUSION_COUNTER)
     public static final String PROP_MAX_INCLUSION_COUNTER = "sling.max.inclusions";
 
-    /** @scr.property valueRef="DEFAULT_ALLOW_TRACE" */
+    public static final boolean DEFAULT_ALLOW_TRACE = false;
+
+    @Property(boolValue=DEFAULT_ALLOW_TRACE)
     public static final String PROP_ALLOW_TRACE = "sling.trace.allow";
 
-    public static final boolean DEFAULT_ALLOW_TRACE = false;
+    @Reference
+    private HttpService httpService;
+
+    @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC)
+    private AdapterManager adapterManager;
 
     /** default log */
-    private static final Logger log = LoggerFactory.getLogger(SlingMainServlet.class);
+    private final Logger log = LoggerFactory.getLogger(SlingMainServlet.class);
 
     /**
      * The registration path for the SlingMainServlet is hard wired to always
@@ -119,25 +106,12 @@ public class SlingMainServlet extends Ge
      * The name of the product to report in the {@link #getServerInfo()} method
      * (value is "ApacheSling").
      */
-    private static String PRODUCT_NAME = "ApacheSling";
-
-    /**
-     * The name of the Declarative Services reference to the Servlet API Filter
-     * services (value is "Filter").
-     */
-    private static String FILTER_NAME = "Filter";
-
-    /**
-     * The service property used by Felix's HttpService whiteboard implementation.
-     */
-    private static String FELIX_WHITEBOARD_PATTERN_PROPERTY = "pattern";
+    static String PRODUCT_NAME = "ApacheSling";
 
     private SlingServletContext slingServletContext;
 
     private ComponentContext osgiComponentContext;
 
-    private List<ServiceReference> delayedComponentFilters;
-
     /**
      * The server information to report in the {@link #getServerInfo()} method.
      * By default this is just the {@link #PRODUCT_NAME}. The
@@ -147,38 +121,19 @@ public class SlingMainServlet extends Ge
      */
     private String serverInfo = PRODUCT_NAME;
 
-    /**
-     * @scr.reference
-     */
-    private HttpService httpService;
-
-    /** @scr.reference cardinality="0..1" policy="dynamic" */
-    private MimeTypeService mimeTypeService;
-
-    /** @scr.reference cardinality="0..1" policy="dynamic" */
-    private ServletResolver servletResolver;
-
-    /** @scr.reference cardinality="0..1" policy="dynamic" */
-    private ErrorHandler errorHandler;
-
-    /** @scr.reference cardinality="0..1" policy="dynamic" */
-    private RequestLogger requestLogger;
-
-    /** @scr.reference cardinality="0..1" policy="dynamic" */
-    private AdapterManager adapterManager;
+    private RequestListenerManager requestListenerManager;
 
-    /** @scr.reference cardinality="0..1" policy="dynamic" */
-    private AuthenticationSupport authenticationSupport;
+    private boolean allowTrace = DEFAULT_ALLOW_TRACE;
 
-    private SlingFilterChainHelper requestFilterChain = new SlingFilterChainHelper();
+    private Object printerRegistration;
 
-    private SlingFilterChainHelper innerFilterChain = new SlingFilterChainHelper();
+    // new properties
 
-    private RequestListenerManager requestListenerManager;
+    private SlingHttpContext slingHttpContext = new SlingHttpContext();
 
-    private boolean allowTrace = DEFAULT_ALLOW_TRACE;
+    private ServletFilterManager filterManager;
 
-    private Object printerRegistration;
+    private final SlingRequestProcessorImpl requestProcessor = new SlingRequestProcessorImpl();
 
     // ---------- Servlet API -------------------------------------------------
 
@@ -195,6 +150,7 @@ public class SlingMainServlet extends Ge
 
             requestListenerManager.sendEvent( request, SlingRequestEvent.EventType.EVENT_INIT );
 
+            ResourceResolver resolver = null;
             try {
                 if (!allowTrace && "TRACE".equals(request.getMethod())) {
                     HttpServletResponse response = (HttpServletResponse) res;
@@ -203,8 +159,15 @@ public class SlingMainServlet extends Ge
                     return;
                 }
 
+                // get ResourceResolver (set by AuthenticationSupport)
+                Object resolverObject = request.getAttribute(AuthenticationSupport.REQUEST_ATTRIBUTE_RESOLVER);
+                resolver = (resolverObject instanceof ResourceResolver)
+                        ? (ResourceResolver) resolverObject
+                        : null;
+
                 // real request handling for HTTP requests
-                service(request, (HttpServletResponse) res);
+                requestProcessor.processRequest(request, (HttpServletResponse) res,
+                    resolver);
 
             } catch (IOException ioe) {
 
@@ -244,6 +207,13 @@ public class SlingMainServlet extends Ge
 
             } finally {
 
+
+                // close the resource resolver (not relying on servlet request
+                // listener to do this for now; see SLING-1270)
+                if (resolver != null) {
+                    resolver.close();
+                }
+
                 requestListenerManager.sendEvent( request, SlingRequestEvent.EventType.EVENT_DESTROY );
 
                 // reset the thread name
@@ -258,265 +228,6 @@ public class SlingMainServlet extends Ge
         }
     }
 
-    // ---------- Request Handling on behalf of the servlet -------------------
-
-    public void service(HttpServletRequest servletRequest,
-            HttpServletResponse servletResponse) throws IOException {
-
-        // setting the Sling request and response
-        final RequestData requestData = new RequestData(this, servletRequest,
-            servletResponse);
-        final SlingHttpServletRequest request = requestData.getSlingRequest();
-        final SlingHttpServletResponse response = requestData.getSlingResponse();
-
-        // request entry log
-        if (requestLogger != null) {
-            requestLogger.logRequestEntry(request, response);
-        }
-
-        ResourceResolver resolver = null;
-        try {
-            // check that we have all required services
-            String errorMessage = null;
-            final String serviceMissingSuffix =  " service missing, cannot service requests";
-            if (getServletResolver() == null) {
-                errorMessage = "ServletResolver" + serviceMissingSuffix;
-            } else if (mimeTypeService == null) {
-                errorMessage = "MimeTypeService" + serviceMissingSuffix;
-            }
-
-            // get ResourceResolver (set by AuthenticationSupport)
-            resolver = (ResourceResolver) servletRequest.getAttribute(AuthenticationSupport.REQUEST_ATTRIBUTE_RESOLVER);
-            if (resolver == null) {
-                errorMessage = "Missing ResourceResolver";
-            }
-
-            if (errorMessage != null) {
-                final int status = HttpServletResponse.SC_SERVICE_UNAVAILABLE;
-                log.error("{} , sending status {}", errorMessage, status);
-                sendError(status, errorMessage, null, servletRequest, servletResponse);
-                return;
-            }
-
-            // initialize the request data - resolve resource and servlet
-            Resource resource = requestData.initResource(resolver);
-            requestData.initServlet(resource);
-
-            Filter[] filters = requestFilterChain.getFilters();
-            if (filters != null) {
-                FilterChain processor = new RequestSlingFilterChain(this,
-                    filters);
-
-                request.getRequestProgressTracker().log(
-                    "Applying request filters");
-
-                processor.doFilter(request, response);
-
-            } else {
-
-                // no filters, directly call resource level filters and servlet
-                processRequest(request, response);
-
-            }
-
-        } catch (ResourceNotFoundException rnfe) {
-
-            // send this exception as a 404 status
-            log.info("service: Resource {} not found", rnfe.getResource());
-
-            getErrorHandler().handleError(HttpServletResponse.SC_NOT_FOUND,
-                rnfe.getMessage(), request, response);
-
-        } catch (SlingException se) {
-
-            // if we have request data and a non-null active servlet name
-            // we assume, that this is the name of the causing servlet
-            if (requestData.getActiveServletName() != null) {
-                request.setAttribute(ERROR_SERVLET_NAME,
-                    requestData.getActiveServletName());
-            }
-
-            // send this exception as is (albeit unwrapping and wrapped
-            // exception.
-            Throwable t = (se.getCause() != null) ? se.getCause() : se;
-            log.error("service: Uncaught SlingException", t);
-            getErrorHandler().handleError(t, request, response);
-
-        } catch (AccessControlException ace) {
-
-            // SLING-319 if anything goes wrong, send 403/FORBIDDEN
-            log.info(
-                "service: Authenticated user {} does not have enough rights to executed requested action",
-                request.getRemoteUser());
-            getErrorHandler().handleError(HttpServletResponse.SC_FORBIDDEN,
-                null, request, response);
-
-        } catch (Throwable t) {
-
-            // if we have request data and a non-null active servlet name
-            // we assume, that this is the name of the causing servlet
-            if (requestData.getActiveServletName() != null) {
-                request.setAttribute(ERROR_SERVLET_NAME,
-                    requestData.getActiveServletName());
-            }
-
-            log.error("service: Uncaught Throwable", t);
-            getErrorHandler().handleError(t, request, response);
-
-        } finally {
-
-            // request exit log
-            if (requestLogger != null) {
-                requestLogger.logRequestExit(request, response);
-            }
-
-            // dispose any request data
-            requestData.dispose();
-
-            // close the resource resolver (not relying on servlet request
-            // listener to do this for now; see SLING-1270)
-            if (resolver != null) {
-                resolver.close();
-            }
-        }
-    }
-
-    // ---------- Generic Content Request processor ----------------------------
-
-    public void includeContent(ServletRequest request,
-            ServletResponse response, Resource resource,
-            RequestPathInfo resolvedURL) throws IOException, ServletException {
-
-        // we need a SlingHttpServletRequest/SlingHttpServletResponse tupel
-        // to continue
-        SlingHttpServletRequest cRequest = RequestData.toSlingHttpServletRequest(request);
-        SlingHttpServletResponse cResponse = RequestData.toSlingHttpServletResponse(response);
-
-        // get the request data (and btw check the correct type)
-        RequestData requestData = RequestData.getRequestData(cRequest);
-        ContentData contentData = requestData.pushContent(resource,
-            resolvedURL);
-
-        try {
-            // resolve the servlet
-            Servlet servlet = getServletResolver().resolveServlet(cRequest);
-            contentData.setServlet(servlet);
-
-            processRequest(cRequest, cResponse);
-        } finally {
-            requestData.popContent();
-        }
-    }
-
-    public void processRequest(SlingHttpServletRequest request,
-            SlingHttpServletResponse response) throws IOException,
-            ServletException {
-
-        // 2.0 Set Content from mappedURL
-        // ContentData contentData = null;
-
-        Filter filters[] = innerFilterChain.getFilters();
-        if (filters != null) {
-            FilterChain processor = new SlingComponentFilterChain(filters);
-
-            request.getRequestProgressTracker().log("Applying inner filters");
-
-            processor.doFilter(request, response);
-        } else {
-            log.debug("service: No Resource level filters, calling servlet");
-            RequestData.service(request, response);
-        }
-    }
-
-    // ---------- ErrorHandler interface (default implementation) --------------
-
-    // reset the response, set the status and write a simple message
-    public void handleError(int status, String message,
-            SlingHttpServletRequest request, SlingHttpServletResponse response)
-            throws IOException {
-
-        if (message == null) {
-            message = "HTTP ERROR:" + String.valueOf(status);
-        } else {
-            message = "HTTP ERROR:" + status + " - " + message;
-        }
-
-        sendError(status, message, null, request, response);
-    }
-
-    // just rethrow the exception as explained in the class comment
-    public void handleError(Throwable throwable,
-            SlingHttpServletRequest request, SlingHttpServletResponse response)
-            throws IOException {
-        sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
-            throwable.getMessage(), throwable, request, response);
-    }
-
-    private void sendError(int status, String message, Throwable throwable,
-            HttpServletRequest request, HttpServletResponse response)
-            throws IOException {
-
-        if (response.isCommitted()) {
-            log.error(
-                "handleError: Response already committed; cannot send error "
-                    + status + message, throwable);
-        } else {
-
-            // error situation
-            String servletName = (String) request.getAttribute(ERROR_SERVLET_NAME);
-            String requestURI = (String) request.getAttribute(ERROR_REQUEST_URI);
-            if (requestURI == null) {
-                requestURI = request.getRequestURI();
-            }
-
-            // reset anything in the response first
-            response.reset();
-
-            // set the status, content type and encoding
-            response.setStatus(status);
-            response.setContentType("text/html; charset=UTF-8");
-
-            PrintWriter pw = response.getWriter();
-            pw.println("<html><head><title>");
-            pw.println(ResponseUtil.escapeXml(message));
-            pw.println("</title></head><body><h1>");
-            if (throwable != null) {
-                pw.println(ResponseUtil.escapeXml(throwable.toString()));
-            } else if (message != null) {
-                pw.println(ResponseUtil.escapeXml(message));
-            } else {
-                pw.println("Internal error (no Exception to report)");
-            }
-            pw.println("</h1><p>");
-            pw.println("RequestURI=" + ResponseUtil.escapeXml(request.getRequestURI()));
-            if (servletName != null) {
-                pw.println("</p>Servlet=" + servletName + "<p>");
-            }
-            pw.println("</p>");
-
-            if (throwable != null) {
-                pw.println("<h3>Exception stacktrace:</h3>");
-                pw.println("<pre>");
-                throwable.printStackTrace(pw);
-                pw.println("</pre>");
-
-                RequestProgressTracker tracker = ((SlingHttpServletRequest) request).getRequestProgressTracker();
-                pw.println("<h3>Request Progress:</h3>");
-                pw.println("<pre>");
-                tracker.dump(pw);
-                pw.println("</pre>");
-            }
-
-            pw.println("<hr /><address>");
-            pw.println(getServerInfo());
-            pw.println("</address></body></html>");
-
-            // commit the response
-            response.flushBuffer();
-
-        }
-    }
-
     // ---------- Internal helper ----------------------------------------------
 
     public String getServerInfo() {
@@ -527,23 +238,6 @@ public class SlingMainServlet extends Ge
         return osgiComponentContext.getBundleContext();
     }
 
-    public ServletResolver getServletResolver() {
-        return servletResolver;
-    }
-
-    public ErrorHandler getErrorHandler() {
-        ErrorHandler eh = errorHandler;
-        return (eh != null) ? eh : this;
-    }
-
-    /**
-     * Returns the {@link AdapterManager} bound to this instance or
-     * <code>null</code> if no adapter manager is bound to this instance.
-     */
-    public AdapterManager getAdapterManager() {
-        return adapterManager;
-    }
-
     // ---------- Property Setter for SCR --------------------------------------
 
     protected void activate(ComponentContext componentContext) {
@@ -562,6 +256,7 @@ public class SlingMainServlet extends Ge
             + System.getProperty("os.name") + " "
             + System.getProperty("os.version") + " "
             + System.getProperty("os.arch") + ")";
+        this.requestProcessor.setServerInfo(serverInfo);
 
         // prepare the servlet configuration from the component config
         final Hashtable<String, Object> configuration = new Hashtable<String, Object>();
@@ -588,13 +283,14 @@ public class SlingMainServlet extends Ge
         RequestData.setMaxCallCounter(OsgiUtil.toInteger(
             componentConfig.get(PROP_MAX_CALL_COUNTER),
             RequestData.DEFAULT_MAX_CALL_COUNTER));
+        RequestData.setSlingMainServlet(this);
 
         // register the servlet and resources
         try {
             Dictionary<String, String> servletConfig = toStringConfig(configuration);
 
             this.httpService.registerServlet(SLING_ROOT, this, servletConfig,
-                this);
+                slingHttpContext);
 
             log.info("{} ready to serve requests", this.getServerInfo());
 
@@ -604,38 +300,22 @@ public class SlingMainServlet extends Ge
 
         // now that the sling main servlet is registered with the HttpService
         // and initialized we can register the servlet context
-        final SlingServletContext tmpServletContext = new SlingServletContext(this);
+        slingServletContext = new SlingServletContext(this);
 
         // register render filters already registered after registration with
         // the HttpService as filter initialization may cause the servlet
         // context to be required (see SLING-42)
-
-        List<ServiceReference> filterList;
-        synchronized (this) {
-            filterList = delayedComponentFilters;
-
-            // prepare the Sling Component Context now after having finished the
-            // handler setup but before initializing the filters.
-            // After leaving this synched block, bindFilter will be "active" and
-            // set the delayedComponentFilters field to null for GC
-            slingServletContext = tmpServletContext;
-            delayedComponentFilters = null;
-        }
-
-        // if there are filters at all, initialize them now
-        if (filterList != null) {
-            for (ServiceReference serviceReference : filterList) {
-                initFilter(componentContext, serviceReference);
-            }
-        }
+        filterManager = new ServletFilterManager(
+            componentContext.getBundleContext(), slingServletContext);
+        filterManager.open();
+        requestProcessor.setFilterManager(filterManager);
 
         // initialize requestListenerManager
         requestListenerManager = new RequestListenerManager( bundleContext, slingServletContext );
 
         // try to setup configuration printer
         try {
-            this.printerRegistration = WebConsoleConfigPrinter.register(bundleContext, requestFilterChain, innerFilterChain);
-
+            this.printerRegistration = WebConsoleConfigPrinter.register(bundleContext, filterManager);
         } catch (Throwable t) {
             log.debug("Unable to register web console configuration printer.", t);
         }
@@ -647,16 +327,13 @@ public class SlingMainServlet extends Ge
             WebConsoleConfigPrinter.unregister(this.printerRegistration);
             this.printerRegistration = null;
         }
-
-        if ( this.requestListenerManager != null ) {
-            this.requestListenerManager.dispose();
-            this.requestListenerManager = null;
+        // destroy servlet filters before destroying the sling servlet
+        // context because the filters depend on that context
+        if (filterManager != null) {
+            requestProcessor.setFilterManager(null);
+            filterManager.close();
         }
 
-        // first destroy the filters
-        destroyFilters(innerFilterChain);
-        destroyFilters(requestFilterChain);
-
         // second unregister the servlet context *before* unregistering
         // and destroying the the sling main servlet
         if (slingServletContext != null) {
@@ -667,113 +344,61 @@ public class SlingMainServlet extends Ge
         // third unregister and destroy the sling main servlet
         httpService.unregister(SLING_ROOT);
 
+        // dispose of request listener manager after unregistering the servlet
+        // to prevent a potential NPE in the service method
+        if ( this.requestListenerManager != null ) {
+            this.requestListenerManager.dispose();
+            this.requestListenerManager = null;
+        }
+
+        // reset the sling main servlet reference (help GC and be nice)
+        RequestData.setSlingMainServlet(null);
+
         this.osgiComponentContext = null;
 
         log.info(this.getServerInfo() + " shut down");
     }
 
-    protected void bindFilter(ServiceReference ref) {
-        synchronized (this) {
-            if (slingServletContext == null) {
-                if (delayedComponentFilters == null) {
-                    delayedComponentFilters = new ArrayList<ServiceReference>();
-                }
-                delayedComponentFilters.add(ref);
-            } else {
-                initFilter(osgiComponentContext, ref);
-            }
-        }
+    void setErrorHandler(final ErrorHandler errorHandler) {
+        requestProcessor.setErrorHandler(errorHandler);
     }
 
-    protected void unbindFilter(ServiceReference ref) {
-        // service id
-        Object serviceId = ref.getProperty(Constants.SERVICE_ID);
-
-        // unregister by scope and destroy it
-        Filter filter = getChain(ref).removeFilterById(serviceId);
-        if (filter != null) {
-            try {
-                filter.destroy();
-            } catch (Throwable t) {
-                log.error("Unexpected problem destroying ComponentFilter {}",
-                    filter, t);
-            }
-        }
+    void unsetErrorHandler(final ErrorHandler errorHandler) {
+        requestProcessor.unsetErrorHandler(errorHandler);
     }
 
-    private void initFilter(ComponentContext osgiContext, ServiceReference ref) {
-        // Check if filter will be registered by Felix HttpService Whiteboard
-        if (ref.getProperty(FELIX_WHITEBOARD_PATTERN_PROPERTY) != null) {
-            return;
-        }
-
-        final Filter filter = (Filter) osgiContext.locateService(FILTER_NAME, ref);
-        if ( filter == null ) {
-            return;
-        }
-
-        // require a name for the filter
-        final String filterName = SlingFilterConfig.getName(ref);
-        if (filterName == null) {
-            log.error("initFilter: Missing name for filter {}", ref);
-            return;
-        }
-
-        // initialize the filter first
-        try {
-            final FilterConfig config = new SlingFilterConfig(slingServletContext,
-                ref, filterName);
-            filter.init(config);
-
-            // service id
-            Long serviceId = (Long) ref.getProperty(Constants.SERVICE_ID);
-
-            // get the order, Integer.MAX_VALUE by default
-            Object orderObj = ref.getProperty("filter.order");
-            int order = (orderObj instanceof Integer)
-                    ? ((Integer) orderObj).intValue()
-                    : Integer.MAX_VALUE;
+    public void setServletResolver(final ServletResolver servletResolver) {
+        requestProcessor.setServletResolver(servletResolver);
+    }
 
-            // register by scope
-            getChain(ref).addFilter(filter, serviceId, order);
+    public void unsetServletResolver(final ServletResolver servletResolver) {
+        requestProcessor.unsetServletResolver(servletResolver);
+    }
 
-        } catch (ServletException ce) {
-            log.error("Filter " + filterName + " failed to initialize", ce);
-        } catch (Throwable t) {
-            log.error("Unexpected Problem initializing ComponentFilter " + "",
-                t);
-        }
+    public void setRequestLogger(final RequestLogger requestLogger) {
+        requestProcessor.setRequestLogger(requestLogger);
     }
 
-    private void destroyFilters(SlingFilterChainHelper chain) {
-        Filter[] filters = chain.removeAllFilters();
-        if (filters != null) {
-            for (int i = 0; i < filters.length; i++) {
-                try {
-                    filters[i].destroy();
-                } catch (Throwable t) {
-                    log.error(
-                        "Unexpected problem destroying ComponentFilter {}",
-                        filters[i], t);
-                }
-            }
-        }
+    public void unsetRequestLogger(final RequestLogger requestLogger) {
+        requestProcessor.unsetRequestLogger(requestLogger);
     }
 
-    private SlingFilterChainHelper getChain(ServiceReference ref) {
+    public void setMimeTypeService(final MimeTypeService mimeTypeService) {
+        slingHttpContext.setMimeTypeService(mimeTypeService);
+    }
 
-        // component rendering filter
-        Object scope = ref.getProperty("filter.scope");
-        if ("component".equals(scope)) {
-            return innerFilterChain;
-        } else if ("request".equals(scope)) {
-            return requestFilterChain;
-        }
+    public void unsetMimeTypeService(final MimeTypeService mimeTypeService) {
+        slingHttpContext.unsetMimeTypeService(mimeTypeService);
+    }
 
-        log.warn(String.format("A Filter (Service ID %s) has been registered without a filter.scope property.", ref.getProperty(Constants.SERVICE_ID)));
+    public void setAuthenticationSupport(
+            final AuthenticationSupport authenticationSupport) {
+        slingHttpContext.setAuthenticationSupport(authenticationSupport);
+    }
 
-        // global filter by default
-        return requestFilterChain;
+    public void unsetAuthenticationSupport(
+            final AuthenticationSupport authenticationSupport) {
+        slingHttpContext.unsetAuthenticationSupport(authenticationSupport);
     }
 
     private Dictionary<String, String> toStringConfig(Dictionary<?, ?> config) {
@@ -788,74 +413,17 @@ public class SlingMainServlet extends Ge
     // ---------- HttpContext interface ----------------------------------------
 
     public String getMimeType(String name) {
-        MimeTypeService mtservice = mimeTypeService;
-        if (mtservice != null) {
-            return mtservice.getMimeType(name);
-        }
-
-        log.debug(
-            "getMimeType: MimeTypeService not available, cannot resolve mime type for {}",
-            name);
-        return null;
-    }
-
-    public URL getResource(String name) {
-        return null;
+        return slingHttpContext.getMimeType(name);
     }
 
-    /**
-     * Tries to authenticate the request using the
-     * <code>SlingAuthenticator</code>. If the authenticator or the
-     * Repository is missing this method returns <code>false</code> and sends
-     * a 503/SERVICE UNAVAILABLE status back to the client.
-     */
-    public boolean handleSecurity(HttpServletRequest request,
-            HttpServletResponse response) throws IOException {
-
-        final AuthenticationSupport authenticator = this.authenticationSupport;
-        if (authenticator != null) {
-
-            // SLING-559: ensure correct parameter handling according to
-            // ParameterSupport
-            request = new HttpServletRequestWrapper(request) {
-                @Override
-                public String getParameter(String name) {
-                    return getParameterSupport().getParameter(name);
-                }
-
-                @Override
-                public Map<String, String[]> getParameterMap() {
-                    return getParameterSupport().getParameterMap();
-                }
-
-                @Override
-                public Enumeration<String> getParameterNames() {
-                    return getParameterSupport().getParameterNames();
-                }
-
-                @Override
-                public String[] getParameterValues(String name) {
-                    return getParameterSupport().getParameterValues(name);
-                }
-
-                private ParameterSupport getParameterSupport() {
-                    return ParameterSupport.getInstance(getRequest());
-                }
-            };
-
-            return authenticator.handleSecurity(request, response);
-
+    public <Type> Type adaptTo(Object object, Class<Type> type) {
+        AdapterManager adapterManager = this.adapterManager;
+        if (adapterManager != null) {
+            return adapterManager.getAdapter(object, type);
         }
 
-        log.error("handleSecurity: AuthenticationSupport service missing. Cannot authenticate request.");
-
-        // send 503/SERVICE UNAVAILABLE, flush to ensure delivery
-        response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,
-            "AuthenticationSupport service missing. Cannot authenticate request.");
-        response.flushBuffer();
-
-        // terminate this request now
-        return false;
+        // no adapter manager, nothing to adapt to
+        return null;
     }
 
     /**

Added: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java?rev=993280&view=auto
==============================================================================
--- sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java (added)
+++ sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java Tue Sep  7 08:45:36 2010
@@ -0,0 +1,351 @@
+/*
+ * 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.engine.impl;
+
+import static org.apache.sling.api.SlingConstants.ERROR_SERVLET_NAME;
+
+import java.io.IOException;
+import java.security.AccessControlException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.UnavailableException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.api.SlingException;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.api.SlingServletException;
+import org.apache.sling.api.request.RequestPathInfo;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceNotFoundException;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.servlets.ServletResolver;
+import org.apache.sling.engine.SlingRequestProcessor;
+import org.apache.sling.engine.impl.filter.AbstractSlingFilterChain;
+import org.apache.sling.engine.impl.filter.RequestSlingFilterChain;
+import org.apache.sling.engine.impl.filter.ServletFilterManager;
+import org.apache.sling.engine.impl.filter.SlingComponentFilterChain;
+import org.apache.sling.engine.impl.filter.ServletFilterManager.FilterChainType;
+import org.apache.sling.engine.impl.log.RequestLogger;
+import org.apache.sling.engine.impl.request.ContentData;
+import org.apache.sling.engine.impl.request.RequestData;
+import org.apache.sling.engine.servlets.ErrorHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SlingRequestProcessorImpl implements SlingRequestProcessor {
+
+    /** default log */
+    private final Logger log = LoggerFactory.getLogger(SlingRequestProcessorImpl.class);
+
+    /** @scr.reference cardinality="0..1" policy="dynamic" */
+
+    // used fields ....
+
+    private final DefaultErrorHandler defaultErrorHandler = new DefaultErrorHandler();
+
+    private ErrorHandler errorHandler = defaultErrorHandler;
+
+    private RequestLogger requestLogger;
+
+    private ServletResolver servletResolver;
+
+    private ServletFilterManager filterManager;
+
+    // ---------- helper setters
+
+    void setServerInfo(final String serverInfo) {
+        defaultErrorHandler.setServerInfo(serverInfo);
+    }
+
+    void setErrorHandler(final ErrorHandler errorHandler) {
+        this.errorHandler = errorHandler;
+    }
+
+    void unsetErrorHandler(final ErrorHandler errorHandler) {
+        if (this.errorHandler == errorHandler) {
+            this.errorHandler = defaultErrorHandler;
+        }
+    }
+
+    void setRequestLogger(final RequestLogger requestLogger) {
+        this.requestLogger = requestLogger;
+    }
+
+    void unsetRequestLogger(final RequestLogger requestLogger) {
+        if (this.requestLogger == requestLogger) {
+            this.requestLogger = null;
+        }
+    }
+
+    void setServletResolver(final ServletResolver servletResolver) {
+        this.servletResolver = servletResolver;
+    }
+
+    void unsetServletResolver(final ServletResolver servletResolver) {
+        if (this.servletResolver == servletResolver) {
+            this.servletResolver = null;
+        }
+    }
+
+    void setFilterManager(final ServletFilterManager filterManager) {
+        this.filterManager = filterManager;
+    }
+
+    // ---------- SlingRequestProcessor interface
+
+    public void processRequest(final HttpServletRequest servletRequest,
+            final HttpServletResponse servletResponse,
+            final ResourceResolver resourceResolver) throws IOException {
+
+        // setting the Sling request and response
+        final RequestData requestData = new RequestData(this, servletRequest,
+            servletResponse);
+        final SlingHttpServletRequest request = requestData.getSlingRequest();
+        final SlingHttpServletResponse response = requestData.getSlingResponse();
+
+        // request entry log
+        if (requestLogger != null) {
+            requestLogger.logRequestEntry(request, response);
+        }
+
+        try {
+            // check that we have all required services
+            if (resourceResolver == null) {
+                throw new UnavailableException("ResourceResolver");
+            } else if (servletResolver == null) {
+                throw new UnavailableException("ServletResolver");
+            }
+
+            // initialize the request data - resolve resource and servlet
+            Resource resource = requestData.initResource(resourceResolver);
+            requestData.initServlet(resource);
+
+            Filter[] filters = filterManager.getFilters(FilterChainType.REQUEST);
+            if (filters != null) {
+                FilterChain processor = new RequestSlingFilterChain(this,
+                    filters);
+
+                request.getRequestProgressTracker().log(
+                    "Applying request filters");
+
+                processor.doFilter(request, response);
+
+            } else {
+
+                // no filters, directly call resource level filters and servlet
+                processComponent(request, response, FilterChainType.COMPONENT);
+
+            }
+
+        } catch (ResourceNotFoundException rnfe) {
+
+            // send this exception as a 404 status
+            log.info("service: Resource {} not found", rnfe.getResource());
+
+            handleError(HttpServletResponse.SC_NOT_FOUND, rnfe.getMessage(),
+                request, response);
+
+        } catch (SlingException se) {
+
+            // if we have request data and a non-null active servlet name
+            // we assume, that this is the name of the causing servlet
+            if (requestData.getActiveServletName() != null) {
+                request.setAttribute(ERROR_SERVLET_NAME,
+                    requestData.getActiveServletName());
+            }
+
+            // send this exception as is (albeit unwrapping and wrapped
+            // exception.
+            Throwable t = (se.getCause() != null) ? se.getCause() : se;
+            log.error("service: Uncaught SlingException", t);
+            handleError(t, request, response);
+
+        } catch (AccessControlException ace) {
+
+            // SLING-319 if anything goes wrong, send 403/FORBIDDEN
+            log.info(
+                "service: Authenticated user {} does not have enough rights to executed requested action",
+                request.getRemoteUser());
+            handleError(HttpServletResponse.SC_FORBIDDEN, null, request,
+                response);
+
+        } catch (UnavailableException ue) {
+
+            final int status = HttpServletResponse.SC_SERVICE_UNAVAILABLE;
+            final String errorMessage = ue.getMessage()
+                + " service missing, cannot service requests";
+            log.error("{} , sending status {}", errorMessage, status);
+            handleError(status, errorMessage, request, response);
+
+        } catch (Throwable t) {
+
+            // if we have request data and a non-null active servlet name
+            // we assume, that this is the name of the causing servlet
+            if (requestData.getActiveServletName() != null) {
+                request.setAttribute(ERROR_SERVLET_NAME,
+                    requestData.getActiveServletName());
+            }
+
+            log.error("service: Uncaught Throwable", t);
+            handleError(t, request, response);
+
+        } finally {
+
+            // request exit log
+            if (requestLogger != null) {
+                requestLogger.logRequestExit(request, response);
+            }
+
+            // dispose any request data
+            requestData.dispose();
+        }
+    }
+
+    /**
+     * Renders the component defined by the RequestData's current ComponentData
+     * instance after calling all filters of the given
+     * {@link org.apache.sling.engine.impl.filter.ServletFilterManager.FilterChainType
+     * filterChainType}.
+     *
+     * @param request
+     * @param response
+     * @param filterChainType
+     * @throws IOException
+     * @throws ServletException
+     */
+
+    public void processComponent(SlingHttpServletRequest request,
+            SlingHttpServletResponse response,
+            final FilterChainType filterChainType) throws IOException,
+            ServletException {
+
+        Filter filters[] = filterManager.getFilters(filterChainType);
+        if (filters != null) {
+
+            FilterChain processor = new SlingComponentFilterChain(filters);
+            request.getRequestProgressTracker().log("Applying inner filters");
+            processor.doFilter(request, response);
+
+        } else {
+
+            log.debug("service: No Resource level filters, calling servlet");
+            RequestData.service(request, response);
+
+        }
+    }
+
+    // ---------- Generic Content Request processor ----------------------------
+
+    /**
+     * Dispatches the request on behalf of the
+     * {@link org.apache.sling.engine.impl.request.SlingRequestDispatcher}.
+     */
+    public void dispatchRequest(ServletRequest request,
+            ServletResponse response, Resource resource,
+            RequestPathInfo resolvedURL, boolean include) throws IOException,
+            ServletException {
+
+        // we need a SlingHttpServletRequest/SlingHttpServletResponse tupel
+        // to continue
+        SlingHttpServletRequest cRequest = RequestData.toSlingHttpServletRequest(request);
+        SlingHttpServletResponse cResponse = RequestData.toSlingHttpServletResponse(response);
+
+        // get the request data (and btw check the correct type)
+        RequestData requestData = RequestData.getRequestData(cRequest);
+        ContentData contentData = requestData.pushContent(resource, resolvedURL);
+
+        try {
+            // resolve the servlet
+            Servlet servlet = servletResolver.resolveServlet(cRequest);
+            contentData.setServlet(servlet);
+
+            FilterChainType type = include
+                    ? FilterChainType.INCLUDE
+                    : FilterChainType.FORWARD;
+
+            processComponent(cRequest, cResponse, type);
+        } finally {
+            requestData.popContent();
+        }
+    }
+
+    // ---------- Error Handling with Filters
+
+    void handleError(final int status, final String message,
+            final SlingHttpServletRequest request,
+            final SlingHttpServletResponse response) throws IOException {
+
+        Filter[] filters = filterManager.getFilters(FilterChainType.ERROR);
+        if (filters != null && filters.length > 0) {
+            FilterChain processor = new AbstractSlingFilterChain(filters) {
+
+                @Override
+                protected void render(SlingHttpServletRequest request,
+                        SlingHttpServletResponse response) throws IOException {
+                    errorHandler.handleError(status, message, request, response);
+                }
+            };
+            request.getRequestProgressTracker().log("Applying error filters");
+
+            try {
+                processor.doFilter(request, response);
+            } catch (ServletException se) {
+                throw new SlingServletException(se);
+            }
+        } else {
+            errorHandler.handleError(status, message, request, response);
+        }
+    }
+
+    // just rethrow the exception as explained in the class comment
+    private void handleError(final Throwable throwable,
+            final SlingHttpServletRequest request,
+            final SlingHttpServletResponse response) throws IOException {
+        Filter[] filters = filterManager.getFilters(FilterChainType.ERROR);
+        if (filters != null && filters.length > 0) {
+            FilterChain processor = new AbstractSlingFilterChain(filters) {
+
+                @Override
+                protected void render(SlingHttpServletRequest request,
+                        SlingHttpServletResponse response) throws IOException {
+                    errorHandler.handleError(throwable, request, response);
+                }
+            };
+            request.getRequestProgressTracker().log("Applying error filters");
+
+            try {
+                processor.doFilter(request, response);
+            } catch (ServletException se) {
+                throw new SlingServletException(se);
+            }
+        } else {
+            errorHandler.handleError(throwable, request, response);
+        }
+    }
+
+    public ServletResolver getServletResolver() {
+        return servletResolver;
+    }
+}

Propchange: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url