You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@apache.org on 2006/09/02 06:30:18 UTC

svn commit: r439527 [1/2] - in /tomcat/sandbox/tomcat-lite: ./ java/org/apache/tomcat/lite/ java/org/apache/tomcat/lite/http/ java/org/apache/tomcat/lite/webmap/ java/org/apache/tomcat/servlets/config/ java/org/apache/tomcat/servlets/deploy/ java/org/a...

Author: costin
Date: Fri Sep  1 21:30:15 2006
New Revision: 439527

URL: http://svn.apache.org/viewvc?rev=439527&view=rev
Log:
Many fixes and improvements, now alost everything I tried works ( I ran the old watchdog once, all old servlet tests are passing ).
The JSP integration is working again - but in a much cleaner way, no hacks ( and it can be used independent of tomcat
in a simpler way than the old jasper servlet )


Added:
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletResponseIncludeWrapper.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/servlets/jsp/JspCompileServlet.java
    tomcat/sandbox/tomcat-lite/webapps/ROOT/test.jsp
    tomcat/sandbox/tomcat-lite/webapps/__x_classpath/
    tomcat/sandbox/tomcat-lite/webapps/__x_classpath/WEB-INF/
    tomcat/sandbox/tomcat-lite/webapps/__x_classpath/WEB-INF/lib/
Modified:
    tomcat/sandbox/tomcat-lite/build.xml
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/RequestDispatcherImpl.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletConfigImpl.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletContextImpl.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletRequestImpl.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletResponseImpl.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/TomcatLite.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/http/CoyoteAdapter.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/webmap/WebappServletMapper.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/servlets/config/ServletData.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/servlets/deploy/ReloadServlet.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/servlets/deploy/WebXml.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/servlets/jsp/JspProxyServlet.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/servlets/sec/SimpleAuthServlet.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/servlets/session/SessionManagerServlet.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/util/loader/Module.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/util/loader/Repository.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/util/net/http11/Http11Processor.java
    tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/util/net/nio/NioEndpoint.java
    tomcat/sandbox/tomcat-lite/webapps/ROOT/index.html
    tomcat/sandbox/tomcat-lite/webapps/__x_engine/WEB-INF/web.xml
    tomcat/sandbox/tomcat-lite/webapps/__x_protocol/WEB-INF/web.xml

Modified: tomcat/sandbox/tomcat-lite/build.xml
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/build.xml?rev=439527&r1=439526&r2=439527&view=diff
==============================================================================
--- tomcat/sandbox/tomcat-lite/build.xml (original)
+++ tomcat/sandbox/tomcat-lite/build.xml Fri Sep  1 21:30:15 2006
@@ -102,6 +102,13 @@
       </fileset>
     </jar>
 
+    <jar destfile="webapps/__x_classpath/WEB-INF/lib/jasper.jar" 
+         manifest="resources/jasper.MF">
+      <fileset dir="${tc6.classes}" >
+        <include name="org/apache/jasper/*"/>
+      </fileset>
+    </jar>
+    
   </target>
 
   <target name="all" depends="tomcat-lite.jar,tomcat-runtime.jar" />

Modified: tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/RequestDispatcherImpl.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/RequestDispatcherImpl.java?rev=439527&r1=439526&r2=439527&view=diff
==============================================================================
--- tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/RequestDispatcherImpl.java (original)
+++ tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/RequestDispatcherImpl.java Fri Sep  1 21:30:15 2006
@@ -34,60 +34,25 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.tomcat.lite.util.MappingData;
 import org.apache.tomcat.lite.webmap.WebappFilterMapper;
+import org.apache.tomcat.util.buf.CharChunk;
+import org.apache.tomcat.util.buf.MessageBytes;
 import org.apache.tomcat.util.res.StringManager;
 
 /**
- * Standard implementation of <code>RequestDispatcher</code> that allows a
- * request to be forwarded to a different resource to create the ultimate
- * response, or to include the output of another resource in the response
- * from this resource.  This implementation allows application level servlets
- * to wrap the request and/or response objects that are passed on to the
- * called resource, as long as the wrapping classes extend
- * <code>javax.servlet.ServletRequestWrapper</code> and
- * <code>javax.servlet.ServletResponseWrapper</code>.
  *
- * @author Craig R. McClanahan
- * @version $Revision: 303947 $ $Date: 2005-06-08 22:50:26 -0700 (Wed, 08 Jun 2005) $
  */
-
 final class RequestDispatcherImpl implements RequestDispatcher {
+    /**
+     * Thread local mapping data. 
+     */
+    private transient ThreadLocal localMappingData = new ThreadLocal();
 
-    public RequestDispatcherImpl(ServletConfigImpl wrapper, String name) {
-        this.wrapper = wrapper;
-        this.name = name;
-        this.context = (ServletContextImpl) wrapper.getParent();
-
-    }
-    
     /**
-     * Construct a new instance of this class, configured according to the
-     * specified parameters.  If both servletPath and pathInfo are
-     * <code>null</code>, it will be assumed that this RequestDispatcher
-     * was acquired by name, rather than by path.
-     *
-     * @param wrapper The Wrapper associated with the resource that will
-     *  be forwarded to or included (required)
-     * @param requestURI The request URI to this resource (if any)
-     * @param servletPath The revised servlet path to this resource (if any)
-     * @param pathInfo The revised extra path information to this resource
-     *  (if any)
-     * @param queryString Query string parameters included with this request
-     *  (if any)
-     * @param name Servlet name (if a named dispatcher was created)
-     *  else <code>null</code>
-     */
-    public RequestDispatcherImpl(ServletConfigImpl wrapper, 
-                                 String requestURI, String servletPath,
-                                 String pathInfo, String queryString) {
-        this.wrapper = wrapper;
-        this.context = (ServletContextImpl) wrapper.getParent();
-        this.requestURI = requestURI;
-        this.servletPath = servletPath;
-        this.origServletPath = servletPath;
-        this.pathInfo = pathInfo;
-        this.queryString = queryString;
-    }
+     * Thread local URI message bytes.
+     */
+    private transient ThreadLocal localUriMB = new ThreadLocal();
 
     /**
      * The request attribute under which the original servlet path is stored
@@ -186,10 +151,11 @@
 
     private static Log log = LogFactory.getLog(RequestDispatcherImpl.class);
 
+    private String path;
     /**
      * The Context this RequestDispatcher is associated with.
      */
-    private ServletContextImpl context = null;
+    private ServletContextImpl ctx = null;
 
     /**
      * The servlet name for a named dispatcher.
@@ -265,6 +231,20 @@
     
     private Servlet servlet; 
 
+    /** Named dispatcher 
+     */
+    public RequestDispatcherImpl(ServletConfigImpl wrapper, String name) {
+        this.wrapper = wrapper;
+        this.name = name;
+        this.ctx = (ServletContextImpl) wrapper.getServletContext();
+
+    }
+    
+    public RequestDispatcherImpl(ServletContextImpl ctx, String path) {
+        this.path = path;
+        this.ctx = ctx;
+    }
+   
 
 
     /**
@@ -283,17 +263,12 @@
     {
         // Reset any output that has been buffered, but keep headers/cookies
         if (response.isCommitted()) {
-            if ( log.isDebugEnabled() )
-                log.debug("  Forward on committed response --> ISE");
-            throw new IllegalStateException
-                (sm.getString("applicationDispatcher.forward.ise"));
+            throw new IllegalStateException("forward(): response.isComitted()");
         }
         
         try {
             response.resetBuffer();
         } catch (IllegalStateException e) {
-            if ( log.isDebugEnabled() )
-                log.debug("  Forward resetBuffer() returned ISE: " + e);
             throw e;
         }
 
@@ -301,30 +276,27 @@
         setup(request, response, false);
 
         // Identify the HTTP-specific request and response objects (if any)
-        HttpServletRequest hrequest = null;
-        hrequest = (HttpServletRequest) request;
-        HttpServletResponse hresponse = null;
-        hresponse = (HttpServletResponse) response;
-
-        // Handle a nn-HTTP forward by passing the existing request/response
-        if ((servletPath == null) && (pathInfo == null)) {
-            ServletRequestWrapperImpl wrequest =
-                (ServletRequestWrapperImpl) wrapRequest();
+        HttpServletRequest hrequest = (HttpServletRequest) request;
+
+        ServletRequestWrapperImpl wrequest =
+            (ServletRequestWrapperImpl) wrapRequest();
+
+        
+        if (name != null) {
             wrequest.setRequestURI(hrequest.getRequestURI());
             wrequest.setContextPath(hrequest.getContextPath());
             wrequest.setServletPath(hrequest.getServletPath());
             wrequest.setPathInfo(hrequest.getPathInfo());
             wrequest.setQueryString(hrequest.getQueryString());
 
-            processRequest(request,response);
-
-            wrequest.recycle();
-            unwrapRequest();
+            
         } else { // path based
-            ServletRequestWrapperImpl wrequest =
-                (ServletRequestWrapperImpl) wrapRequest();
-
-            String contextPath = context.getContextPath();
+            mapPath();
+            if (wrapper == null) {
+                throw new ServletException("Forward not found " + 
+                        path);
+            }
+            String contextPath = ctx.getContextPath();
             if (hrequest.getAttribute(FORWARD_REQUEST_URI_ATTR) == null) {
                 wrequest.setAttribute(FORWARD_REQUEST_URI_ATTR,
                                       hrequest.getRequestURI());
@@ -346,20 +318,19 @@
                 wrequest.setQueryString(queryString);
                 wrequest.setQueryParams(queryString);
             }
-
-            processRequest(request,response);
-
-            wrequest.recycle();
-            unwrapRequest();
-
         }
+        processRequest(outerRequest, outerResponse);
+
+        wrequest.recycle();
+        unwrapRequest();
 
         // This is not a real close in order to support error processing
         if ( log.isDebugEnabled() )
             log.debug(" Disabling the response for futher output");
 
         if  (response instanceof ServletResponseImpl) {
-            ((ServletResponseImpl) response).finish();
+            ((ServletResponseImpl) response).flushBuffer();
+            ((ServletResponseImpl) response).setSuspended(true);
         } else {
             // Servlet SRV.6.2.2. The Resquest/Response may have been wrapped
             // and may no longer be instance of RequestFacade 
@@ -385,7 +356,6 @@
                 ;
             }
         }
-
     }
 
     
@@ -409,48 +379,24 @@
         setup(request, response, true);
 
         // Create a wrapped response to use for this request
-        ServletResponse wresponse = wrapResponse(true);
+        // this actually gets inserted somewhere in the chain - it's not 
+        // the last one, but first non-user response
+        wrapResponse();
+        ServletRequestWrapperImpl wrequest =
+            (ServletRequestWrapperImpl) wrapRequest();
 
-        // Handle a non-HTTP include
-        if (!(request instanceof HttpServletRequest) ||
-            !(response instanceof HttpServletResponse)) {
-
-            if ( log.isDebugEnabled() )
-                log.debug(" Non-HTTP Include");
-            request.setAttribute(WebappFilterMapper.DISPATCHER_TYPE_ATTR,
-                                             new Integer(WebappFilterMapper.INCLUDE));
-            request.setAttribute(WebappFilterMapper.DISPATCHER_REQUEST_PATH_ATTR, origServletPath);
-            invoke(request, outerResponse);
-        }
 
         // Handle an HTTP named dispatcher include
-        else if (name != null) {
-
-            if ( log.isDebugEnabled() )
-                log.debug(" Named Dispatcher Include");
-
-            ServletRequestWrapperImpl wrequest =
-                (ServletRequestWrapperImpl) wrapRequest();
+        if (name != null) {
             wrequest.setAttribute(NAMED_DISPATCHER_ATTR, name);
-            if (servletPath != null)
-                wrequest.setServletPath(servletPath);
+            if (servletPath != null) wrequest.setServletPath(servletPath);
             wrequest.setAttribute(WebappFilterMapper.DISPATCHER_TYPE_ATTR,
-                                             new Integer(WebappFilterMapper.INCLUDE));
-            wrequest.setAttribute(WebappFilterMapper.DISPATCHER_REQUEST_PATH_ATTR, origServletPath);
-            invoke(outerRequest, wresponse);
-
-            wrequest.recycle();
-        }
-
-        // Handle an HTTP path based include
-        else {
-
-            if ( log.isDebugEnabled() )
-                log.debug(" Path Based Include");
-
-            ServletRequestWrapperImpl wrequest =
-                (ServletRequestWrapperImpl) wrapRequest();
-            String contextPath = context.getContextPath();
+                                  new Integer(WebappFilterMapper.INCLUDE));
+            wrequest.setAttribute(WebappFilterMapper.DISPATCHER_REQUEST_PATH_ATTR, 
+                                  origServletPath);
+        } else {
+            mapPath();
+            String contextPath = ctx.getContextPath();
             if (requestURI != null)
                 wrequest.setAttribute(INCLUDE_REQUEST_URI_ATTR,
                                       requestURI);
@@ -470,19 +416,94 @@
             }
             
             wrequest.setAttribute(WebappFilterMapper.DISPATCHER_TYPE_ATTR,
-                                             new Integer(WebappFilterMapper.INCLUDE));
-            wrequest.setAttribute(WebappFilterMapper.DISPATCHER_REQUEST_PATH_ATTR, origServletPath);
-            invoke(outerRequest, wresponse);
-
-            wrequest.recycle();
+                                  new Integer(WebappFilterMapper.INCLUDE));
+            wrequest.setAttribute(WebappFilterMapper.DISPATCHER_REQUEST_PATH_ATTR, 
+                                  origServletPath);
         }
 
-        
+        invoke(outerRequest, outerResponse);
+
+        wrequest.recycle();
+        unwrapRequest();
+        unwrapResponse();
     }
 
 
     // -------------------------------------------------------- Private Methods
 
+    public void mapPath() {
+        if (path == null || servletPath != null) return;
+        
+        // Retrieve the thread local URI, used for mapping
+        // TODO: recycle RequestDispatcher stack and associated objects
+        // instead of this object
+        
+        MessageBytes uriMB = (MessageBytes) localUriMB.get();
+        if (uriMB == null) {
+            uriMB = MessageBytes.newInstance();
+            CharChunk uriCC = uriMB.getCharChunk();
+            uriCC.setLimit(-1);
+            localUriMB.set(uriMB);
+        } else {
+            uriMB.recycle();
+        }
+
+        // Get query string
+        int pos = path.indexOf('?');
+        if (pos >= 0) {
+            queryString = path.substring(pos + 1);
+        } else {
+            pos = path.length();
+        }
+ 
+        // Retrieve the thread local mapping data
+        MappingData mappingData = (MappingData) localMappingData.get();
+        if (mappingData == null) {
+            mappingData = new MappingData();
+            localMappingData.set(mappingData);
+        }
+
+        // Map the URI
+        CharChunk uriCC = uriMB.getCharChunk();
+        try {
+            /*
+             * Ignore any trailing path params (separated by ';') for mapping
+             * purposes.
+             * This is sometimes broken - path params can be on any path 
+             * component, not just last.
+             */
+            int semicolon = path.indexOf(';');
+            if (pos >= 0 && semicolon > pos) {
+                semicolon = -1;
+            }
+            if (ctx.getContextPath().length() > 1 )
+                uriCC.append(ctx.getContextPath());
+            uriCC.append(path, 0, semicolon > 0 ? semicolon : pos);
+            
+            ctx.getMapper().map(uriMB, mappingData);
+            
+            // at least default wrapper must be returned
+            
+            /*
+             * Append any trailing path params (separated by ';') that were
+             * ignored for mapping purposes, so that they're reflected in the
+             * RequestDispatcher's requestURI
+             */
+            if (semicolon > 0) {
+                uriCC.append(path, semicolon, pos - semicolon);
+            }
+        } catch (Exception e) {
+            log.error("getRequestDispatcher()", e);
+        }
+
+        wrapper = (ServletConfigImpl) mappingData.wrapper;
+        servletPath = mappingData.wrapperPath.toString();
+        pathInfo = mappingData.pathInfo.toString();
+
+        mappingData.recycle();
+
+    }
+    
 
     /**
      * Prepare the request based on the filter configuration.
@@ -512,6 +533,7 @@
     }
     
     
+    
 
     /**
      * Ask the resource represented by this RequestDispatcher to process
@@ -535,7 +557,7 @@
         // classloader. If it's not, we're saving it, and setting the context
         // classloader to the Context classloader
         ClassLoader oldCCL = Thread.currentThread().getContextClassLoader();
-        ClassLoader contextClassLoader = context.getClassLoader();
+        ClassLoader contextClassLoader = ctx.getClassLoader();
 
         if (oldCCL != contextClassLoader) {
             Thread.currentThread().setContextClassLoader(contextClassLoader);
@@ -570,18 +592,18 @@
                filterChain.doFilter(request, response);
              }
         } catch (IOException e) {
-            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException",
+            ctx.getLogger().error(sm.getString("applicationDispatcher.serviceException",
                              wrapper.getServletName()), e);
             ioException = e;
         } catch (UnavailableException e) {
-            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException",
+            ctx.getLogger().error(sm.getString("applicationDispatcher.serviceException",
                              wrapper.getServletName()), e);
             servletException = e;
             wrapper.unavailable(e);
         } catch (ServletException e) {
             servletException = e;
         } catch (RuntimeException e) {
-            wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException",
+            ctx.getLogger().error(sm.getString("applicationDispatcher.serviceException",
                              wrapper.getServletName()), e);
             runtimeException = e;
         }
@@ -618,20 +640,8 @@
 
     private ServletException servletDealocate(ServletException servletException)
     {
-        try {
-            if (servlet != null) {
-                wrapper.deallocate(servlet);
-            }
-        } catch (ServletException e) {
-            wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException",
-                             wrapper.getServletName()), e);
-            servletException = e;
-        } catch (Throwable e) {
-            wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException",
-                             wrapper.getServletName()), e);
-            servletException = new ServletException
-                (sm.getString("applicationDispatcher.deallocateException",
-                              wrapper.getServletName()), e);
+        if (servlet != null) {
+            wrapper.deallocate(servlet);
         }
         return servletException;
     }
@@ -644,7 +654,7 @@
 
         // Check for the servlet being marked unavailable
         if (wrapper.isUnavailable()) {
-            wrapper.getLogger().warn(
+            ctx.getLogger().warn(
                     sm.getString("applicationDispatcher.isUnavailable", 
                     wrapper.getServletName()));
             long available = wrapper.getAvailable();
@@ -662,12 +672,14 @@
                 servlet = wrapper.allocate();
             }
         } catch (ServletException e) {
-            wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException",
-                             wrapper.getServletName()), ServletConfigImpl.getRootCause(e));
+            ctx.getLogger().error("RequestDispatcher: allocate " + 
+                             wrapper.getServletName() + " " + 
+                             wrapper.getJspFile() + 
+                             " " + wrapper.getServletClass());
             servletException = e;
             servlet = null;
         } catch (Throwable e) {
-            wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException",
+            ctx.getLogger().error(sm.getString("applicationDispatcher.allocateException",
                              wrapper.getServletName()), e);
             servletException = new ServletException
                 (sm.getString("applicationDispatcher.allocateException",
@@ -773,24 +785,32 @@
                 break;
             if (current instanceof ServletRequestImpl)
                 break;
+            // user-specified
             previous = current;
             current = ((ServletRequestWrapper) current).getRequest();
         }
+        // now previous will be a user-specified wrapper, 
+        // and current one of our own wrappers ( deeper in stack )
+        // ... current USER_previous USER USER
+        // previous is null if the top request is ours.
 
         // Instantiate a new wrapper at this point and insert it in the chain
         ServletRequest wrapper = null;
         
         // Compute a crossContext flag
-        HttpServletRequest hcurrent = (HttpServletRequest) current;
         boolean crossContext = isCrossContext();
-
         wrapper = 
-            new ServletRequestWrapperImpl(hcurrent, context, crossContext);
+            new ServletRequestWrapperImpl((HttpServletRequest) current, 
+                                          ctx, crossContext);
 
-        if (previous == null)
+        if (previous == null) {
+            // outer becomes the wrapper, includes orig wrapper inside
             outerRequest = wrapper;
-        else
+        } else {
+            // outer remains user-specified sersvlet, delegating to 
+            // our wrapper, which delegates to real request or our wrapper.
             ((ServletRequestWrapper) previous).setRequest(wrapper);
+        }
         wrapRequest = wrapper;
         return (wrapper);
     }
@@ -808,7 +828,7 @@
                 // Forward
                 contextPath = houterRequest.getContextPath();
             }
-            crossContext = !(context.getContextPath().equals(contextPath));
+            crossContext = !(ctx.getContextPath().equals(contextPath));
         }
         return crossContext;
     }
@@ -817,16 +837,17 @@
     /**
      * Create and return a response wrapper that has been inserted in the
      * appropriate spot in the response chain.
+     * 
+     * Side effect: updates outerResponse, wrapResponse.
+     * The chain is updated with a wrapper below lowest user wrapper
      */
-    private ServletResponse wrapResponse(boolean including) {
+    private ServletResponse wrapResponse() {
         // Locate the response we should insert in front of
         ServletResponse previous = null;
         ServletResponse current = outerResponse;
         while (current != null) {
             if (!(current instanceof ServletResponseWrapper))
                 break;
-            if (current instanceof ServletResponseWrapperImpl)
-                break;
             if (current instanceof ServletResponseImpl)
                 break;
             previous = current;
@@ -834,14 +855,17 @@
         }
 
         // Instantiate a new wrapper at this point and insert it in the chain
-        ServletResponse wrapper = null;
-            wrapper =
-                new ServletResponseWrapperImpl((HttpServletResponse) current,
-                                            including);
-        if (previous == null)
+        ServletResponse wrapper = 
+             new ServletResponseIncludeWrapper(current);
+            
+        if (previous == null) {
+            // outer is ours, we can wrap on top
             outerResponse = wrapper;
-        else
+        } else {
+            // outer is user-specified, leave it alone. 
+            // we insert ourself below the lowest user-specified response
             ((ServletResponseWrapper) previous).setResponse(wrapper);
+        }
         wrapResponse = wrapper;
         return (wrapper);
 

Modified: tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletConfigImpl.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletConfigImpl.java?rev=439527&r1=439526&r2=439527&view=diff
==============================================================================
--- tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletConfigImpl.java (original)
+++ tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletConfigImpl.java Fri Sep  1 21:30:15 2006
@@ -22,26 +22,19 @@
 import java.io.Serializable;
 import java.lang.reflect.Method;
 import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Stack;
 
 import javax.servlet.Servlet;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
 import javax.servlet.SingleThreadModel;
 import javax.servlet.UnavailableException;
 
-import org.apache.catalina.LifecycleException;
-import org.apache.commons.logging.Log;
 import org.apache.tomcat.servlets.config.ServletData;
 import org.apache.tomcat.servlets.util.Enumerator;
 import org.apache.tomcat.util.IntrospectionUtils;
-import org.apache.tomcat.util.res.StringManager;
 
 /**
  * Based on Wrapper.
@@ -53,58 +46,25 @@
  * @author Craig R. McClanahan
  * @author Remy Maucherat
  */
-public class ServletConfigImpl implements ServletConfig, Serializable {
+public class ServletConfigImpl implements ServletConfig {
     
-    private transient static org.apache.commons.logging.Log log=
+    private static org.apache.commons.logging.Log log=
         org.apache.commons.logging.LogFactory.getLog( ServletConfigImpl.class );
 
     private static final String[] DEFAULT_SERVLET_METHODS = new String[] {
                                                     "GET", "HEAD", "POST" };
 
-    static transient StringManager sm = 
-        StringManager.getManager("org.apache.tomcat.lite");
-  
     public static final String JSP_SERVLET_CLASS =
-        "org.apache.jasper.servlet.JspServlet";
+        "org.apache.tomcat.servlets.jsp.JspProxyServlet";
 
-    public static final String JSP_SERVLET_NAME = "jsp";
-
-    public ServletConfigImpl() {
-        super();
-    }
+    public static final String SINGLE_THREADED_PROXY =
+        "org.apache.tomcat.servlets.jsp.SingleThreadedProxyServlet";
 
-    public ServletConfigImpl(ServletContextImpl ctx, ServletData sd) {
-        data = sd;
-        setParent((ServletContextImpl) ctx);
-        ctx.facade.notifyAdd(this);
-    }
+    public static final String JSP_SERVLET_NAME = "jsp";
 
     ServletData data;
     
     /**
-     * The context-relative URI of the JSP file for this servlet.
-     */
-    private String jspFile = null;
-
-    /**
-     * The security role references for this servlet, keyed by role name
-     * used in the servlet.  The corresponding value is the role name of
-     * the web application itself.
-     */
-    private HashMap references = new HashMap();
-
-    /**
-     * The run-as identity for this servlet.
-     */
-    private String runAs = null;
-
-    /**
-     * True if this StandardWrapper is for the JspServlet
-     */
-    private boolean isJspServlet;
-
-    
-    /**
      * The date and time at which this servlet will become available (in
      * milliseconds since the epoch), or zero if the servlet is available.
      * If this value equals Long.MAX_VALUE, the unavailability of this
@@ -118,45 +78,38 @@
      */
     private transient int countAllocated = 0;
 
+    private ServletContextImpl ctx;
+
     /**
      * The (single) initialized instance of this servlet.
      */
     private transient Servlet instance = null;
-
+    
     /**
      * Are we unloading our servlet instance at the moment?
      */
     private transient boolean unloading = false;
 
     // Support for SingleThreaded
+    private Class classClass = null;
     private transient boolean singleThreadModel = false;
-
     /**
      * Stack containing the STM instances.
      */
     private transient Stack instancePool = null;
 
+    
     // Statistics
     private transient long loadTime=0;
     private transient int classLoadTime=0;
-
-    private ServletContextImpl parent;
-    
-    /**
-     * Static class array used when the SecurityManager is turned on and 
-     * <code>Servlet.init</code> is invoked.
-     */
-    private static Class[] classType = new Class[]{ServletConfig.class};
     
-    
-    /**
-     * Static class array used when the SecurityManager is turned on and 
-     * <code>Servlet.service</code>  is invoked.
-     */                                                 
-    private static Class[] classTypeUsedInService = new Class[]{
-                                                         ServletRequest.class,
-                                                         ServletResponse.class};
     // ------------------------------------------------------------- Properties
+    public ServletConfigImpl(ServletContextImpl ctx, ServletData sd) {
+        data = sd;
+        this.ctx = (ServletContextImpl) ctx;
+        ctx.facade.notifyAdd(this);
+    }
+
 
     /**
      * Return the available date/time for this servlet, in milliseconds since
@@ -167,9 +120,7 @@
      * the servlet is currently available.
      */
     public long getAvailable() {
-
         return (this.available);
-
     }
 
 
@@ -203,117 +154,31 @@
     }
 
     /**
-     * Return the context-relative URI of the JSP file for this servlet.
+     * Return the jsp-file setting for this servlet.
      */
     public String getJspFile() {
-        return (this.jspFile);
-    }
-
-
-    /**
-     * Set the context-relative URI of the JSP file for this servlet.
-     *
-     * @param jspFile JSP file URI
-     */
-    public void setJspFile(String jspFile) {
-
-        String oldJspFile = this.jspFile;
-        this.jspFile = jspFile;
-//        support.firePropertyChange("jspFile", oldJspFile, this.jspFile);
-
-        // Each jsp-file needs to be represented by its own JspServlet and
-        // corresponding JspMonitoring mbean, because it may be initialized
-        // with its own init params
-        isJspServlet = true;
-
+        return data.jspFile;
     }
 
-
     /**
      * Return the load-on-startup order value (negative value means
      * load on first call).
      */
     public int getLoadOnStartup() {
-
-        if (isJspServlet && this.data.loadOnStartup < 0) {
-            /*
-             * JspServlet must always be preloaded, because its instance is
-             * used during registerJMX (when registering the JSP
-             * monitoring mbean)
-             */
-             return Integer.MAX_VALUE;
-        } else {
-            return (this.data.loadOnStartup);
-        }
-    }
-
-    /**
-     * Set the parent Container of this Wrapper, but only if it is a Context.
-     *
-     * @param container Proposed parent Container
-     */
-    public void setParent(ServletContextImpl container) {
-        this.parent = container;
-    }
-
-    public ServletContextImpl getParent() {
-        return parent;
-    }
-
-    /**
-     * Return the run-as identity for this servlet.
-     */
-    public String getRunAs() {
-
-        return (this.runAs);
-
+        return data.loadOnStartup;
     }
 
-
-    /**
-     * Set the run-as identity for this servlet.
-     *
-     * @param runAs New run-as identity value
-     */
-    public void setRunAs(String runAs) {
-
-        String oldRunAs = this.runAs;
-        this.runAs = runAs;
-//        support.firePropertyChange("runAs", oldRunAs, this.runAs);
-
-    }
-
-
     /**
      * Return the fully qualified servlet class name for this servlet.
      */
     public String getServletClass() {
-
-        return (this.data.servletClass);
-
-    }
-
-    /**
-     * Return <code>true</code> if the servlet class represented by this
-     * component implements the <code>SingleThreadModel</code> interface.
-     */
-    public boolean isSingleThreadModel() {
-
-        try {
-            loadServlet();
-        } catch (Throwable t) {
-            ;
-        }
-        return (singleThreadModel);
-
+        return data.servletClass;
     }
 
-
     /**
      * Is this servlet currently unavailable?
      */
     public boolean isUnavailable() {
-
         if (available == 0L)
             return (false);
         else if (available <= System.currentTimeMillis()) {
@@ -395,97 +260,85 @@
         return rootCause;
     }
 
-
-    /**
-     * Add a new security role reference record to the set of records for
-     * this servlet.
-     *
-     * @param name Role name used within this servlet
-     * @param link Role name used within the web application
-     */
-    public void addSecurityReference(String name, String link) {
-
-        synchronized (references) {
-            references.put(name, link);
-        }
-//        fireContainerEvent("addSecurityReference", name);
-
-    }
-
     /**
-     * Allocate an initialized instance of this Servlet that is ready to have
-     * its <code>service()</code> method called.  If the servlet class does
-     * not implement <code>SingleThreadModel</code>, the (only) initialized
-     * instance may be returned immediately.  If the servlet class implements
-     * <code>SingleThreadModel</code>, the Wrapper implementation must ensure
-     * that this instance is not allocated again until it is deallocated by a
-     * call to <code>deallocate()</code>.
-     *
-     * @exception ServletException if the servlet init() method threw
-     *  an exception
-     * @exception ServletException if a loading error occurs
+     *  MUST be called before service()
+     *  This method should be called to get the servlet. After 
+     *  service(), dealocate should be called. This deals with STM and
+     *  update use counters.
+     *  
+     *  Normally called from RequestDispatcher and TomcatLite.
      */
     public Servlet allocate() throws ServletException {
         // If we are currently unloading this servlet, throw an exception
-        if (unloading)
+        if (unloading) 
             throw new ServletException
-              (sm.getString("standardWrapper.unloading", getServletName()));
+              ("allocate() while unloading " + getServletName());
 
-        // If not SingleThreadedModel, return the same instance every time
-        if (!singleThreadModel) {
-            if (instance == null) {
-                synchronized (this) {
-                    if (instance == null) {
-                        try {
-                            if (log.isDebugEnabled())
-                                log.debug("Allocating non-STM instance");
-
-                            instance = loadServlet();
-                        } catch (ServletException e) {
-                            throw e;
-                        } catch (Throwable e) {
-                            throw new ServletException
-                                (sm.getString("standardWrapper.allocate"), e);
-                        }
+        Servlet servlet = null;
+        if (instance == null && !singleThreadModel) {
+            // never loaded.
+            synchronized (this) {
+                if (instance == null && !singleThreadModel) {
+                    try {
+                        servlet = loadServlet();
+                    } catch (ServletException e) {
+                        throw e;
+                    } catch (Throwable e) {
+                        throw new ServletException("loadServlet()", e);
+                    }
+                    if (servlet != null && !singleThreadModel) {
+                        instance = servlet;
                     }
                 }
             }
+        }
+
+        // If not SingleThreadedModel, return the same instance every time
+        if (instance != null) {
             countAllocated++;
+            System.err.println("New servet " + instance + " " + 
+                    countAllocated + " " + getServletName());
             return (instance);
         }
-
+        
         // Simpler policy for ST: unbound number of servlets ( can grow to
         // one per thread )
         
         synchronized (instancePool) {
             if (instancePool.isEmpty()) {
                 try {
-                    Servlet newServlet = loadServlet();
+                    if (servlet != null) {
+                        // this is the first invocation
+                        countAllocated++;
+                        return servlet;
+                    }
                     countAllocated++;
+                    Servlet newServlet = loadServlet();
+                    System.err.println("New STM servet " + newServlet + " " + 
+                            countAllocated);
                     return newServlet;
                 } catch (ServletException e) {
                     throw e;
                 } catch (Throwable e) {
-                    throw new ServletException
-                            (sm.getString("standardWrapper.allocate"), e);
+                    throw new ServletException("allocate " + getServletName(),
+                            e);
                 }
-            } 
-            return (Servlet) instancePool.pop();
+            }
+            System.err.println("Get from pool " + instancePool.size() +  " " +
+                    countAllocated);
+            Servlet s = (Servlet) instancePool.pop();
+            countAllocated++;
+            System.err.println("After get " + instancePool.size() + " " + s  + 
+                    " " + countAllocated);
+            return s;
         }
     }
 
 
     /**
-     * Return this previously allocated servlet to the pool of available
-     * instances.  If this servlet class does not implement SingleThreadModel,
-     * no action is actually required.
-     *
-     * @param servlet The servlet to be returned
-     *
-     * @exception ServletException if a deallocation error occurs
+     * MUST be called after service().
      */
-    public void deallocate(Servlet servlet) throws ServletException {
-
+    public void deallocate(Servlet servlet) {
         // If not SingleThreadModel, no action is required
         if (!singleThreadModel) {
             countAllocated--;
@@ -495,61 +348,15 @@
         // Unlock and free this instance
         synchronized (instancePool) {
             countAllocated--;
+            if (instancePool.contains(servlet)) {
+                System.err.println("Aleady in pool " + servlet + " " 
+                        + instancePool.size()+ " " + countAllocated);
+                return;
+            }
+            System.err.println("return  pool " + servlet +  " " + 
+                    instancePool.size() + " " + countAllocated);
             instancePool.push(servlet);
         }
-
-    }
-
-
-    /**
-     * Return the security role link for the specified security role
-     * reference name, if any; otherwise return <code>null</code>.
-     *
-     * @param name Security role reference used within this servlet
-     */
-    public String findSecurityReference(String name) {
-
-        synchronized (references) {
-            return ((String) references.get(name));
-        }
-
-    }
-
-
-    /**
-     * Return the set of security role reference names associated with
-     * this servlet, if any; otherwise return a zero-length array.
-     */
-    public String[] findSecurityReferences() {
-
-        synchronized (references) {
-            String results[] = new String[references.size()];
-            return ((String[]) references.keySet().toArray(results));
-        }
-
-    }
-
-    /**
-     * Load and initialize an instance of this servlet, if there is not already
-     * at least one initialized instance.  This can be used, for example, to
-     * load servlets that are marked in the deployment descriptor to be loaded
-     * at server startup time.
-     * <p>
-     * <b>IMPLEMENTATION NOTE</b>:  Servlets whose classnames begin with
-     * <code>org.apache.catalina.</code> (so-called "container" servlets)
-     * are loaded by the same classloader that loaded this class, rather than
-     * the classloader for the current web application.
-     * This gives such classes access to Catalina internals, which are
-     * prevented for classes loaded for web applications.
-     *
-     * @exception ServletException if the servlet init() method threw
-     *  an exception
-     * @exception ServletException if some other loading problem occurs
-     */
-    public synchronized void load() throws ServletException {
-        if(instance == null) { 
-            instance = loadServlet();
-        }
     }
 
 
@@ -564,76 +371,30 @@
         if (!singleThreadModel && (instance != null))
             return instance;
 
-        PrintStream out = System.out;
-
         Servlet servlet;
         
         long t1=System.currentTimeMillis();
 
-        // If this "servlet" is really a JSP file, get the right class.
-        // HOLD YOUR NOSE - this is a kludge that avoids having to do special
-        // case Catalina-specific code in Jasper - it also requires that the
-        // servlet path be replaced by the <jsp-file> element content in
-        // order to be completely effective
         String actualClass = data.servletClass;
-//        if ((actualClass == null) && (jspFile != null)) {
-//            ServletConfigImpl jspWrapper = (ServletConfigImpl)
-//            ((ServletContextImpl) getParent()).getServletConfig(JSP_SERVLET_NAME);
-//            if (jspWrapper != null) {
-//                actualClass = jspWrapper.getServletClass();
-//                // Merge init parameters
-//                String paramNames[] = jspWrapper.findInitParameters();
-//                for (int i = 0; i < paramNames.length; i++) {
-//                    if (parameters.get(paramNames[i]) == null) {
-//                        parameters.put
-//                        (paramNames[i], 
-//                         jspWrapper.findInitParameter(paramNames[i]));
-//                    }
-//                }
-//            }
-//        }
-
-        // Complain if no servlet class has been specified
-        if (actualClass == null) {
-            unavailable(null);
-            throw new ServletException
-            (sm.getString("standardWrapper.notClass", getServletName()));
-        }
-
-        ClassLoader classLoader = parent.getClassLoader(); 
-        if (classLoader == null ) 
-            classLoader = this.getClass().getClassLoader();
-            
-        // Special case class loader for a container provided servlet
-        //  
-        if (isContainerProvidedServlet(actualClass) && 
-            ! ((ServletContextImpl)getParent()).getPrivileged() ) {
-            // If it is a priviledged context - using its own
-            // class loader will work, since it's a child of the container
-            // loader
-            classLoader = this.getClass().getClassLoader();
-        }
+        
+        // jsp-file case. Load the JspProxyServlet instead, with the 
+        // right params. Note the JspProxyServlet is _not_ jasper, 
+        // nor 'jsp' servlet - it is just a proxy with no special 
+        // params. It calls the jsp servlet and jasper to generate the
+        // real class.
+        
+        // this is quite different from catalina, where an ugly kludge was
+        // used to use the same jsp servlet in 2 roles
+        
+        // the jsp proxy is replaced by the web.xml processor
 
-        // Load the specified servlet class from the appropriate class loader
-        Class classClass = null;
-        try {
-            if (classLoader != null) {
-                classClass = classLoader.loadClass(actualClass);
-            } else {
-                classClass = Class.forName(actualClass);
-            }
-        } catch (ClassNotFoundException e) {
-            unavailable(null);
-            getServletContext().log( "Error loading " + classLoader + " " + actualClass, e );
-            throw new ServletException
-            (sm.getString("standardWrapper.missingClass", actualClass),
-             e);
+        if (classClass == null) {
+            loadClass(actualClass);
         }
-
+        
         if (classClass == null) {
             unavailable(null);
-            throw new ServletException
-            (sm.getString("standardWrapper.missingClass", actualClass));
+            throw new UnavailableException("ClassNotFound: " + actualClass);
         }
 
         // Instantiate and initialize an instance of the servlet class itself
@@ -641,21 +402,22 @@
             servlet = (Servlet) classClass.newInstance();
         } catch (ClassCastException e) {
             unavailable(null);
-            // Restore the context ClassLoader
-            throw new ServletException
-            (sm.getString("standardWrapper.notServlet", actualClass), e);
+            throw new UnavailableException("ClassCast: (Servlet)" + 
+                    actualClass);
         } catch (Throwable e) {
             unavailable(null);
 
             // Added extra log statement for Bugzilla 36630:
             // http://issues.apache.org/bugzilla/show_bug.cgi?id=36630
             if(log.isDebugEnabled()) {
-                log.debug(sm.getString("standardWrapper.instantiate", actualClass), e);
+                log.debug("newInstance() error: servlet-name: " + 
+                        getServletName() +
+                        " servlet-class: " + actualClass, e);
             }
 
             // Restore the context ClassLoader
-            throw new ServletException
-            (sm.getString("standardWrapper.instantiate", actualClass), e);
+            throw new ServletException("newInstance() error " + getServletName() + 
+                    " " + actualClass, e);
         }
 
         classLoadTime=(int) (System.currentTimeMillis() -t1);
@@ -663,8 +425,6 @@
         // Call the initialization method of this servlet
         try {
             servlet.init(this);
-
-            jspLoadOnStartup(servlet);
         } catch (UnavailableException f) {
             unavailable(f);
             throw f;
@@ -672,8 +432,7 @@
             throw f;
         } catch (Throwable f) {
             getServletContext().log("StandardWrapper.Throwable", f );
-            throw new ServletException
-            (sm.getString("standardWrapper.initException", getServletName()), f);
+            throw new ServletException("Servlet.init()", f);
         }
 
         // Register our newly initialized instance
@@ -684,43 +443,36 @@
         }
         loadTime=System.currentTimeMillis() -t1;
         return servlet;
-
     }
 
-    private void jspLoadOnStartup(Servlet servlet) throws ServletException,
-        IOException
-    {
-        // Invoke jspInit on JSP pages
-        if ((data.loadOnStartup >= 0) && (jspFile != null)) {
-            // Invoking jspInit
-            ServletRequestImpl req = new ServletRequestImpl();
-            req.setServletPath(jspFile);
-            req.setQueryString("jsp_precompile=true");
-            ServletResponseImpl res = new ServletResponseImpl();
 
-            servlet.service(req, res);
+    private void loadClass(String actualClass) throws ServletException {
+        // Complain if no servlet class has been specified
+        if (actualClass == null) {
+            unavailable(null);
+            throw new ServletException("servlet-class missing " +  
+                    getServletName());
         }
-    }
-
-    /**
-     * Remove any security role reference for the specified role name.
-     *
-     * @param name Security role used within this servlet to be removed
-     */
-    public void removeSecurityReference(String name) {
-        synchronized (references) {
-            references.remove(name);
+        
+        ClassLoader classLoader = ctx.getClassLoader(); 
+        if (classLoader == null ) 
+            classLoader = this.getClass().getClassLoader();
+        
+        // Load the specified servlet class from the appropriate class loader
+        try {
+            classClass = classLoader.loadClass(actualClass);
+        } catch (ClassNotFoundException e) {
+            classClass = null;
         }
     }
 
-
     /**
      * Return a String representation of this component.
      */
     public String toString() {
         StringBuffer sb = new StringBuffer();
-        if (getParent() != null) {
-            sb.append(getParent().toString());
+        if (ctx != null) {
+            sb.append(ctx.toString());
             sb.append(".");
         }
         sb.append("StandardWrapper[");
@@ -738,7 +490,7 @@
      *  to mark this servlet as permanently unavailable
      */
     public void unavailable(UnavailableException unavailable) {
-        getServletContext().log(sm.getString("standardWrapper.unavailable", getServletName()));
+        getServletContext().log("UnavailableException:" + getServletName());
         if (unavailable == null)
             setAvailable(Long.MAX_VALUE);
         else if (unavailable.isPermanent())
@@ -765,6 +517,7 @@
      *  destroy() method
      */
     public synchronized void unload() throws ServletException {
+        setAvailable(Long.MAX_VALUE);        
 
         // Nothing to do if we have never loaded the instance
         if (!singleThreadModel && (instance == null))
@@ -775,11 +528,11 @@
         // (possibly more than once if non-STM)
         if (countAllocated > 0) {
             int nRetries = 0;
-            long delay = parent.getUnloadDelay() / 20;
+            long delay = ctx.getUnloadDelay() / 20;
             while ((nRetries < 21) && (countAllocated > 0)) {
                 if ((nRetries % 10) == 0) {
-                    log.info(sm.getString("standardWrapper.waiting",
-                                          new Integer(countAllocated)));
+                    log.info("Servlet.unload() timeout " + 
+                            countAllocated);
                 }
                 try {
                     Thread.sleep(delay);
@@ -792,29 +545,31 @@
 
         ClassLoader oldCtxClassLoader =
             Thread.currentThread().getContextClassLoader();
-        ClassLoader classLoader = instance.getClass().getClassLoader();
-
-        PrintStream out = System.out;
-        // Call the servlet destroy() method
-        try {
-            Thread.currentThread().setContextClassLoader(classLoader);
-            instance.destroy();
-        } catch (Throwable t) {
+        if (instance != null) {
+            ClassLoader classLoader = instance.getClass().getClassLoader();
+            
+            PrintStream out = System.out;
+            // Call the servlet destroy() method
+            try {
+                Thread.currentThread().setContextClassLoader(classLoader);
+                instance.destroy();
+            } catch (Throwable t) {
+                instance = null;
+                //instancePool = null;
+                unloading = false;
+                throw new ServletException("Servlet.destroy() " + 
+                        getServletName(), t);
+            } finally {
+                // restore the context ClassLoader
+                Thread.currentThread().setContextClassLoader(oldCtxClassLoader);
+            }
+            
+            // Deregister the destroyed instance
             instance = null;
-            instancePool = null;
-            unloading = false;
-            throw new ServletException
-                (sm.getString("standardWrapper.destroyException", getServletName()),
-                 t);
-        } finally {
-            // restore the context ClassLoader
-            Thread.currentThread().setContextClassLoader(oldCtxClassLoader);
         }
-
-        // Deregister the destroyed instance
-        instance = null;
         if (singleThreadModel && (instancePool != null)) {
             try {
+                ClassLoader classLoader = ctx.getClassLoader();
                 Thread.currentThread().setContextClassLoader(classLoader);
                 while (!instancePool.isEmpty()) {
                     ((Servlet) instancePool.pop()).destroy();
@@ -822,9 +577,7 @@
             } catch (Throwable t) {
                 instancePool = null;
                 unloading = false;
-                throw new ServletException
-                    (sm.getString("standardWrapper.destroyException",
-                                  getServletName()), t);
+                throw new ServletException("Servlet.destroy() " + getServletName(), t);
             } finally {
                 // restore the context ClassLoader
                 Thread.currentThread().setContextClassLoader
@@ -869,7 +622,7 @@
      * Return the servlet context with which this servlet is associated.
      */
     public ServletContext getServletContext() {
-        return parent;
+        return ctx;
     }
 
 
@@ -877,7 +630,7 @@
      * Return the name of this servlet.
      */
     public String getServletName() {
-        return data.serlvetName;
+        return data.servletName;
     }
 
 //    public long getProcessingTime() {
@@ -944,35 +697,6 @@
 
     // -------------------------------------------------------- Private Methods
 
-
-    /**
-     * Add a default Mapper implementation if none have been configured
-     * explicitly.
-     *
-     * @param mapperClass Java class name of the default Mapper
-     */
-    protected void addDefaultMapper(String mapperClass) {
-
-        ;       // No need for a default Mapper on a Wrapper
-
-    }
-
-
-    /**
-     * Return <code>true</code> if the specified class name represents a
-     * container provided servlet class that should be loaded by the
-     * server class loader.
-     *
-     * @param classname Name of the class to be checked
-     */
-    private boolean isContainerProvidedServlet(String classname) {
-        if (classname.startsWith("org.apache.tomcat.")) {
-            return (true);
-        }
-       return false;
-    }
-
-
     private Method[] getAllDeclaredMethods(Class c) {
 
         if (c.equals(javax.servlet.http.HttpServlet.class)) {
@@ -1000,42 +724,6 @@
 	return thisMethods;
     }
 
-
-    // ------------------------------------------------------ Lifecycle Methods
-
-
-    /**
-     * Start this component, pre-loading the servlet if the load-on-startup
-     * value is set appropriately.
-     *
-     * @exception LifecycleException if a fatal error occurs during startup
-     */
-    public void start() {
-        setAvailable(0L);
-    }
-
-
-    /**
-     * Stop this component, gracefully shutting down the servlet if it has
-     * been initialized.
-     *
-     * @exception LifecycleException if a fatal error occurs during shutdown
-     */
-    public void stop() {
-        setAvailable(Long.MAX_VALUE);        
-        // Shut down our servlet instance (if it has been initialized)
-        try {
-            unload();
-        } catch (ServletException e) {
-            getServletContext().log(sm.getString
-                      ("standardWrapper.unloadException", getServletName()), e);
-        }
-    }
-
-    public Log getLogger() {
-        return parent.getLogger();
-    }
-
     /** Specify the instance. Avoids the class lookup, disables unloading.
      *  Use for embedded case, or to control the allocation.
      * 
@@ -1043,6 +731,10 @@
      */
     public void setServlet(Servlet servlet) {
         instance = servlet;
+    }
+
+    public String getSecurityRoleRef(String role) {
+        return (String)data.securityRoleRef.get(role);
     }
 
 

Modified: tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletContextImpl.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletContextImpl.java?rev=439527&r1=439526&r2=439527&view=diff
==============================================================================
--- tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletContextImpl.java (original)
+++ tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletContextImpl.java Fri Sep  1 21:30:15 2006
@@ -21,12 +21,12 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.Serializable;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -48,11 +48,11 @@
 import javax.servlet.ServletContextListener;
 import javax.servlet.ServletException;
 
+import org.apache.catalina.util.RequestUtil;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.tomcat.lite.TomcatLite.ContextConfigData;
 import org.apache.tomcat.lite.util.CharsetMapper;
-import org.apache.tomcat.lite.util.MappingData;
 import org.apache.tomcat.lite.webmap.WebappFilterMapper;
 import org.apache.tomcat.lite.webmap.WebappServletMapper;
 import org.apache.tomcat.servlets.config.FilterData;
@@ -61,12 +61,9 @@
 import org.apache.tomcat.servlets.config.WebAppData;
 import org.apache.tomcat.servlets.deploy.WebXml;
 import org.apache.tomcat.servlets.file.WebdavServlet;
+import org.apache.tomcat.servlets.session.SessionManagerServlet;
 import org.apache.tomcat.servlets.util.Enumerator;
 import org.apache.tomcat.servlets.util.UrlUtils;
-import org.apache.tomcat.servlets.session.SessionManagerServlet;
-
-import org.apache.tomcat.util.buf.CharChunk;
-import org.apache.tomcat.util.buf.MessageBytes;
 import org.apache.tomcat.util.loader.Repository;
 import org.apache.tomcat.util.res.StringManager;
 
@@ -92,9 +89,6 @@
 
 public class ServletContextImpl implements ServletContext, Serializable {
 
-    public ServletContextImpl() {
-    }
-
     /**
      * Empty collection to serve as the basis for empty enumerations.
      * <strong>DO NOT ADD ANY ELEMENTS TO THIS COLLECTION!</strong>
@@ -167,28 +161,25 @@
 
     private WebappFilterMapper webappFilterMapper = new WebappFilterMapper(this);
 
-    /**
-     * Thread local mapping data. 
-     */
-    private transient ThreadLocal localMappingData = new ThreadLocal();
-
-    /**
-     * Thread local URI message bytes.
-     */
-    private transient ThreadLocal localUriMB = new ThreadLocal();
 
     transient CharsetMapper charsetMapper = new CharsetMapper();
 
     transient Repository repository;
     
-    transient TomcatLite facade = TomcatLite.getServletImpl();
+    transient TomcatLite facade;
 
     private WebAppData webAppData;
 
     private ContextConfigData contextConfig;
 
     // ------------------------------------------------- ServletContext Methods
-
+    public ServletContextImpl(TomcatLite facade) {
+        this.facade = facade;
+    }
+    
+    public ServletContextImpl() {
+        
+    }
 
     public CharsetMapper getCharsetMapper() {
         return charsetMapper;
@@ -395,7 +386,7 @@
      * Return the major version of the Java Servlet API that we implement.
      */
     public int getMajorVersion() {
-        return 3;
+        return 2;
     }
 
 
@@ -425,6 +416,20 @@
         return contentTypes.getProperty(extension);
     }
 
+    /**
+     * Return the real path for a given virtual path, if possible; otherwise
+     * return <code>null</code>.
+     *
+     * @param path The path to the desired resource
+     */
+    public String getRealPath(String path) {
+        if (path == null) {
+            return null;
+        }
+
+        File file = new File(basePath, path);
+        return (file.getAbsolutePath());
+    }
 
     /**
      * Return a <code>RequestDispatcher</code> object that acts as a
@@ -443,21 +448,6 @@
 
 
     /**
-     * Return the real path for a given virtual path, if possible; otherwise
-     * return <code>null</code>.
-     *
-     * @param path The path to the desired resource
-     */
-    public String getRealPath(String path) {
-        if (path == null) {
-            return null;
-        }
-
-        File file = new File(basePath, path);
-        return (file.getAbsolutePath());
-    }
-
-    /**
      * Return a <code>RequestDispatcher</code> instance that acts as a
      * wrapper for the resource at the given path.  The path must begin
      * with a "/" and is interpreted as relative to the current context root.
@@ -473,78 +463,36 @@
         path = UrlUtils.normalize(path);
         if (path == null)  return (null);
 
-        // Retrieve the thread local URI, used for mapping
-        MessageBytes uriMB = (MessageBytes) localUriMB.get();
-        if (uriMB == null) {
-            uriMB = MessageBytes.newInstance();
-            CharChunk uriCC = uriMB.getCharChunk();
-            uriCC.setLimit(-1);
-            localUriMB.set(uriMB);
-        } else {
-            uriMB.recycle();
-        }
+        
+        return new RequestDispatcherImpl(this, path);
+    }
 
-        // Get query string
-        String queryString = null;
-        int pos = path.indexOf('?');
-        if (pos >= 0) {
-            queryString = path.substring(pos + 1);
-        } else {
-            pos = path.length();
-        }
- 
-        // Retrieve the thread local mapping data
-        MappingData mappingData = (MappingData) localMappingData.get();
-        if (mappingData == null) {
-            mappingData = new MappingData();
-            localMappingData.set(mappingData);
-        }
+    public RequestDispatcher getRequestDispatcher(String path, 
+                                                  int type,
+                                                  String dispatcherPath) {
+        RequestDispatcher dispatcher = getRequestDispatcher(path);
+        //((RequestDispatcherImpl)dispatcher);
+        return dispatcher;
+    }
 
-        // Map the URI
-        CharChunk uriCC = uriMB.getCharChunk();
-        try {
-            uriCC.append(path, 0, path.length());
-            /*
-             * Ignore any trailing path params (separated by ';') for mapping
-             * purposes
-             */
-            int semicolon = path.indexOf(';');
-            if (pos >= 0 && semicolon > pos) {
-                semicolon = -1;
-            }
-            uriCC.append(path, 0, semicolon > 0 ? semicolon : pos);
-            
-            getMapper().map(uriMB, mappingData);
-            if (mappingData.wrapper == null) {
-                return null;
-            }
-            
-            /*
-             * Append any trailing path params (separated by ';') that were
-             * ignored for mapping purposes, so that they're reflected in the
-             * RequestDispatcher's requestURI
-             */
-            if (semicolon > 0) {
-                uriCC.append(path, semicolon, pos - semicolon);
-            }
-        } catch (Exception e) {
-            log("getRequestDispatcher()", e);
-            return (null);
+    ThreadLocal requestDispatcherStack = new ThreadLocal();
+    
+    private RequestDispatcherImpl getRequestDispatcher() {
+        ArrayList<RequestDispatcherImpl> list = 
+            (ArrayList)requestDispatcherStack.get();
+        if (list == null) {
+            list = new ArrayList();
+            requestDispatcherStack.set(list);
         }
-
-        ServletConfigImpl wrapper = (ServletConfigImpl) mappingData.wrapper;
-        String wrapperPath = mappingData.wrapperPath.toString();
-        String pathInfo = mappingData.pathInfo.toString();
-
-        mappingData.recycle();
-        
-        return new RequestDispatcherImpl(wrapper, uriCC.toString(), 
-                                         wrapperPath, pathInfo, 
-                                         queryString);
+        
+        
+        return null;
     }
 
-
-
+    public void resetDispatcherStack() {
+        
+    }
+    
     /**
      * Return the URL to the resource that is mapped to a specified path.
      * The path must begin with a "/" and is interpreted as relative to the
@@ -892,7 +840,8 @@
             try {
                 fc.getFilter(); // will triger init()
             } catch (Throwable e) {
-                log.warn("Error initializing filter " + fc.getFilterName(), e);
+                log.warn(getContextPath() + " Filter.init() " + 
+                        fc.getFilterName(), e);
             } 
             
         }
@@ -902,14 +851,16 @@
         while (fI.hasNext()) {
             ServletConfigImpl fc = (ServletConfigImpl)fI.next();
             if (fc.getLoadOnStartup() > 0 ) {
-            try {
-                fc.loadServlet(); 
-            } catch (Throwable e) {
-                log.warn("Error initializing  " + fc.getServletName(), e);
-            } 
+                try {
+                    fc.loadServlet(); 
+                } catch (Throwable e) {
+                    log.warn("Error initializing  " + fc.getServletName(), e);
+                } 
             }
         }
     }
+
+    public static final String INTERNAL_PREFIX = "_SERVLET_IMPL_";
     
     public void initListeners() throws ServletException {
         Iterator fI = webAppData.listenerClass.iterator();
@@ -924,7 +875,10 @@
             } 
             
         }
+        setAttribute(INTERNAL_PREFIX + ".EventListeners", lifecycleListeners);
+
     }
+    public static String CONTAINER_PREFIX = "__x_";
 
     public ClassLoader getClassLoader() {
         if( repository != null ) 
@@ -939,18 +893,30 @@
 
     public void processWebAppData(WebAppData d) throws ServletException {
         this.webAppData = d;
-        
+        initDefaults();
+            
         for(Entry<String, String> k: d.mimeMapping.entrySet()) {
             addMimeType(k.getKey(), k.getValue());
         }
         
-        getManager().setSessionTimeout(d.sessionTimeout);
+        if (d.sessionTimeout > 0 )
+            getManager().setSessionTimeout(d.sessionTimeout);
         
         for(FilterData fd: d.filters.values()) {
             addFilter(fd);
         }
         
         for(ServletData sd: d.servlets.values()) {
+            // jsp-file equivalent to JspProxyServlet + arg
+            if (sd.servletClass == null) {
+                if (sd.jspFile == null) {
+                    log.error("Missing servlet class for " + sd.servletName);
+                    continue;
+                }
+                sd.servletClass = ServletConfigImpl.JSP_SERVLET_CLASS;
+                sd.initParams.put(CONTAINER_PREFIX + "jspFile", sd.jspFile);
+            }
+             
             ServletConfigImpl sw = new ServletConfigImpl(this, sd);
             addServletConfig(sw);
         }
@@ -974,27 +940,27 @@
             }
          }
     }
+    
+    public WebAppData getConfig() {
+        return webAppData;
+    }
+    
 
     public void init() throws ServletException {
         String base = getBasePath();
         
+        Repository ctxRepo = null;
         // create a class loader
-        Repository ctxRepo = new Repository();
-        ctxRepo.setParentClassLoader(this.getClass().getClassLoader());
+        if (getContextPath().startsWith("/__x_classpath")) {
+            ctxRepo = getEngine().getRepository();
+        } else {
+            ctxRepo = new Repository();
+            ctxRepo.setParent(facade.getRepository());
+        }
         ctxRepo.addDir(new File(base + "/WEB-INF/classes"));
         ctxRepo.addLibs(new File(base + "/WEB-INF/lib"));
         setRepository(ctxRepo);
 
-        // Add default mappings.
-        ServletData sd = new ServletData();
-        sd.serlvetName = "default";
-        ServletConfigImpl fileS = new ServletConfigImpl(this, sd);
-        
-        Servlet defaultS = new WebdavServlet();
-        defaultS.init(fileS);
-        fileS.setServlet(defaultS);
-        addMapping("/", fileS);
-
         if (webAppData != null && webAppData.fileName != null) {
             File f = new File(webAppData.fileName);
             if (f.exists()) {
@@ -1008,6 +974,8 @@
             }
         }
         if (webAppData == null) {
+            // Add default mappings.
+            initDefaults();
             readWebXml(base);
             if (contextConfig != null) {
                 contextConfig.webXml = webAppData;
@@ -1042,6 +1010,23 @@
         initServlets();
     }
 
+    private void initDefaults() throws ServletException {
+        ServletData sd = new ServletData();
+        sd.servletName = "default";
+        ServletConfigImpl fileS = new ServletConfigImpl(this, sd);
+        
+        Servlet defaultS = new WebdavServlet();
+        defaultS.init(fileS);
+        fileS.setServlet(defaultS);
+        addMapping("/", fileS);
+        
+        sd = new ServletData();
+        sd.servletName = ServletConfigImpl.JSP_SERVLET_NAME;
+        fileS = new ServletConfigImpl(this, sd);
+        sd.servletClass = ServletConfigImpl.JSP_SERVLET_CLASS;
+        addMapping("*.jsp", fileS);
+    }
+
     private void readWebXml(String base) throws ServletException {
         WebXml webXml = new WebXml();
         webXml.readWebXml(base);
@@ -1074,5 +1059,117 @@
     public void setContextConfigData(ContextConfigData ctxD) {
         this.contextConfig = ctxD;
     }
+
+    public TomcatLite getEngine() {
+        return facade;
+    }
+    
+    public String findStatusPage(int status) {
+        if (getConfig().errorPageCode.size() == 0) {
+            return null;
+        }
+        if (status == 200) {
+            return null;
+        }
+
+        return getConfig().errorPageCode.get(Integer.toString(status));
+    }
+
+    public void handleStatusPage(ServletRequestImpl req, 
+                                 ServletResponseImpl res, 
+                                 int status, 
+                                 String statusPage) {
+       String message = RequestUtil.filter(res.getMessage());
+       if (message == null)
+           message = "";
+       setErrorAttributes(req, status, message);
+       dispatchError(req, res, statusPage);
+   }
+
+   private void setErrorAttributes(ServletRequestImpl req,
+                                   int status,
+                                   String message) {
+       req.setAttribute("javax.servlet.error.status_code", 
+               new Integer(status));
+       if (req.getWrapper() != null) {
+           req.setAttribute("javax.servlet.error.servlet_name", 
+                   req.getWrapper().data.servletName);
+       }
+       req.setAttribute("javax.servlet.error.request_uri", 
+               req.getRequestURI());
+       req.setAttribute("javax.servlet.error.message", 
+               message);
+
+   }
+   
+   public void handleError(ServletRequestImpl req, 
+                           ServletResponseImpl res,
+                           Throwable t) {
+       Throwable realError = t;
+       if (realError instanceof ServletException) {
+           realError = ((ServletException) realError).getRootCause();
+           if (realError == null) {
+               realError = t;
+           }
+       }
+      //if (realError instanceof ClientAbortException ) {
+
+       String errorPage = findErrorPage(t);
+       if ((errorPage == null) && (realError != t)) {
+           errorPage = findErrorPage(realError);
+       }
+
+       if (errorPage != null) {
+           setErrorAttributes(req, 500, t.getMessage());
+           req.setAttribute("javax.servlet.error.exception", realError);
+           req.setAttribute("javax.servlet.error.exception_type",
+                   realError.getClass());
+           dispatchError(req, res, errorPage);
+       } else {
+           log("Unhandled error", t);
+           if (res.getStatus() < 500) {
+               res.setStatus(500);
+           }
+       }
+   }
+
+   private void dispatchError(ServletRequestImpl req, 
+                              ServletResponseImpl res, 
+                              String errorPage) {
+       RequestDispatcher rd =
+           getRequestDispatcher(errorPage);
+       try {
+           // will clean up the buffer 
+           rd.forward(req, res);
+           return; // handled
+       } catch (ServletException e) {
+           // TODO
+       } catch (IOException e) {
+           // TODO
+       }
+   }
+   
+   protected String findErrorPage(Throwable exception) {
+       if (getConfig().errorPageException.size() == 0) {
+           return null;
+       }
+       if (exception == null)
+           return (null);
+       Class clazz = exception.getClass();
+       String name = clazz.getName();
+       while (!Object.class.equals(clazz)) {
+           String page = getConfig().errorPageException.get(name);
+           if (page != null)
+               return (page);
+           clazz = clazz.getSuperclass();
+           if (clazz == null)
+               break;
+           name = clazz.getName();
+       }
+       return (null);
+
+   }
+
+
 }
 

Modified: tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletRequestImpl.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletRequestImpl.java?rev=439527&r1=439526&r2=439527&view=diff
==============================================================================
--- tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletRequestImpl.java (original)
+++ tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletRequestImpl.java Fri Sep  1 21:30:15 2006
@@ -1404,7 +1404,11 @@
      * Return the scheme used to make this Request.
      */
     public String getScheme() {
-        return (coyoteRequest.scheme().toString());
+        String scheme = coyoteRequest.scheme().toString();
+        if (scheme == null) {
+            scheme = (isSecure() ? "https" : "http");
+        }
+        return scheme;
     }
 
 
@@ -2410,7 +2414,7 @@
 
         // Check for a role alias defined in a <security-role-ref> element
         if (wrapper != null) {
-            String realRole = wrapper.findSecurityReference(role);
+            String realRole = wrapper.getSecurityRoleRef(role);
             if (realRole != null) {
                 role = realRole;
             }

Modified: tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletResponseImpl.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletResponseImpl.java?rev=439527&r1=439526&r2=439527&view=diff
==============================================================================
--- tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletResponseImpl.java (original)
+++ tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletResponseImpl.java Fri Sep  1 21:30:15 2006
@@ -341,7 +341,9 @@
      * 
      * @param suspended The new suspended flag value
      */
-    public void setSuspended(boolean suspended) {
+    public void setSuspended(boolean suspended) throws IOException {
+        //coyoteResponse.setCommitted(true);
+        flushBuffer();
         outputBuffer.setSuspended(suspended);
     }
 
@@ -387,23 +389,6 @@
 
 
     /**
-     * Perform whatever actions are required to flush and close the output
-     * stream or writer, in a single operation.
-     *
-     * @exception IOException if an input/output error occurs
-     */
-    public void finishResponse() 
-        throws IOException {
-        // Writing leftover bytes
-        try {
-            outputBuffer.close();
-        } catch(Throwable t) {
-	    t.printStackTrace();
-        }
-    }
-
-
-    /**
      * Return the content length that was set or calculated for this Response.
      */
     public int getContentLength() {
@@ -606,8 +591,8 @@
 
     /**
      * Set the content length (in bytes) for this Response.
-     *
-     * @param length The new content length
+     * Ignored for writers if non-ISO-8859-1 encoding ( we could add more 
+     * encodings that are constant.
      */
     public void setContentLength(int length) {
 
@@ -618,9 +603,10 @@
         if (included)
             return;
         
-        if (usingWriter)
+        // writers can use variable-length encoding. 
+        if (usingWriter && !"ISO-8859-1".equals(getCharacterEncoding())) {
             return;
-        
+        }
         coyoteResponse.setContentLength(length);
 
     }
@@ -1081,22 +1067,24 @@
         if (included)
             return; 
 
-//        Wrapper wrapper = getRequest().getWrapper();
-//        if (wrapper != null) {
-//            wrapper.incrementErrorCount();
-//        } 
-
         setError();
 
         coyoteResponse.setStatus(status);
         coyoteResponse.setMessage(message);
 
-        // Clear any data content that has been buffered
-        resetBuffer();
-
-        // Cause the response to be finished (from the application perspective)
-        setSuspended(true);
+        // Now go over the error-page handling - 
+        String statusPage = request.getContext().findStatusPage(status);
+        
+        if (statusPage != null) {
+            request.getContext().handleStatusPage(request, 
+                    this, status, statusPage);
+        } else {
+            // Clear any data content that has been buffered
+            resetBuffer();
 
+            // Cause the response to be finished (from the application perspective)
+            setSuspended(true);
+        }
     }
 
 
@@ -1432,11 +1420,6 @@
         sb.append(query);
         return (sb.toString());
 
-    }
-
-    public void finish() {
-
-        setSuspended(true);
     }
 
 

Added: tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletResponseIncludeWrapper.java
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletResponseIncludeWrapper.java?rev=439527&view=auto
==============================================================================
--- tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletResponseIncludeWrapper.java (added)
+++ tomcat/sandbox/tomcat-lite/java/org/apache/tomcat/lite/ServletResponseIncludeWrapper.java Fri Sep  1 21:30:15 2006
@@ -0,0 +1,120 @@
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ * 
+ * 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.
+ */
+
+
+package org.apache.tomcat.lite;
+
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Locale;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+import org.apache.tomcat.util.res.StringManager;
+
+
+/**
+ * Wrapper around the response object received as parameter to 
+ * RequestDispatcher.include().
+ * 
+ * @author Costin Manolache
+ */
+public class ServletResponseIncludeWrapper extends HttpServletResponseWrapper {
+    public ServletResponseIncludeWrapper(ServletResponse current) {
+        super((HttpServletResponse) current);
+    }
+
+    // Not overriden:
+    /*
+    public boolean containsHeader(String name)
+    public String encodeRedirectUrl(String url)
+    public String encodeRedirectURL(String url)
+    public String encodeUrl(String url)
+    public String encodeURL(String url)
+    public void flushBuffer() throws IOException
+    public int getBufferSize()
+    public String getCharacterEncoding()
+    public String getContentType()
+    public Locale getLocale()
+    public ServletOutputStream getOutputStream() throws IOException
+    public ServletResponse getResponse()
+    public PrintWriter getWriter() throws IOException
+    public boolean isCommitted()
+    public void resetBuffer()
+    public void setCharacterEncoding(String charset)
+    public void setResponse(ServletResponse response)
+     */
+    
+    public void reset() {
+        if (getResponse().isCommitted())
+            getResponse().reset(); 
+        else
+            throw new IllegalStateException();
+    }
+
+    public void setContentLength(int len) {
+    }
+
+    public void setContentType(String type) {
+    }
+
+    public void setLocale(Locale loc) {
+    }
+
+    public void setBufferSize(int size) {
+    }
+
+    public void addCookie(Cookie cookie) {
+    }
+
+    public void addDateHeader(String name, long value) {
+    }
+
+    public void addHeader(String name, String value) {
+    }
+
+    public void addIntHeader(String name, int value) {
+    }
+
+    public void sendError(int sc) throws IOException {
+    }
+
+    public void sendError(int sc, String msg) throws IOException {
+    }
+
+    public void sendRedirect(String location) throws IOException {
+    }
+
+    public void setDateHeader(String name, long value) {
+    }
+
+    public void setHeader(String name, String value) {
+    }
+
+    public void setIntHeader(String name, int value) {
+    }
+
+    public void setStatus(int sc) {
+    }
+
+    public void setStatus(int sc, String msg) {
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org