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><sling:include></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><sling:forward></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