Author: fmeschbe
Date: Wed Dec 19 04:36:40 2007
New Revision: 605524
URL: http://svn.apache.org/viewvc?rev=605524&view=rev
Log:
SLING-141 Remove ServletResolver implementation from core module. At the
same time a new interface - ErrorHandler - is defined which is expected
to be implemented by an OSGi service. If no such service exists, a very
basic implementation is available as part of the SlingMainServlet.
Added:
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/servlets/AbstractServiceReferenceConfig.java
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/servlets/ErrorHandler.java
Removed:
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/helper/AbstractServiceReferenceConfig.java
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/helper/SlingServletConfig.java
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/servlets/
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/servlets/DefaultErrorHandlerServlet.java
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/servlets/DefaultServlet.java
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/servlets/ErrorHandlerServlet.java
Modified:
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/CoreConstants.java
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingHttpServletResponseImpl.java
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingMainServlet.java
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/helper/SlingFilterConfig.java
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/request/RequestData.java
Modified:
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/CoreConstants.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/CoreConstants.java?rev=605524&r1=605523&r2=605524&view=diff
==============================================================================
---
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/CoreConstants.java
(original)
+++
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/CoreConstants.java
Wed Dec 19 04:36:40 2007
@@ -74,22 +74,4 @@
* ignored.
*/
public static final String SLING_SERLVET_NAME = "sling.core.servletName";
-
- /**
- * The name of the service registration property of a Servlet registered as
- * a service containing the resource type(s) supported by the servlet
(value
- * is "sling.core.resourceTypes"). The type of this property is a String or
- * String[] (array of strings) denoting the resource types. If this
property
- * is missing or empty the Servlet is ignored.
- */
- public static final String SLING_RESOURCE_TYPES =
"sling.core.resourceTypes";
-
- /**
- * The name of the registered servlet used as the default servlet if no
- * other servlet or script could be selected (value is
- * "sling.core.servlet.default"). If no servlet is registered under this
- * name, the [EMAIL PROTECTED]
org.apache.sling.core.servlets.DefaultServlet} is used.
- */
- public static final String DEFAULT_SERVLET_NAME =
"sling.core.servlet.default";
-
}
Modified:
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingHttpServletResponseImpl.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingHttpServletResponseImpl.java?rev=605524&r1=605523&r2=605524&view=diff
==============================================================================
---
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingHttpServletResponseImpl.java
(original)
+++
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingHttpServletResponseImpl.java
Wed Dec 19 04:36:40 2007
@@ -30,7 +30,7 @@
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.core.RequestUtil;
import org.apache.sling.core.impl.request.RequestData;
-import org.apache.sling.core.impl.servlets.ErrorHandler;
+import org.apache.sling.core.servlets.ErrorHandler;
import org.apache.sling.jcr.resource.PathResolver;
/**
Modified:
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingMainServlet.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingMainServlet.java?rev=605524&r1=605523&r2=605524&view=diff
==============================================================================
---
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingMainServlet.java
(original)
+++
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingMainServlet.java
Wed Dec 19 04:36:40 2007
@@ -19,6 +19,7 @@
package org.apache.sling.core.impl;
import java.io.IOException;
+import java.io.PrintWriter;
import java.net.URL;
import java.security.AccessControlException;
import java.util.ArrayList;
@@ -53,14 +54,13 @@
import org.apache.sling.core.impl.filter.RequestSlingFilterChain;
import org.apache.sling.core.impl.filter.SlingComponentFilterChain;
import org.apache.sling.core.impl.filter.SlingFilterChainHelper;
-import org.apache.sling.core.impl.helper.AbstractServiceReferenceConfig;
import org.apache.sling.core.impl.helper.SlingFilterConfig;
import org.apache.sling.core.impl.helper.SlingServletContext;
import org.apache.sling.core.impl.request.ContentData;
import org.apache.sling.core.impl.request.RequestData;
import org.apache.sling.core.impl.services.ServiceLocatorImpl;
-import org.apache.sling.core.impl.servlets.ErrorHandler;
-import org.apache.sling.core.impl.servlets.SlingServletResolver;
+import org.apache.sling.core.servlets.AbstractServiceReferenceConfig;
+import org.apache.sling.core.servlets.ErrorHandler;
import org.apache.sling.jcr.resource.JcrResourceResolverFactory;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
@@ -83,7 +83,7 @@
* @scr.reference name="Filter" interface="javax.servlet.Filter"
* cardinality="0..n" policy="dynamic"
*/
-public class SlingMainServlet extends GenericServlet {
+public class SlingMainServlet extends GenericServlet implements ErrorHandler {
/** default log */
private static final Logger log =
LoggerFactory.getLogger(SlingMainServlet.class);
@@ -126,6 +126,12 @@
/** @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;
+
private SlingFilterChainHelper requestFilterChain = new
SlingFilterChainHelper();
private SlingFilterChainHelper innerFilterChain = new
SlingFilterChainHelper();
@@ -136,10 +142,6 @@
private SlingAuthenticator slingAuthenticator;
- private SlingServletResolver servletResolver;
-
- private ErrorHandler errorHandler;
-
// ---------- Servlet API -------------------------------------------------
public void service(ServletRequest req, ServletResponse res)
@@ -158,7 +160,7 @@
// ---------- Request Handling on behalf of the servlet -------------------
public void service(HttpServletRequest clientRequest,
- HttpServletResponse clientResponse) throws IOException {
+ HttpServletResponse clientResponse) throws ServletException,
IOException {
Session session = (Session)
clientRequest.getAttribute(SlingHttpContext.SESSION);
if (session != null) {
@@ -269,10 +271,94 @@
} else {
log.debug("service: No Resource level filters, calling servlet");
Servlet servlet =
RequestData.getRequestData(request).getContentData().getServlet();
- servlet.service(request, response);
+ if (servlet != null) {
+ servlet.service(request, response);
+ } else {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND,
+ "No Servlet or Script to handle request to "
+ + request.getResource().getURI());
+ }
}
}
+ // ---------- ErrorHandler interface (default implementation)
--------------
+
+ // reset the response, set the status and write a simple message
+ public void handleError(int status, String message,
+ HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+
+ if (message == null) {
+ message = String.valueOf(status);
+ } else {
+ message = status + " - " + message;
+ }
+
+ if (response.isCommitted()) {
+ log.error("handleError: Response already committed; cannot send
error "
+ + status + message);
+ } else {
+
+ // 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(message);
+ pw.println("</title></head><body><h1>");
+ pw.println("HTTP ERROR:" + message);
+ pw.println("</h1><p>");
+ pw.println("RequestURI=" + request.getRequestURI());
+ pw.println("</p><hr /><address>");
+ pw.println(getServerInfo());
+ pw.println("</address></body></html>");
+
+ // commit the response
+ response.flushBuffer();
+
+ }
+ }
+
+ // just rethrow the exception as explained in the class comment
+ public void handleError(Throwable throwable, HttpServletRequest request,
+ HttpServletResponse response) throws IOException {
+
+ if (response.isCommitted()) {
+ log.error(
+ "handleError: Response already committed; cannot send error",
+ throwable);
+ } else {
+
+ // reset anything in the response first
+ response.reset();
+
+ // set the status, content type and encoding
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ response.setContentType("text/html; charset=UTF-8");
+
+ PrintWriter pw = response.getWriter();
+ pw.println("<html><head><title>");
+ pw.println(throwable.getMessage());
+ pw.println("</title></head><body><h1>");
+ pw.println(throwable.toString());
+ pw.println("</h1><p>");
+ pw.println("RequestURI=" + request.getRequestURI());
+ pw.println("</p><pre>");
+ throwable.printStackTrace(pw);
+ pw.println("</pre><hr /><address>");
+ pw.println(getServerInfo());
+ pw.println("</address></body></html>");
+
+ // commit the response
+ response.flushBuffer();
+
+ }
+ }
+
// ---------- Internal helper
----------------------------------------------
public String getServerInfo() {
@@ -300,7 +386,8 @@
}
public ErrorHandler getErrorHandler() {
- return errorHandler;
+ ErrorHandler eh = errorHandler;
+ return (eh != null) ? eh : this;
}
// ---------- Property Setter for SCR
--------------------------------------
@@ -349,9 +436,6 @@
SlingServletContext tmpServletContext = new SlingServletContext(this);
slingServiceLocator = new ServiceLocatorImpl(bundleContext);
slingAuthenticator = new SlingAuthenticator(bundleContext);
- servletResolver = new SlingServletResolver(bundleContext,
- tmpServletContext);
- errorHandler = new ErrorHandler(bundleContext, tmpServletContext);
// register the servlet and resources
try {
@@ -410,14 +494,6 @@
destroyFilters(innerFilterChain);
destroyFilters(requestFilterChain);
- if (errorHandler != null) {
- errorHandler.dispose();
- errorHandler = null;
- }
- if (servletResolver != null) {
- servletResolver.dispose();
- servletResolver = null;
- }
if (slingAuthenticator != null) {
slingAuthenticator.dispose();
slingAuthenticator = null;
Modified:
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/helper/SlingFilterConfig.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/helper/SlingFilterConfig.java?rev=605524&r1=605523&r2=605524&view=diff
==============================================================================
---
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/helper/SlingFilterConfig.java
(original)
+++
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/helper/SlingFilterConfig.java
Wed Dec 19 04:36:40 2007
@@ -21,9 +21,11 @@
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
+import org.apache.sling.core.servlets.AbstractServiceReferenceConfig;
import org.osgi.framework.ServiceReference;
-public class SlingFilterConfig extends AbstractServiceReferenceConfig
implements FilterConfig {
+public class SlingFilterConfig extends AbstractServiceReferenceConfig
implements
+ FilterConfig {
public SlingFilterConfig(ServletContext servletContext,
ServiceReference reference, String filterName) {
Modified:
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/request/RequestData.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/request/RequestData.java?rev=605524&r1=605523&r2=605524&view=diff
==============================================================================
---
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/request/RequestData.java
(original)
+++
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/request/RequestData.java
Wed Dec 19 04:36:40 2007
@@ -140,8 +140,10 @@
// finally resolve the servlet for the resource
ServletResolver sr = slingMainServlet.getServletResolver();
- Servlet servlet = sr.resolveServlet(slingRequest);
- contentData.setServlet(servlet);
+ if (sr != null) {
+ Servlet servlet = sr.resolveServlet(slingRequest);
+ contentData.setServlet(servlet);
+ }
}
public void dispose() {
Added:
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/servlets/AbstractServiceReferenceConfig.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/servlets/AbstractServiceReferenceConfig.java?rev=605524&view=auto
==============================================================================
---
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/servlets/AbstractServiceReferenceConfig.java
(added)
+++
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/servlets/AbstractServiceReferenceConfig.java
Wed Dec 19 04:36:40 2007
@@ -0,0 +1,127 @@
+/*
+ * 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.core.servlets;
+
+import static org.apache.sling.core.CoreConstants.SLING_SERLVET_NAME;
+import static org.osgi.framework.Constants.SERVICE_ID;
+import static org.osgi.framework.Constants.SERVICE_PID;
+import static org.osgi.service.component.ComponentConstants.COMPONENT_NAME;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
+import javax.servlet.ServletContext;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * The <code>AbstractServiceReferenceConfig</code> may be used as a base class
+ * to define <code>ServletConfig</code> and <code>FilterConfig</code>
+ * instances from OSGi <code>ServiceReference</code> objects. The properties
+ * of this service reference are used as the initialization parameters of the
+ * configuration object.
+ * <p>
+ * The name of the servlet or filter may be retrieved from the service
reference
+ * by calling the static [EMAIL PROTECTED] #getName(ServiceReference)} method.
This method
+ * looks for the following service reference properties, assuming the first
non-<code>null</code>
+ * value found:
+ * <ol>
+ * <li><em>sling.core.servletName</em> - A service registration property
+ * which may be set to define an independent servlet name.
+ * <li><em>component.name</em> - The name of the Declarative Services
+ * component if the OSGi service is registered using Declarative Services.
+ * <li><em>service.pid</em> - The Service PID of the service.
+ * <li><em>service.id</em> - The ID of the service as set by the OSGi
+ * framework service registry. This property is guaranteed to always be set by
+ * the OSGi specification.
+ * </ol>
+ */
+public abstract class AbstractServiceReferenceConfig {
+
+ /** The list of property names checked by [EMAIL PROTECTED]
#getName(ServiceReference)} */
+ private static final String[] NAME_PROPERTIES = { SLING_SERLVET_NAME,
+ COMPONENT_NAME, SERVICE_PID, SERVICE_ID };
+
+ /** The <code>ServletContext</code> of this configuration object */
+ private ServletContext servletContext;
+
+ /** The <code>ServiceReference</code> providing the properties */
+ private ServiceReference reference;
+
+ /** The name of this configuration object */
+ private String name;
+
+ /**
+ * Sets up this base configuration object.
+ *
+ * @param servletContext The <code>ServletContext</code> attached to this
+ * configuration.
+ * @param reference The service reference providing the initialization
+ * parameter values.
+ * @param name The name of this configuration.
+ * @see #getName()
+ */
+ public AbstractServiceReferenceConfig(ServletContext servletContext,
+ ServiceReference reference, String name) {
+ this.servletContext = servletContext;
+ this.reference = reference;
+ this.name = name;
+ }
+
+ public String getInitParameter(String name) {
+ Object prop = reference.getProperty(name);
+ return (prop == null) ? null : String.valueOf(prop);
+ }
+
+ public Enumeration<?> getInitParameterNames() {
+ List<?> keys = Arrays.asList(reference.getPropertyKeys());
+ return Collections.enumeration(keys);
+ }
+
+ public ServletContext getServletContext() {
+ return servletContext;
+ }
+
+ /**
+ * Returns the name of this configuration object. Implementations may use
+ * this value to implement the <code>ServletConfig.getServletName()</code>
+ * or <code>FilterConfig.getFilterName()</code> methods.
+ */
+ protected String getName() {
+ return name;
+ }
+
+ /**
+ * Looks for a name value in the service reference properties. See the
+ * class comment at the top for the list of properties checked by this
+ * method.
+ */
+ public static String getName(ServiceReference reference) {
+ String servletName = null;
+ for (int i = 0; i < NAME_PROPERTIES.length
+ && (servletName == null || servletName.length() == 0); i++) {
+ servletName = (String) reference.getProperty(NAME_PROPERTIES[i]);
+ }
+ return servletName;
+ }
+
+}
Added:
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/servlets/ErrorHandler.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/servlets/ErrorHandler.java?rev=605524&view=auto
==============================================================================
---
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/servlets/ErrorHandler.java
(added)
+++
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/servlets/ErrorHandler.java
Wed Dec 19 04:36:40 2007
@@ -0,0 +1,72 @@
+/*
+ * 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.core.servlets;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+/**
+ * The <code>ErrorHandler</code> defines the interface of the service used by
+ * the Sling to handle calls to <code>HttpServletResponse.sendError</code> and
+ * to handle uncaught <code>Throwable</code>s.
+ */
+public interface ErrorHandler {
+
+ /**
+ * Called to render a response for a HTTP status code. This method should
+ * set the response status and print the status code and optional message.
+ * <p>
+ * If the response has already been committed, an error message should be
+ * logged but no further processing should take place.
+ *
+ * @param status The HTTP status code to set
+ * @param message An optional message to write to the response. This
message
+ * may be <code>null</code>.
+ * @param request The request object providing more information on the
+ * request.
+ * @param response The response object used to send the status and message.
+ * @throws IOException May be thrown if an error occurrs sending the
+ * response.
+ */
+ void handleError(int status, String message, HttpServletRequest request,
+ HttpServletResponse response) throws IOException;
+
+ /**
+ * Called to render a response for an uncaught <code>Throwable</code>.
+ * <p>
+ * If the response has already been committed, an error message should be
+ * logged but no further processing should take place.
+ *
+ * @param throwable The <code>Throwable</code> causing this method to be
+ * called.
+ * @param request The request object providing more information on the
+ * request.
+ * @param response The response object used to send the status and message.
+ * @throws ServletException May be thrown if any processing error occurrs.
+ * @throws IOException May be thrown if an error occurrs sending the
+ * response.
+ */
+ void handleError(Throwable throwable, HttpServletRequest request,
+ HttpServletResponse response) throws ServletException, IOException;
+
+}
\ No newline at end of file