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 2007/12/19 17:42:55 UTC

svn commit: r605610 - in /incubator/sling/trunk/sling/servlet-resolver: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/sling/ src/main/java/org/apache/sling/servlet/ src/main/java/org/apache/sling...

Author: fmeschbe
Date: Wed Dec 19 08:42:53 2007
New Revision: 605610

URL: http://svn.apache.org/viewvc?rev=605610&view=rev
Log:
SLING-141 Create servlet-resolver project

Added:
    incubator/sling/trunk/sling/servlet-resolver/   (with props)
    incubator/sling/trunk/sling/servlet-resolver/pom.xml   (with props)
    incubator/sling/trunk/sling/servlet-resolver/src/
    incubator/sling/trunk/sling/servlet-resolver/src/main/
    incubator/sling/trunk/sling/servlet-resolver/src/main/java/
    incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/
    incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/
    incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/
    incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/
    incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/
    incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/ServletResolverConstants.java   (with props)
    incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/SlingServletResolver.java   (with props)
    incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/defaults/
    incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/defaults/DefaultErrorHandlerServlet.java   (with props)
    incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/defaults/DefaultServlet.java   (with props)
    incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/
    incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/ErrorSlingHttpServletRequest.java   (with props)
    incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/SlingScriptServlet.java   (with props)
    incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/SlingServletConfig.java   (with props)
    incubator/sling/trunk/sling/servlet-resolver/src/main/resources/
    incubator/sling/trunk/sling/servlet-resolver/src/main/resources/META-INF/
    incubator/sling/trunk/sling/servlet-resolver/src/main/resources/META-INF/LICENSE
    incubator/sling/trunk/sling/servlet-resolver/src/main/resources/META-INF/NOTICE

Propchange: incubator/sling/trunk/sling/servlet-resolver/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Wed Dec 19 08:42:53 2007
@@ -0,0 +1,3 @@
+.classpath
+.project
+target

Added: incubator/sling/trunk/sling/servlet-resolver/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlet-resolver/pom.xml?rev=605610&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlet-resolver/pom.xml (added)
+++ incubator/sling/trunk/sling/servlet-resolver/pom.xml Wed Dec 19 08:42:53 2007
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>1-incubator-SNAPSHOT</version>
+        <relativePath>../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.sling.servlet.resolver</artifactId>
+    <packaging>bundle</packaging>
+    <version>2.0.0-incubator-SNAPSHOT</version>
+
+    <name>Sling - Sling ServletResolver</name>
+    <description>
+        Bundle implementing the Sling API ServletResolver.
+    </description>
+
+    <scm>
+        <connection>
+            scm:svn:http://svn.apache.org/repos/asf/incubator/sling/trunk/sling/servlet-resolver
+        </connection>
+        <developerConnection>
+            scm:svn:https://svn.apache.org/repos/asf/incubator/sling/trunk/sling/servlet-resolver
+        </developerConnection>
+        <url>
+            http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlet-resolver
+        </url>
+    </scm>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.sling</groupId>
+                <artifactId>maven-jcrocm-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Private-Package>
+                            org.apache.sling.servlet.resolver.*
+                        </Private-Package>
+                        <Import-Package>
+                            javax.servlet , javax.servlet.http ,
+                            org.apache.commons.beanutils,
+                            org.apache.sling.api,
+                            org.apache.sling.api.request,
+                            org.apache.sling.api.resource,
+                            org.apache.sling.api.scripting,
+                            org.apache.sling.api.services,
+                            org.apache.sling.api.servlets,
+                            org.apache.sling.core.servlets,
+                            org.osgi.framework,
+                            org.osgi.service.component, org.slf4j
+                        </Import-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>2.0.0-incubator-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.core</artifactId>
+            <version>2.0.0-incubator-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-beanutils</groupId>
+            <artifactId>commons-beanutils</artifactId>
+            <version>1.7.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi_R4_core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi_R4_compendium</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+    </dependencies>
+</project>

Propchange: incubator/sling/trunk/sling/servlet-resolver/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/ServletResolverConstants.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/ServletResolverConstants.java?rev=605610&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/ServletResolverConstants.java (added)
+++ incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/ServletResolverConstants.java Wed Dec 19 08:42:53 2007
@@ -0,0 +1,40 @@
+/*
+ * 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.servlet.resolver;
+
+public class ServletResolverConstants {
+
+    /**
+     * 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 {@link org.apache.sling.core.servlets.DefaultServlet} is used.
+     */
+    public static final String DEFAULT_SERVLET_NAME = "sling.core.servlet.default";
+
+}

Propchange: incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/ServletResolverConstants.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/SlingServletResolver.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/SlingServletResolver.java?rev=605610&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/SlingServletResolver.java (added)
+++ incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/SlingServletResolver.java Wed Dec 19 08:42:53 2007
@@ -0,0 +1,526 @@
+/*
+ * 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.servlet.resolver;
+
+import static org.apache.sling.api.SlingConstants.ERROR_MESSAGE;
+import static org.apache.sling.api.SlingConstants.ERROR_REQUEST_URI;
+import static org.apache.sling.api.SlingConstants.ERROR_SERVLET_NAME;
+import static org.apache.sling.api.SlingConstants.ERROR_STATUS;
+import static org.apache.sling.core.CoreConstants.SLING_CURRENT_SERVLET_NAME;
+import static org.apache.sling.servlet.resolver.ServletResolverConstants.DEFAULT_SERVLET_NAME;
+import static org.apache.sling.servlet.resolver.ServletResolverConstants.SLING_RESOURCE_TYPES;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.api.SlingConstants;
+import org.apache.sling.api.SlingException;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.scripting.SlingScript;
+import org.apache.sling.api.scripting.SlingScriptResolver;
+import org.apache.sling.api.servlets.ServletResolver;
+import org.apache.sling.core.CoreConstants;
+import org.apache.sling.core.servlets.AbstractServiceReferenceConfig;
+import org.apache.sling.core.servlets.ErrorHandler;
+import org.apache.sling.servlet.resolver.defaults.DefaultErrorHandlerServlet;
+import org.apache.sling.servlet.resolver.defaults.DefaultServlet;
+import org.apache.sling.servlet.resolver.helper.ErrorSlingHttpServletRequest;
+import org.apache.sling.servlet.resolver.helper.SlingScriptServlet;
+import org.apache.sling.servlet.resolver.helper.SlingServletConfig;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>SlingServletResolver</code> TODO
+ * 
+ * @scr.component label="%servletresolver.name"
+ *                description="%servletresolver.description"
+ * @scr.property name="service.description" value="Sling Servlet Resolver and
+ *               Error Handler"
+ * @scr.property name="service.vendor" value="The Apache Software Foundation"
+ * @scr.service
+ * @scr.reference name="Servlet" interface="javax.servlet.Servlet"
+ *                cardinality="0..n" policy="dynamic"
+ */
+public class SlingServletResolver implements ServletResolver, ErrorHandler {
+
+    /** default log */
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    /**
+     * @scr.property values.1="/apps/components" values.2="/libs/components"
+     *               label="%resolver.path.name"
+     *               description="%resolver.path.description"
+     */
+    public static final String PROP_PATH = "path";
+
+    private static final String REF_SERVLET = "Servlet";
+
+    /** @scr.reference cardinality="0..1" policy="dynamic" */
+    private SlingScriptResolver scriptResolver;
+
+    /** @scr.reference */
+    private ServletContext servletContext;
+
+    private Map<String, Servlet> servlets = new HashMap<String, Servlet>();
+
+    private Map<ServiceReference, Servlet> servletsByReference = new HashMap<ServiceReference, Servlet>();
+
+    private List<ServiceReference> pendingServlets = new ArrayList<ServiceReference>();
+
+    private ComponentContext context;
+
+    private String[] path;
+
+    private Servlet coreDefaultServlet;
+
+    private Servlet defaultErrorServlet;
+
+    // ---------- ServletResolver interface -----------------------------------
+
+    public Servlet resolveServlet(SlingHttpServletRequest request) {
+
+        // resolve a servlet or script based on the request
+        Servlet servlet = resolveServletOrScript(request);
+
+        // use default servlet, create one if missing
+        if (servlet == null) {
+            servlet = getServlet(DEFAULT_SERVLET_NAME);
+        }
+
+        // last resort, use the core bundle default servlet
+        if (servlet == null) {
+            servlet = getCoreDefaultServlet();
+        }
+
+        if (servlet != null && log.isDebugEnabled()) {
+            String name;
+            if (servlet.getServletConfig() != null) {
+                name = servlet.getServletConfig().getServletName();
+            } else {
+                name = servlet.getServletInfo();
+            }
+            if (name == null) {
+                name = servlet.getClass().getName();
+            }
+            log.debug("Using Servlet {} for {}", name, path);
+        }
+
+        return servlet;
+    }
+
+    // ---------- ErrorHandler interface --------------------------------------
+
+    public void handleError(int status, String message,
+            HttpServletRequest request, HttpServletResponse response)
+            throws IOException {
+
+        // do not handle, if already handling ....
+        if (request.getAttribute(ERROR_REQUEST_URI) == null) {
+
+            // find the error handler component
+            ErrorSlingHttpServletRequest eRequest = new ErrorSlingHttpServletRequest(
+                request, String.valueOf(status));
+            Servlet servlet = resolveServletOrScript(eRequest);
+
+            if (servlet == null) {
+                servlet = getDefaultErrorServlet();
+            }
+
+            // set the message properties
+            request.setAttribute(ERROR_STATUS, new Integer(
+                status));
+            request.setAttribute(ERROR_MESSAGE, message);
+            
+            // the servlet name for a sendError handling is still stored
+            // as the request attribute
+            Object servletName = request.getAttribute(SLING_CURRENT_SERVLET_NAME);
+            if (servletName instanceof String) {
+                request.setAttribute(ERROR_SERVLET_NAME, servletName);
+            }
+
+            if (handleError(servlet, request, response)) {
+                return;
+            }
+        }
+
+        // get here, if we have no handler, let the status go up the chain
+        // and if this causes and exception, so what ...
+        response.sendError(status, message);
+    }
+
+    public void handleError(Throwable throwable, HttpServletRequest request,
+            HttpServletResponse response) throws ServletException, IOException {
+
+        // do not handle, if already handling ....
+        if (request.getAttribute(SlingConstants.ERROR_REQUEST_URI) == null) {
+
+            // find the error handler component
+            Servlet servlet = null;
+            Class<?> tClass = throwable.getClass();
+            ErrorSlingHttpServletRequest eRequest = new ErrorSlingHttpServletRequest(
+                request, "");
+            while (servlet == null && tClass != Object.class) {
+                eRequest.setMethod(tClass.getSimpleName());
+                servlet = resolveServletOrScript(eRequest);
+
+                // go to the base class
+                tClass = tClass.getSuperclass();
+            }
+
+            if (servlet == null) {
+                servlet = getDefaultErrorServlet();
+            }
+
+            // set the message properties
+            request.setAttribute(SlingConstants.ERROR_EXCEPTION, throwable);
+            request.setAttribute(SlingConstants.ERROR_EXCEPTION_TYPE,
+                throwable.getClass());
+            request.setAttribute(SlingConstants.ERROR_MESSAGE,
+                throwable.getMessage());
+
+            if (handleError(servlet, request, response)) {
+                return;
+            }
+        }
+
+        // get here, if we have no handler, let the throwable go up the chain
+        if (throwable instanceof IOException) {
+            throw (IOException) throwable;
+        } else if (throwable instanceof ServletException) {
+            throw (ServletException) throwable;
+        } else if (throwable instanceof RuntimeException) {
+            throw (RuntimeException) throwable;
+        } else {
+            throw new ServletException(throwable);
+        }
+    }
+
+    // ---------- internal helper ---------------------------------------------
+
+    Servlet resolveServletOrScript(SlingHttpServletRequest request) {
+
+        // get the servlet by resource type
+        Servlet servlet = getServlet(request.getResource().getResourceType());
+        if (servlet != null) {
+            return servlet;
+        }
+
+        // no typed servlet, so lets try scripting
+        try {
+            servlet = getScriptServlet(request);
+            if (servlet != null) {
+                return servlet;
+            }
+        } catch (SlingException se) {
+            log.error("resolveServlet: Error trying to find script", se);
+        }
+
+        // no script either
+        return null;
+    }
+
+    private Servlet getScriptServlet(SlingHttpServletRequest request)
+            throws SlingException {
+        SlingScriptResolver ssr = scriptResolver;
+        if (ssr != null) {
+            SlingScript script = ssr.resolveScript(request);
+            if (script != null) {
+                return new SlingScriptServlet(script);
+            }
+        }
+
+        return null;
+    }
+
+    private Servlet getCoreDefaultServlet() {
+        if (coreDefaultServlet == null) {
+            try {
+                Servlet servlet = new DefaultServlet();
+                servlet.init(new SlingServletConfig(servletContext, null,
+                    "Sling Core Default Servlet"));
+                coreDefaultServlet = servlet;
+            } catch (ServletException se) {
+                log.error("Failed to initiliaze Servlet", se);
+            }
+        }
+
+        return coreDefaultServlet;
+    }
+
+    private Servlet getDefaultErrorServlet() {
+        if (defaultErrorServlet == null) {
+            try {
+                Servlet servlet = new DefaultErrorHandlerServlet();
+                servlet.init(new SlingServletConfig(servletContext, null,
+                    "Sling Default Error Handler Servlet"));
+                defaultErrorServlet = servlet;
+            } catch (ServletException se) {
+                log.error("Failed to initiliaze Servlet", se);
+            }
+        }
+
+        return defaultErrorServlet;
+    }
+
+    private boolean handleError(Servlet errorHandler,
+            HttpServletRequest request, HttpServletResponse response) {
+
+        request.setAttribute(SlingConstants.ERROR_REQUEST_URI,
+            request.getRequestURI());
+
+        // if there is no explicitly known error causing servlet, use
+        // the name of the error handler servlet
+        if (request.getAttribute(SlingConstants.ERROR_SERVLET_NAME) == null) {
+            request.setAttribute(SlingConstants.ERROR_SERVLET_NAME,
+                errorHandler.getServletConfig().getServletName());
+        }
+
+        // find a component by
+        try {
+            errorHandler.service(request, response);
+            return true;
+        } catch (Throwable t) {
+            log.error("Cannot handle error", t);
+        }
+
+        return false;
+    }
+
+    // ---------- SCR Integration ----------------------------------------------
+
+    protected void activate(ComponentContext context) {
+
+        this.context = context;
+
+        // empty path to begin with
+        path = null;
+
+        // from configuration if available
+        Dictionary<?, ?> properties = context.getProperties();
+        if (properties != null) {
+            Object pathObject = properties.get(PROP_PATH);
+            if (pathObject instanceof String[]) {
+                this.path = (String[]) pathObject;
+                for (int i = 0; i < this.path.length; i++) {
+                    // ensure leading slash
+                    if (!this.path[i].startsWith("/")) {
+                        this.path[i] = "/" + this.path[i];
+                    }
+                    // ensure trailing slash
+                    if (!this.path[i].endsWith("/")) {
+                        this.path[i] += "/";
+                    }
+                }
+            }
+        }
+    }
+
+    protected synchronized void bindServlet(ServiceReference reference) {
+        if (servletContext == null) {
+            pendingServlets.add(reference);
+        } else {
+            createServlet(servletContext, reference);
+        }
+    }
+
+    protected synchronized void unbindServlet(ServiceReference reference) {
+        if (servletContext == null) {
+            pendingServlets.remove(reference);
+        } else {
+            destroyServlet(reference);
+        }
+    }
+
+    protected void bindServletContext(ServletContext newServletContext) {
+
+        boolean destroy;
+        Collection<ServiceReference> refs;
+        
+        synchronized (this) {
+            
+            if (this.servletContext == null) {
+                
+                refs = pendingServlets;
+                pendingServlets = new ArrayList<ServiceReference>();
+                destroy = false;
+                
+            } else {
+                
+                refs = new ArrayList<ServiceReference>(servletsByReference.keySet());
+                destroy = true;
+                
+            }
+
+            this.servletContext = newServletContext;
+        }
+
+        if (destroy) {
+            destroyAllServlets(refs);
+        }
+
+        createAllServlets(this.servletContext, refs);
+    }
+
+    protected void unbindServletContext(ServletContext oldServletContext) {
+
+        if (this.servletContext == oldServletContext) {
+
+            Collection<ServiceReference> refs;
+            synchronized (this) {
+                refs = new ArrayList<ServiceReference>(servletsByReference.keySet());
+                pendingServlets.addAll(refs);
+                this.servletContext = null;
+            }
+
+            // destroy all servlets
+            destroyAllServlets(refs);
+        }
+    }
+
+    // ---------- Servlet Management -------------------------------------------
+
+    private void createAllServlets(ServletContext servletContext,
+            Collection<ServiceReference> pendingServlets) {
+        for (ServiceReference serviceReference : pendingServlets) {
+            createServlet(servletContext, serviceReference);
+        }
+    }
+
+    private boolean createServlet(ServletContext servletContext,
+            ServiceReference reference) {
+        Object typeObject = reference.getProperty(SLING_RESOURCE_TYPES);
+        if (typeObject == null) {
+            log.info(
+                "bindServlet: Ignoring Servlet service {} without resource types",
+                reference.getProperty(Constants.SERVICE_ID));
+            return false;
+        }
+
+        // super:addingService
+        String name = AbstractServiceReferenceConfig.getName(reference);
+        if (name == null) {
+            log.error(
+                "bindServlet: Cannot register servlet {} without a servlet name",
+                reference);
+            return false;
+        }
+
+        Servlet servlet = (Servlet) context.locateService(REF_SERVLET,
+            reference);
+        if (servlet == null) {
+            log.error(
+                "bindServlet: Servlet service not available from reference {}",
+                reference);
+            return false;
+        }
+
+        try {
+            servlet.init(new SlingServletConfig(servletContext, reference, name));
+            log.debug("bindServlet: Servlet {} added", name);
+        } catch (ServletException ce) {
+            log.error("bindServlet: Component " + name
+                + " failed to initialize", ce);
+            return false;
+        } catch (Throwable t) {
+            log.error("bindServlet: Unexpected problem initializing component "
+                + name, t);
+            return false;
+        }
+
+        if (typeObject instanceof String[]) {
+            String[] types = (String[]) typeObject;
+            for (String type : types) {
+                log.debug("bindServlet: Servlet {} handles type {}", name, type);
+                putServlet(type, servlet);
+            }
+        } else {
+            log.debug("bindServlet: Servlet {} handles type {}", name,
+                typeObject);
+            putServlet(typeObject.toString(), servlet);
+        }
+
+        servletsByReference.put(reference, servlet);
+
+        return true;
+    }
+
+    private void destroyAllServlets(Collection<ServiceReference> refs) {
+        for (ServiceReference serviceReference : refs) {
+            destroyServlet(serviceReference);
+        }
+    }
+
+    private void destroyServlet(ServiceReference reference) {
+        Servlet servlet = servletsByReference.remove(reference);
+        if (servlet != null) {
+            String name = servlet.getServletConfig().getServletName();
+            log.debug("unbindServlet: Servlet {} removed", name);
+
+            Object typeObject = reference.getProperty(SLING_RESOURCE_TYPES);
+            if (typeObject instanceof String[]) {
+                String[] types = (String[]) typeObject;
+                for (String type : types) {
+                    log.debug("unbindServlet: Servlet {} unregistered for  {}",
+                        name, type);
+                    removeServlet(type);
+                }
+            } else {
+                log.debug("unbindServlet: Servlet {} unregistered for {}",
+                    name, typeObject);
+                removeServlet((String) typeObject);
+            }
+
+            try {
+                servlet.destroy();
+            } catch (Throwable t) {
+                log.error(
+                    "unbindServlet: Unexpected problem destroying servlet "
+                        + name, t);
+            }
+        }
+    }
+
+    private void putServlet(String resourceType, Servlet servlet) {
+        servlets.put(resourceType, servlet);
+    }
+
+    private Servlet getServlet(String resourceType) {
+        return servlets.get(resourceType);
+    }
+
+    private void removeServlet(String resourceType) {
+        servlets.remove(resourceType);
+    }
+
+}

Propchange: incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/SlingServletResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/defaults/DefaultErrorHandlerServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/defaults/DefaultErrorHandlerServlet.java?rev=605610&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/defaults/DefaultErrorHandlerServlet.java (added)
+++ incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/defaults/DefaultErrorHandlerServlet.java Wed Dec 19 08:42:53 2007
@@ -0,0 +1,248 @@
+/*
+ * 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.servlet.resolver.defaults;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.GenericServlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.api.SlingConstants;
+
+/**
+ * The <code>DefaultErrorHandlerServlet</code> TODO
+ */
+public class DefaultErrorHandlerServlet extends GenericServlet {
+
+    @Override
+    public void service(ServletRequest req, ServletResponse res)
+            throws IOException {
+
+        // get settings
+        Integer scObject = (Integer) req.getAttribute(SlingConstants.ERROR_STATUS);
+        String statusMessage = (String) req.getAttribute(SlingConstants.ERROR_MESSAGE);
+        String requestUri = (String) req.getAttribute(SlingConstants.ERROR_REQUEST_URI);
+        String servletName = (String) req.getAttribute(SlingConstants.ERROR_SERVLET_NAME);
+
+        // ensure values
+        int statusCode = (scObject != null)
+                ? scObject.intValue()
+                : HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
+        if (statusMessage == null) {
+            statusMessage = statusToString(statusCode);
+        }
+
+        // start the response message
+        PrintWriter pw = sendIntro((HttpServletResponse) res, statusCode,
+            statusMessage, requestUri, servletName);
+
+        // write the exception message
+        if (req.getAttribute(SlingConstants.ERROR_EXCEPTION) instanceof Throwable) {
+            Throwable throwable = (Throwable) req.getAttribute(SlingConstants.ERROR_EXCEPTION);
+            pw.println("<h3>Exception:</h3>");
+            pw.println("<pre>");
+            printStackTrace(pw, throwable);
+            pw.println("</pre>");
+        }
+
+        // conclude the response message
+        sendEpilogue(pw);
+    }
+
+    /**
+     * Returns the stack trace for the root exception in this. If this does not
+     * contain exception - as is the case if not handling a thrown exception,
+     * the method returned the undefined value.
+     *
+     * @return The stacktrace for the rootException or the undefined value if
+     *         this has no rootException, that is if not handling a thrown
+     *         exception.
+     */
+    private void printStackTrace(PrintWriter pw, Throwable t) {
+        // nothing to do, if there is no exception
+        if (t == null) {
+            return;
+        }
+
+        // unpack a servlet exception
+        if (t instanceof ServletException) {
+            ServletException se = (ServletException) t;
+            while (se.getRootCause() != null) {
+                t = se.getRootCause();
+                if (t instanceof ServletException) {
+                    se = (ServletException) t;
+                } else {
+                    break;
+                }
+            }
+        }
+
+        // dump stack, including causes
+        t.printStackTrace(pw);
+    }
+
+    /**
+     * Sets the response status and content type header and starts the the
+     * response HTML text with the header, and an introductory phrase.
+     */
+    private PrintWriter sendIntro(HttpServletResponse response, int statusCode,
+            String statusMessage, String requestUri, String servletName)
+            throws IOException {
+
+        // set the status code and content type in the response
+        response.setStatus(statusCode);
+        response.setContentType("text/html; charset=UTF-8");
+
+        PrintWriter pw = response.getWriter();
+        pw.println("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">");
+        pw.println("<html>");
+        pw.println("<head>");
+        pw.println("<title>" + statusCode + " " + statusMessage + "</title>");
+        pw.println("</head>");
+        pw.println("<body>");
+        pw.println("<h1>" + statusMessage + " (" + statusCode + ")</h1>");
+        pw.print("<p>The requested URL " + requestUri
+            + " resulted in an error");
+        
+        if (servletName != null) {
+            pw.print(" in " + servletName);
+        }
+        
+        pw.println(".</p>");
+
+        return pw;
+    }
+
+    /**
+     * Ends the response sending with an apache-style server line and closes the
+     * body and html tags of the HTML response text.
+     */
+    private void sendEpilogue(PrintWriter pw) {
+        pw.println("<hr>");
+        pw.println("<address>" + getServletContext().getServerInfo()
+            + "</address>");
+        pw.println("</body>");
+        pw.println("</html>");
+    }
+
+    public static String statusToString(int statusCode) {
+        switch (statusCode) {
+            case 100:
+                return "Continue";
+            case 101:
+                return "Switching Protocols";
+            case 102:
+                return "Processing (WebDAV)";
+            case 200:
+                return "OK";
+            case 201:
+                return "Created";
+            case 202:
+                return "Accepted";
+            case 203:
+                return "Non-Authoritative Information";
+            case 204:
+                return "No Content";
+            case 205:
+                return "Reset Content";
+            case 206:
+                return "Partial Content";
+            case 207:
+                return "Multi-Status (WebDAV)";
+            case 300:
+                return "Multiple Choices";
+            case 301:
+                return "Moved Permanently";
+            case 302:
+                return "Found";
+            case 303:
+                return "See Other";
+            case 304:
+                return "Not Modified";
+            case 305:
+                return "Use Proxy";
+            case 307:
+                return "Temporary Redirect";
+            case 400:
+                return "Bad Request";
+            case 401:
+                return "Unauthorized";
+            case 402:
+                return "Payment Required";
+            case 403:
+                return "Forbidden";
+            case 404:
+                return "Not Found";
+            case 405:
+                return "Method Not Allowed";
+            case 406:
+                return "Not Acceptable";
+            case 407:
+                return "Proxy Authentication Required";
+            case 408:
+                return "Request Time-out";
+            case 409:
+                return "Conflict";
+            case 410:
+                return "Gone";
+            case 411:
+                return "Length Required";
+            case 412:
+                return "Precondition Failed";
+            case 413:
+                return "Request Entity Too Large";
+            case 414:
+                return "Request-URI Too Large";
+            case 415:
+                return "Unsupported Media Type";
+            case 416:
+                return "Requested range not satisfiable";
+            case 417:
+                return "Expectation Failed";
+            case 422:
+                return "Unprocessable Entity (WebDAV)";
+            case 423:
+                return "Locked (WebDAV)";
+            case 424:
+                return "Failed Dependency (WebDAV)";
+            case 500:
+                return "Internal Server Error";
+            case 501:
+                return "Not Implemented";
+            case 502:
+                return "Bad Gateway";
+            case 503:
+                return "Service Unavailable";
+            case 504:
+                return "Gateway Time-out";
+            case 505:
+                return "HTTP Version not supported";
+            case 507:
+                return "Insufficient Storage (WebDAV)";
+            case 510:
+                return "Not Extended";
+            default:
+                return String.valueOf(statusCode);
+        }
+    }
+}

Propchange: incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/defaults/DefaultErrorHandlerServlet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/defaults/DefaultServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/defaults/DefaultServlet.java?rev=605610&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/defaults/DefaultServlet.java (added)
+++ incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/defaults/DefaultServlet.java Wed Dec 19 08:42:53 2007
@@ -0,0 +1,238 @@
+/*
+ * 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.servlet.resolver.defaults;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.TreeMap;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.beanutils.BeanMap;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.api.resource.NonExistingResource;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
+
+/**
+ * The <code>DefaultServlet</code> is a very simple default resource handler.
+ * <p>
+ * The default servlet is not registered to handle any concrete resource
+ * type. Rather it is used internally on demand.
+ *
+ */
+public class DefaultServlet extends SlingSafeMethodsServlet {
+
+    @Override
+    protected void doGet(SlingHttpServletRequest request,
+            SlingHttpServletResponse response) throws IOException {
+
+        Resource resource = request.getResource();
+
+        // cannot handle the request for missing resources
+        if (resource instanceof NonExistingResource) {
+            response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            return;
+        }
+
+        // format response according to extension (use Mime mapping instead)
+        String extension = request.getRequestPathInfo().getExtension();
+        if ("html".equals(extension) || "htm".equals(extension)) {
+            this.renderContentHtml(resource, response);
+        } else if ("xml".equals(extension)) {
+            this.renderContentXML(resource, response);
+        } else if ("properties".equals(extension)) {
+            this.renderContentProperties(resource, response);
+        } else if ("json".equals(extension)) {
+            this.renderContentJson(resource, response);
+        } else {
+            // default rendering as plain text
+            this.renderContentText(resource, response);
+        }
+    }
+
+    private void renderContentHtml(Resource resource,
+            SlingHttpServletResponse response) throws IOException {
+        Map<Object, Object> contentMap = new TreeMap<Object, Object>(
+            this.asMap(resource));
+
+        response.setContentType("text/html; charset=UTF-8");
+        PrintWriter pw = response.getWriter();
+
+        pw.println("<html><head><title>");
+        pw.println(resource.getURI());
+        pw.println("</title></head><body bgcolor='white' fgcolor='black'>");
+        pw.println("<h1>Contents of <code>" + resource.getURI()
+            + "</code></h1>");
+
+        pw.println("<table>");
+        pw.println("<tr><th>name</th><th>Value</th></tr>");
+
+        for (Map.Entry<Object, Object> entry : contentMap.entrySet()) {
+            pw.println("<tr><td>" + entry.getKey() + "</td><td>"
+                + entry.getValue() + "</td></tr>");
+        }
+
+        pw.println("</body></html>");
+    }
+
+    private void renderContentText(Resource resource,
+            SlingHttpServletResponse response) throws IOException {
+        Map<Object, Object> contentMap = new TreeMap<Object, Object>(
+            this.asMap(resource));
+
+        response.setContentType("text/plain; charset=UTF-8");
+        PrintWriter pw = response.getWriter();
+
+        pw.println("Contents of " + resource.getURI());
+        pw.println();
+
+        for (Map.Entry<Object, Object> entry : contentMap.entrySet()) {
+            pw.println(entry.getKey() + ": " + entry.getValue());
+        }
+    }
+
+    private void renderContentProperties(Resource resource,
+            SlingHttpServletResponse response) throws IOException {
+        Properties props = new Properties();
+
+        Map<Object, Object> contentMap = new TreeMap<Object, Object>(
+            this.asMap(resource));
+        for (Map.Entry<Object, Object> entry : contentMap.entrySet()) {
+            props.setProperty(String.valueOf(entry.getKey()),
+                String.valueOf(entry.getValue()));
+        }
+
+        response.setContentType("text/plain; charset=ISO-8859-1");
+
+        OutputStream out = response.getOutputStream();
+        props.store(out, "Contents of " + resource.getURI());
+    }
+
+    private void renderContentXML(Resource resource,
+            SlingHttpServletResponse response) throws IOException {
+        Map<Object, Object> contentMap = new TreeMap<Object, Object>(
+            this.asMap(resource));
+
+        response.setContentType("text/xml; charset=UTF-8");
+        PrintWriter pw = response.getWriter();
+
+        pw.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+        pw.println("<content>");
+
+        for (Map.Entry<Object, Object> entry : contentMap.entrySet()) {
+
+            pw.println("  <property>");
+            pw.println("    <name>" + entry.getKey() + "</name>");
+
+            if (entry.getValue() instanceof Collection) {
+                pw.println("    <values>");
+                Collection<?> coll = (Collection<?>) entry.getValue();
+                for (Iterator<?> ci = coll.iterator(); ci.hasNext();) {
+                    pw.println("      <value>" + ci.next() + "</value>");
+                }
+                pw.println("    </values>");
+
+            } else {
+                pw.println("    <value>" + entry.getValue() + "</value>");
+            }
+            pw.println("  </property>");
+        }
+
+        pw.println("</content>");
+    }
+
+    private void renderContentJson(Resource resource,
+            SlingHttpServletResponse response) throws IOException {
+
+        Map<Object, Object> contentMap = new TreeMap<Object, Object>(
+            this.asMap(resource));
+
+        response.setContentType("text/x-json; charset=UTF-8");
+        PrintWriter pw = response.getWriter();
+
+        pw.println("{");
+
+        boolean notFirst = false;
+        for (Map.Entry<Object, Object> entry : contentMap.entrySet()) {
+
+            if (notFirst) {
+                pw.println(',');
+            } else {
+                notFirst = true;
+            }
+
+            pw.print("  \"" + entry.getKey() + "\": ");
+
+            if (entry.getValue() instanceof Collection) {
+                pw.println("[");
+                Collection<?> coll = (Collection<?>) entry.getValue();
+                for (Iterator<?> ci = coll.iterator(); ci.hasNext();) {
+                    pw.print("    ");
+                    this.printObjectJson(pw, ci.next());
+                    if (ci.hasNext()) {
+                        pw.println(',');
+                    }
+                }
+                pw.println();
+                pw.print("  ]");
+
+            } else {
+                this.printObjectJson(pw, entry.getValue());
+            }
+        }
+
+        pw.println();
+        pw.println("}");
+
+    }
+
+    private void printObjectJson(PrintWriter pw, Object object) {
+        boolean quote = !((object instanceof Boolean) || (object instanceof Number));
+        if (quote) {
+            pw.print('"');
+        }
+        pw.print(object);
+        if (quote) {
+            pw.print('"');
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private Map<Object, Object> asMap(Resource resource) {
+        
+        Object object = resource.adaptTo(Object.class);
+        if (object != null) {
+            if (object instanceof Map) {
+                return (Map<Object, Object>) object; // unchecked cast
+            }
+
+            return new BeanMap(object); // unchecked cast
+        }
+
+        // no objects available
+        return null;
+    }
+}

Propchange: incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/defaults/DefaultServlet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/ErrorSlingHttpServletRequest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/ErrorSlingHttpServletRequest.java?rev=605610&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/ErrorSlingHttpServletRequest.java (added)
+++ incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/ErrorSlingHttpServletRequest.java Wed Dec 19 08:42:53 2007
@@ -0,0 +1,132 @@
+/*
+ * 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.servlet.resolver.helper;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpSession;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.request.RequestDispatcherOptions;
+import org.apache.sling.api.request.RequestParameter;
+import org.apache.sling.api.request.RequestParameterMap;
+import org.apache.sling.api.request.RequestPathInfo;
+import org.apache.sling.api.request.RequestProgressTracker;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.services.ServiceLocator;
+
+public class ErrorSlingHttpServletRequest extends
+        HttpServletRequestWrapper implements SlingHttpServletRequest {
+
+    private SlingHttpServletRequest delegatee;
+    private String methodName;
+
+    public ErrorSlingHttpServletRequest(HttpServletRequest delegatee,
+            String errorMethod) {
+        super(delegatee);
+
+        this.delegatee = (delegatee instanceof SlingHttpServletRequest)
+                ? (SlingHttpServletRequest) delegatee
+                : null;
+        this.methodName = errorMethod;
+    }
+
+    public void setMethod(String methodName) {
+        this.methodName = methodName.toLowerCase();
+    }
+    
+    @Override
+    public String getMethod() {
+        return methodName;
+    }
+
+
+    // ---------- SlingHttpServletRequest ----------------------------------
+
+    public Cookie getCookie(String name) {
+        return (delegatee == null) ? null : delegatee.getCookie(name);
+    }
+
+    public RequestDispatcher getRequestDispatcher(Resource resource,
+            RequestDispatcherOptions options) {
+        return (delegatee == null) ? null : delegatee.getRequestDispatcher(resource, options);
+    }
+
+    public RequestDispatcher getRequestDispatcher(Resource resource) {
+        return (delegatee == null) ? null : delegatee.getRequestDispatcher(resource);
+    }
+
+    public RequestParameter getRequestParameter(String name) {
+        return (delegatee == null) ? null : delegatee.getRequestParameter(name);
+    }
+
+    public RequestParameterMap getRequestParameterMap() {
+        return (delegatee == null) ? null : delegatee.getRequestParameterMap();
+    }
+
+    public RequestParameter[] getRequestParameters(String name) {
+        return (delegatee == null) ? null : delegatee.getRequestParameters(name);
+    }
+
+    public RequestPathInfo getRequestPathInfo() {
+        return (delegatee == null) ? null : delegatee.getRequestPathInfo();
+    }
+
+    public RequestProgressTracker getRequestProgressTracker() {
+        return (delegatee == null) ? null : delegatee.getRequestProgressTracker();
+    }
+
+    public Resource getResource() {
+        return (delegatee == null) ? null : delegatee.getResource();
+    }
+
+    public ResourceBundle getResourceBundle(Locale locale) {
+        return (delegatee == null) ? null : delegatee.getResourceBundle(locale);
+    }
+
+    public ResourceResolver getResourceResolver() {
+        return (delegatee == null) ? null : delegatee.getResourceResolver();
+    }
+
+    public String getResponseContentType() {
+        return (delegatee == null) ? null : delegatee.getResponseContentType();
+    }
+
+    public Enumeration<String> getResponseContentTypes() {
+        return (delegatee == null) ? null : delegatee.getResponseContentTypes();
+    }
+
+    public ServiceLocator getServiceLocator() {
+        return (delegatee == null) ? null : delegatee.getServiceLocator();
+    }
+
+}
\ No newline at end of file

Propchange: incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/ErrorSlingHttpServletRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/SlingScriptServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/SlingScriptServlet.java?rev=605610&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/SlingScriptServlet.java (added)
+++ incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/SlingScriptServlet.java Wed Dec 19 08:42:53 2007
@@ -0,0 +1,101 @@
+/*
+ * 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.servlet.resolver.helper;
+
+import static java.lang.Boolean.TRUE;
+import static org.apache.sling.api.scripting.SlingBindings.FLUSH;
+import static org.apache.sling.api.scripting.SlingBindings.REQUEST;
+import static org.apache.sling.api.scripting.SlingBindings.RESPONSE;
+
+import java.io.IOException;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import org.apache.sling.api.SlingException;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.scripting.SlingBindings;
+import org.apache.sling.api.scripting.SlingScript;
+
+/**
+ * The <code>SlingScriptServlet</code> is a servlet encapsulating a
+ * <code>SlingScript</code> instance for unified use in the
+ * {@link SlingServletResolver}.
+ */
+public class SlingScriptServlet implements Servlet {
+
+    private ServletConfig servletConfig;
+    
+    /**
+     * The script to call in the
+     * {@link #service(ServletRequest, ServletResponse)} method.
+     */
+    private final SlingScript script;
+
+    public SlingScriptServlet(SlingScript script) {
+        this.script = script;
+    }
+
+    public void service(ServletRequest req, ServletResponse res)
+            throws ServletException, IOException {
+
+        SlingHttpServletRequest request = (SlingHttpServletRequest) req;
+
+        try {
+            // prepare the properties for the script
+            SlingBindings props = new SlingBindings();
+            props.put(REQUEST, req);
+            props.put(RESPONSE, res);
+            props.put(FLUSH, TRUE);
+
+            res.setCharacterEncoding("UTF-8");
+            res.setContentType(request.getResponseContentType());
+
+            // evaluate the script now using the ScriptEngine
+            script.eval(props);
+
+        } catch (IOException ioe) {
+            throw ioe;
+        } catch (ServletException se) {
+            throw se;
+        } catch (Exception e) {
+            throw new SlingException("Cannot get DefaultSlingScript: "
+                + e.getMessage(), e);
+        }
+    }
+
+    public ServletConfig getServletConfig() {
+        return servletConfig;
+    }
+
+    public String getServletInfo() {
+        return "Script " + script.getScriptResource().getURI();
+    }
+
+    public void init(ServletConfig servletConfig) {
+        this.servletConfig = servletConfig;
+    }
+
+    public void destroy() {
+    }
+
+}

Propchange: incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/SlingScriptServlet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/SlingServletConfig.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/SlingServletConfig.java?rev=605610&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/SlingServletConfig.java (added)
+++ incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/SlingServletConfig.java Wed Dec 19 08:42:53 2007
@@ -0,0 +1,37 @@
+/*
+ * 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.servlet.resolver.helper;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+
+import org.apache.sling.core.servlets.AbstractServiceReferenceConfig;
+import org.osgi.framework.ServiceReference;
+
+public class SlingServletConfig extends AbstractServiceReferenceConfig implements ServletConfig {
+
+    public SlingServletConfig(ServletContext servletContext,
+            ServiceReference reference, String servletName) {
+        super(servletContext, reference, servletName);
+    }
+
+    public String getServletName() {
+        return getName();
+    }
+}
\ No newline at end of file

Propchange: incubator/sling/trunk/sling/servlet-resolver/src/main/java/org/apache/sling/servlet/resolver/helper/SlingServletConfig.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlet-resolver/src/main/resources/META-INF/LICENSE
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlet-resolver/src/main/resources/META-INF/LICENSE?rev=605610&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlet-resolver/src/main/resources/META-INF/LICENSE (added)
+++ incubator/sling/trunk/sling/servlet-resolver/src/main/resources/META-INF/LICENSE Wed Dec 19 08:42:53 2007
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.

Added: incubator/sling/trunk/sling/servlet-resolver/src/main/resources/META-INF/NOTICE
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlet-resolver/src/main/resources/META-INF/NOTICE?rev=605610&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlet-resolver/src/main/resources/META-INF/NOTICE (added)
+++ incubator/sling/trunk/sling/servlet-resolver/src/main/resources/META-INF/NOTICE Wed Dec 19 08:42:53 2007
@@ -0,0 +1,5 @@
+Apache Sling Servlet Resolver
+Copyright 2007 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).