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


Reply via email to