Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * 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.catalina.core;
  
  import static org.jboss.web.CatalinaMessages.MESSAGES;
  
  
  
Standard implementation of RequestDispatcher 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 javax.servlet.ServletRequestWrapper and javax.servlet.ServletResponseWrapper.

Author(s):
Craig R. McClanahan
Version:
$Revision: 1965 $ $Date: 2012-02-15 10:14:38 +0100 (Wed, 15 Feb 2012) $
  
  
  public final class ApplicationDispatcher
      implements RequestDispatcher {
  
  
      protected class PrivilegedForward implements PrivilegedExceptionAction {
          private ServletRequest request;
          private ServletResponse response;
  
          PrivilegedForward(ServletRequest requestServletResponse response)
          {
              this. = request;
              this. = response;
          }
  
          public Object run() throws java.lang.Exception {
              doForward(,);
              return null;
          }
      }
  
      protected class PrivilegedInclude implements PrivilegedExceptionAction {
          private ServletRequest request;
          private ServletResponse response;
  
          PrivilegedInclude(ServletRequest requestServletResponse response)
          {
              this. = request;
              this. = response;
          }
  
          public Object run() throws ServletExceptionIOException {
             doInclude(,);
             return null;
         }
     }
 
     protected class PrivilegedInvoke implements PrivilegedExceptionAction {
         private ServletRequest request;
         private ServletResponse response;
 
         PrivilegedInvoke(ServletRequest requestServletResponse response)
         {
             this. = request;
             this. = response;
         }
 
         public Object run() throws ServletExceptionIOException {
             doInvoke(,);
             return null;
         }
     }
 
     protected class PrivilegedAsync implements PrivilegedExceptionAction {
         private ServletRequest request;
         private ServletResponse response;
         private boolean attributes;
 
         PrivilegedAsync(ServletRequest requestServletResponse responseboolean attributes)
         {
             this. = request;
             this. = response;
             this. = attributes;
         }
 
         public Object run() throws ServletExceptionIOException {
             doAsync();
             return null;
         }
     }

    
    
Used to pass state when the request dispatcher is used. Using instance variables causes threading issues and state is too complex to pass and return single ServletRequest or ServletResponse objects.
 
     private static class State {
         State(ServletRequest requestServletResponse response,
                 boolean including) {
             this. = request;
             this. = response;
             this. = including;
         }

        
The outermost request that will be passed on to the invoked servlet.
 
         ServletRequest outerRequest = null;


        
The outermost response that will be passed on to the invoked servlet.
 
         ServletResponse outerResponse = null;
        
        
The request wrapper we have created and installed (if any).
 
         ServletRequest wrapRequest = null;


        
The response wrapper we have created and installed (if any).
 
         ServletResponse wrapResponse = null;
        
        
Are we performing an include() instead of a forward()?
 
         boolean including = false;

        
Outer most HttpServletRequest in the chain
 
         HttpServletRequest hrequest = null;

        
Outermost HttpServletResponse in the chain
 
         HttpServletResponse hresponse = null;
     }
 
     // ----------------------------------------------------------- Constructors
 

    
Construct a new instance of this class, configured according to the specified parameters. If both servletPath and pathInfo are null, it will be assumed that this RequestDispatcher was acquired by name, rather than by path.

Parameters:
wrapper The Wrapper associated with the resource that will be forwarded to or included (required)
requestURI The request URI to this resource (if any)
requestPath The revised path to this resource, relative to the context (if any)
servletPath The revised servlet path to this resource (if any)
pathInfo The revised extra path information to this resource (if any)
queryString Query string parameters included with this request (if any)
name Servlet name (if a named dispatcher was created) else null
 
     public ApplicationDispatcher
         (Wrapper wrapperString requestURIString requestPathString servletPath,
          String pathInfoString queryStringString name) {
 
         super();
 
         // Save all of our configuration parameters
         this. = wrapper;
         this. = (Contextwrapper.getParent();
         this. = requestURI;
         this. = requestPath;
         this. = servletPath;
         this. = pathInfo;
         this. = queryString;
         this. = name;
         this. = wrapper.getInstanceSupport();
 
     }
 
 
     // ----------------------------------------------------- Instance Variables
 
    
The Context this RequestDispatcher is associated with.
 
     private Context context = null;


    
Descriptive information about this implementation.
 
     private static final String info =
         "org.apache.catalina.core.ApplicationDispatcher/1.0";


    
The servlet name for a named dispatcher.
 
     private String name = null;


    
The extra path information for this RequestDispatcher.
 
     private String pathInfo = null;


    
The query string parameters for this RequestDispatcher.
 
     private String queryString = null;


    
The request path for this RequestDispatcher.
 
     private String requestPath = null;


    
The request URI for this RequestDispatcher.
 
     private String requestURI = null;


    
The servlet path for this RequestDispatcher.
 
     private String servletPath = null;


    
The InstanceSupport instance associated with our Wrapper (used to send "before dispatch" and "after dispatch" events.
 
     private InstanceSupport support = null;


    
The Wrapper associated with the resource that will be forwarded to or included.
 
     private Wrapper wrapper = null;
 
 
     // ------------------------------------------------------------- Properties
 

    
Return the descriptive information about this implementation.
 
     public String getInfo() {
 
         return ();
 
     }
 
 
     // --------------------------------------------------------- Public Methods
 

    
Batch forward this request and response to another resource for processing. Any runtime exception, IOException, or ServletException thrown by the called servlet will be propogated to the caller. This acts like a straight invacation, using the REQUEST mapping.

Parameters:
request The servlet request to be forwarded
response The servlet response to be forwarded
Throws:
java.io.IOException if an input/output error occurs
javax.servlet.ServletException if a servlet exception occurs
 
     public void invoke(ServletRequest requestServletResponse response)
         throws ServletExceptionIOException
     {
         if (.) {
             try {
                 AccessController.doPrivileged(new PrivilegedInvoke(requestresponse));
             } catch (PrivilegedActionException pe) {
                 Exception e = pe.getException();
                 if (e instanceof ServletException)
                     throw (ServletExceptione;
                 throw (IOExceptione;
             }
         } else {
             doInvoke(request,response);
         }
     }
 
     private void doInvoke(ServletRequest requestServletResponse response)
         throws ServletExceptionIOException
     {
 
         // Set up to handle the specified request and response
         State state = new State(requestresponsefalse);
 
         if (.) {
             // Check SRV.8.2 / SRV.14.2.5.1 compliance
             checkSameObjects(requestresponse);
         }
 
         wrapResponse(state);
         ApplicationHttpRequest wrequest = (ApplicationHttpRequestwrapRequest(state);
         String contextPath = .getPath();
         wrequest.setContextPath(contextPath);
         wrequest.setRequestURI();
         wrequest.setServletPath();
         wrequest.setPathInfo();
         if ( != null) {
             wrequest.setQueryString();
             wrequest.setQueryParams();
         }
 
         state.outerRequest.setAttribute
                 );
         state.outerRequest.setAttribute
                     .);
         invoke(state.outerRequestresponsestate);
 
     }


    
Async forward this request and response to another resource for processing. Any runtime exception, IOException, or ServletException thrown by the called servlet will be propogated to the caller.

Parameters:
request The servlet request to be forwarded
response The servlet response to be forwarded
Throws:
java.io.IOException if an input/output error occurs
javax.servlet.ServletException if a servlet exception occurs
 
     public void async(ServletRequest requestServletResponse responseboolean attributes)
         throws ServletExceptionIOException
     {
         if (.) {
             try {
                 AccessController.doPrivileged(new PrivilegedAsync(requestresponseattributes));
             } catch (PrivilegedActionException pe) {
                 Exception e = pe.getException();
                 if (e instanceof ServletException)
                     throw (ServletExceptione;
                 throw (IOExceptione;
             }
         } else {
             doAsync(request,responseattributes);
         }
     }
 
     private void doAsync(ServletRequest requestServletResponse responseboolean attributes)
         throws ServletExceptionIOException
     {
 
         // Set up to handle the specified request and response
         State state = new State(requestresponsefalse);
 
         if (.) {
             // Check SRV.8.2 / SRV.14.2.5.1 compliance
             checkSameObjects(requestresponse);
         }
 
         if (attributes) {
             wrapResponse(state);
             ApplicationHttpRequest wrequest =
                 (ApplicationHttpRequestwrapRequest(state);
             String contextPath = .getPath();
             HttpServletRequest hrequest = state.hrequest;
             if (hrequest.getAttribute(.) == null) {
                 wrequest.setAttribute(.,
                         hrequest.getRequestURI());
                 wrequest.setAttribute(.,
                         hrequest.getContextPath());
                 wrequest.setAttribute(.,
                         hrequest.getServletPath());
                 wrequest.setAttribute(.,
                         hrequest.getPathInfo());
                 wrequest.setAttribute(.,
                         hrequest.getQueryString());
             }
 
             wrequest.setContextPath(contextPath);
             wrequest.setRequestURI();
             wrequest.setServletPath();
             wrequest.setPathInfo();
             if ( != null) {
                 wrequest.setQueryString();
                 wrequest.setQueryParams();
             }
         }
 
         state.outerRequest.setAttribute
                 );
         state.outerRequest.setAttribute
                     .);
         invoke(state.outerRequestresponsestate);
 
     }


    
Forward this request and response to another resource for processing. Any runtime exception, IOException, or ServletException thrown by the called servlet will be propogated to the caller.

Parameters:
request The servlet request to be forwarded
response The servlet response to be forwarded
Throws:
java.io.IOException if an input/output error occurs
javax.servlet.ServletException if a servlet exception occurs
 
     public void forward(ServletRequest requestServletResponse response)
         throws ServletExceptionIOException
     {
         if (.) {
             try {
                 PrivilegedForward dp = new PrivilegedForward(request,response);
                 AccessController.doPrivileged(dp);
             } catch (PrivilegedActionException pe) {
                 Exception e = pe.getException();
                 if (e instanceof ServletException)
                     throw (ServletExceptione;
                 throw (IOExceptione;
             }
         } else {
             doForward(request,response);
         }
     }
 
     private void doForward(ServletRequest requestServletResponse response)
         throws ServletExceptionIOException
     {
         
         // Reset any output that has been buffered, but keep headers/cookies
         if (response.isCommitted()) {
             throw .cannotForwardAfterCommit();
         }
         try {
             response.resetBuffer();
         } catch (IllegalStateException e) {
             throw e;
         }
 
         // Set up to handle the specified request and response
         State state = new State(requestresponsefalse);
 
         if (.) {
             // Check SRV.8.2 / SRV.14.2.5.1 compliance
             checkSameObjects(requestresponse);
         }
 
         wrapResponse(state);
         // Handle an HTTP named dispatcher forward
         if (( == null) && ( == null)) {
 
             ApplicationHttpRequest wrequest =
                 (ApplicationHttpRequestwrapRequest(state);
             HttpServletRequest hrequest = state.hrequest;
             wrequest.setRequestURI(hrequest.getRequestURI());
             wrequest.setContextPath(hrequest.getContextPath());
             wrequest.setServletPath(hrequest.getServletPath());
             wrequest.setPathInfo(hrequest.getPathInfo());
             wrequest.setQueryString(hrequest.getQueryString());
 
             processRequest(request,response,state);
         }
 
         // Handle an HTTP path-based forward
         else {
 
             ApplicationHttpRequest wrequest =
                 (ApplicationHttpRequestwrapRequest(state);
             String contextPath = .getPath();
             HttpServletRequest hrequest = state.hrequest;
             if (hrequest.getAttribute(.) == null) {
                 wrequest.setAttribute(.,
                                       hrequest.getRequestURI());
                 wrequest.setAttribute(.,
                                       hrequest.getContextPath());
                 wrequest.setAttribute(.,
                                       hrequest.getServletPath());
                 wrequest.setAttribute(.,
                                       hrequest.getPathInfo());
                 wrequest.setAttribute(.,
                                       hrequest.getQueryString());
             }
  
             wrequest.setContextPath(contextPath);
             wrequest.setRequestURI();
             wrequest.setServletPath();
             wrequest.setPathInfo();
             if ( != null) {
                 wrequest.setQueryString();
                 wrequest.setQueryParams();
             }
 
             processRequest(request,response,state);
         }
 
         // During async, the response will not be closed after a forward
         if (request.getAsyncContext() != null) {
             return;
         }
 
         // This is not a real close in order to support error processing
         if (.getLogger().isDebugEnabled() )
             .getLogger().debug(" Disabling the response for futher output");
 
         if  (response instanceof ResponseFacade) {
             ((ResponseFacaderesponse).finish();
         } else {
             // Servlet SRV.6.2.2. The Resquest/Response may have been wrapped
             // and may no longer be instance of RequestFacade 
             if (.getLogger().isDebugEnabled()){
                 .getLogger().debug" The Response is vehiculed using a wrapper: " 
                            + response.getClass().getName() );
             }
 
             // Close anyway
             try {
                 PrintWriter writer = response.getWriter();
                 writer.close();
             } catch (IllegalStateException e) {
                 try {
                     ServletOutputStream stream = response.getOutputStream();
                     stream.close();
                 } catch (IllegalStateException f) {
                     ;
                 } catch (IOException f) {
                     ;
                 }
             } catch (IOException e) {
                 ;
             }
         }
 
     }

    
    
Prepare the request based on the filter configuration.

Parameters:
request The servlet request we are processing
response The servlet response we are creating
state The RD state
Throws:
java.io.IOException if an input/output error occurs
javax.servlet.ServletException if a servlet error occurs
 
     private void processRequest(ServletRequest request
                                 ServletResponse response,
                                 State state)
         throws IOExceptionServletException {
                 
         Integer disInt = (Integerrequest.getAttribute
         if (disInt != null) {
             if (disInt != .) {
                 state.outerRequest.setAttribute
                     (.,
                      );
                 state.outerRequest.setAttribute
                     (.,
                      .);
                 invoke(state.outerRequestresponsestate);
             } else {
                 invoke(state.outerRequestresponsestate);
             }
         }
 
     }
    
    
    
Include the response from another resource in the current response. Any runtime exception, IOException, or ServletException thrown by the called servlet will be propogated to the caller.

Parameters:
request The servlet request that is including this one
response The servlet response to be appended to
Throws:
java.io.IOException if an input/output error occurs
javax.servlet.ServletException if a servlet exception occurs
 
     public void include(ServletRequest requestServletResponse response)
         throws ServletExceptionIOException
     {
         if (.) {
             try {
                 PrivilegedInclude dp = new PrivilegedInclude(request,response);
                 AccessController.doPrivileged(dp);
             } catch (PrivilegedActionException pe) {
                 Exception e = pe.getException();
 
                 if (e instanceof ServletException)
                     throw (ServletExceptione;
                 throw (IOExceptione;
             }
         } else {
             doInclude(request,response);
         }
     }
 
     private void doInclude(ServletRequest requestServletResponse response)
         throws ServletExceptionIOException
     {
         // Set up to handle the specified request and response
         State state = new State(requestresponsetrue);
 
         if (.) {
             // Check SRV.8.2 / SRV.14.2.5.1 compliance
             checkSameObjects(requestresponse);
         }
         
         // Create a wrapped response to use for this request
         wrapResponse(state);
 
         // Handle an HTTP named dispatcher include
         if ( != null) {
 
             ApplicationHttpRequest wrequest =
                 (ApplicationHttpRequestwrapRequest(state);
             wrequest.setAttribute(.);
             if ( != null)
                 wrequest.setServletPath();
                     .);
             wrequest.setAttribute(
                     .,
                     );
             invoke(state.outerRequeststate.outerResponsestate);
         }
 
         // Handle an HTTP path based include
         else {
 
             ApplicationHttpRequest wrequest =
                 (ApplicationHttpRequestwrapRequest(state);
             String contextPath = .getPath();
             if ( != null)
                 wrequest.setAttribute(.,
                                       );
             if (contextPath != null)
                 wrequest.setAttribute(.,
                                       contextPath);
             if ( != null)
                 wrequest.setAttribute(.,
                                       );
             if ( != null)
                 wrequest.setAttribute(.,
                                       );
             if ( != null) {
                 wrequest.setAttribute(.,
                                       );
                 wrequest.setQueryParams();
             }
             
                     .);
             wrequest.setAttribute(
                     .,
                     );
             invoke(state.outerRequeststate.outerResponsestate);
         }
 
     }
 
 
     // -------------------------------------------------------- Private Methods
 

    
Ask the resource represented by this RequestDispatcher to process the associated request, and create (or append to) the associated response.

IMPLEMENTATION NOTE: This implementation assumes that no filters are applied to a forwarded or included resource, because they were already done for the original request.

Parameters:
request The servlet request we are processing
response The servlet response we are creating
Throws:
java.io.IOException if an input/output error occurs
javax.servlet.ServletException if a servlet error occurs
 
     private void invoke(ServletRequest requestServletResponse response,
             State statethrows IOExceptionServletException {
 
         // Initialize local variables we may need
         HttpServletResponse hresponse = state.hresponse;
         Servlet servlet = null;
         IOException ioException = null;
         ServletException servletException = null;
         RuntimeException runtimeException = null;
         boolean unavailable = false;
 
         // Checking to see if the context classloader is the current context
         // 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 = .getLoader().getClassLoader();
 
         ServletRequestEvent event = null;
         Object instances[] = .getApplicationEventListeners();
         if (oldCCL != contextClassLoader) {
             // Enter application scope
             Thread.currentThread().setContextClassLoader(contextClassLoader);
             .getThreadBindingListener().bind();
             if (instances != null && (instances.length > 0)) {
                 event = new ServletRequestEvent(.getServletContext(), request);
                 // create pre-service event
                 for (int i = 0; i < instances.lengthi++) {
                     if (instances[i] == null)
                         continue;
                     if (!(instances[iinstanceof ServletRequestListener))
                         continue;
                     ServletRequestListener listener = (ServletRequestListenerinstances[i];
                     try {
                         listener.requestInitialized(event);
                     } catch (Throwable t) {
                         .getLogger().error
                             (.requestListenerInitException(instances[i].getClass().getName()), t);
                         request.setAttribute(.t);
                         servletException = new ServletException
                             (.requestListenerInitException(instances[i].getClass().getName()), t);
                     }
                 }
             }
         } else {
             oldCCL = null;
         }
 
         // Check for the servlet being marked unavailable
         if (.isUnavailable()) {
             long available = .getAvailable();
             if ((available > 0L) && (available < .))
                 hresponse.setDateHeader("Retry-After"available);
             hresponse.sendError(.
                     .servletIsUnavailable(.getName()));
             unavailable = true;
         }
 
         // Allocate a servlet instance to process this request
         try {
             if (!unavailable) {
                 servlet = .allocate();
             }
         } catch (ServletException e) {
                     StandardWrapper.getRootCause(e));
             servletException = e;
             servlet = null;
         } catch (Throwable e) {
             servletException = new ServletException
                 (.servletAllocateException(.getName()), e);
             servlet = null;
         }
                 
         // Get the FilterChain Here
         ApplicationFilterFactory factory = ApplicationFilterFactory.getInstance();
         ApplicationFilterChain filterChain = factory.createFilterChain(requestservlet);
         // Call the service() method for the allocated servlet instance
         String jspFile = .getJspFile();
         try {
             if (jspFile != null) {
                 request.setAttribute(.jspFile);
             } else {
                 request.removeAttribute(.);
             }
                                       servletrequestresponse);
             // for includes/forwards
             if ((servlet != null) && (filterChain != null)) {
                 filterChain.doFilter(requestresponse);
             }
             // Servlet Service Method is called by the FilterChain
         } catch (ClientAbortException e) {
             ioException = e;
         } catch (IOException e) {
             ioException = e;
         } catch (UnavailableException e) {
             servletException = e;
             .unavailable(e);
         } catch (ServletException e) {
             Throwable rootCause = StandardWrapper.getRootCause(e);
             if (!(rootCause instanceof ClientAbortException)) {
                 .getLogger().error(.servletServiceException(.getName()), rootCause);
             }
             servletException = e;
         } catch (RuntimeException e) {
             runtimeException = e;
         } finally {
             if (jspFile != null) {
                 request.removeAttribute(.);
             }
                                       servletrequestresponse);
         }
 
         // Release the filter chain (if any) for this request
         if (filterChain != null)
             filterChain.release();
 
         // Deallocate the allocated servlet instance
         try {
             if (servlet != null) {
                 .deallocate(servlet);
             }
         } catch (ServletException e) {
             servletException = e;
         } catch (Throwable e) {
             servletException = new ServletException
                 (.servletDeallocateException(.getName()), e);
         }
 
 
         // Reset the old context class loader
         if (oldCCL != null) {
             // Exit application scope
             if (instances != null && (instances.length > 0)) {
                 // create post-service event
                 for (int i = instances.length - 1; i >= 0; i--) {
                     if (instances[i] == null)
                         continue;
                     if (!(instances[iinstanceof ServletRequestListener))
                         continue;
                     ServletRequestListener listener = (ServletRequestListenerinstances[i];
                     try {
                         listener.requestDestroyed(event);
                     } catch (Throwable t) {
                         .getLogger().error(.requestListenerDestroyException(instances[i].getClass().getName()), t);
                         request.setAttribute(.t);
                         servletException = new ServletException
                             (.requestListenerDestroyException(instances[i].getClass().getName()), t);
                     }
                 }
             }
             .getThreadBindingListener().unbind();
             Thread.currentThread().setContextClassLoader(oldCCL);
         }
 
         // Unwrap request/response if needed
         // See Bugzilla 30949
         unwrapRequest(state);
         unwrapResponse(state);
         // Recycle request if necessary (also BZ 30949)
         recycleRequestWrapper(state);
         
         // Rethrow an exception if one was thrown by the invoked servlet
         if (ioException != null)
             throw ioException;
         if (servletException != null)
             throw servletException;
         if (runtimeException != null)
             throw runtimeException;
 
     }


    
Unwrap the request if we have wrapped it.
 
     private void unwrapRequest(State state) {
 
         if (state.wrapRequest == null)
             return;
 
         ServletRequest previous = null;
         ServletRequest current = state.outerRequest;
         while (current != null) {
 
             // If we run into the container request we are done
             if ((current instanceof Request)
                 || (current instanceof RequestFacade))
                 break;
 
             // Remove the current request if it is our wrapper
             if (current == state.wrapRequest) {
                 ServletRequest next =
                   ((ServletRequestWrappercurrent).getRequest();
                 if (previous == null)
                     state.outerRequest = next;
                 else
                     ((ServletRequestWrapperprevious).setRequest(next);
                 break;
             }
 
             // Advance to the next request in the chain
             previous = current;
             current = ((ServletRequestWrappercurrent).getRequest();
 
         }
 
     }


    
Unwrap the response if we have wrapped it.
 
     private void unwrapResponse(State state) {
 
         if (state.wrapResponse == null)
             return;
 
         ServletResponse previous = null;
         ServletResponse current = state.outerResponse;
         while (current != null) {
 
             // If we run into the container response we are done
             if ((current instanceof Response)
                 || (current instanceof ResponseFacade))
                 break;
 
             // Remove the current response if it is our wrapper
             if (current == state.wrapResponse) {
                 ServletResponse next =
                   ((ServletResponseWrappercurrent).getResponse();
                 if (previous == null)
                     state.outerResponse = next;
                 else
                     ((ServletResponseWrapperprevious).setResponse(next);
                 break;
             }
 
             // Advance to the next response in the chain
             previous = current;
             current = ((ServletResponseWrappercurrent).getResponse();
 
         }
 
     }


    
Create and return a request wrapper that has been inserted in the appropriate spot in the request chain.
    private ServletRequest wrapRequest(State state) {
        // Locate the request we should insert in front of
        ServletRequest previous = null;
        ServletRequest current = state.outerRequest;
        while (current != null) {
            if(state.hrequest == null && (current instanceof HttpServletRequest))
                state.hrequest = (HttpServletRequest)current;
            if (!(current instanceof ServletRequestWrapper))
                break;
            if (current instanceof ApplicationHttpRequest)
                break;
            if (current instanceof ApplicationRequest)
                break;
            previous = current;
            current = ((ServletRequestWrappercurrent).getRequest();
        }
        // Instantiate a new wrapper at this point and insert it in the chain
        ServletRequest wrapper = null;
        if ((current instanceof ApplicationHttpRequest) ||
            (current instanceof HttpServletRequest)) {
            // Compute a crossContext flag
            HttpServletRequest hcurrent = (HttpServletRequestcurrent;
            boolean crossContext = false;
            if (state.outerRequest instanceof HttpServletRequest) {
                HttpServletRequest houterRequest = 
                    (HttpServletRequeststate.outerRequest;
                Object contextPath = houterRequest.getAttribute
                    (.);
                if (contextPath == null) {
                    // Forward
                    contextPath = houterRequest.getContextPath();
                }
                crossContext = !(.getPath().equals(contextPath));
            }
            wrapper = new ApplicationHttpRequest
                (hcurrentcrossContext);
        } else {
            wrapper = new ApplicationRequest(current);
        }
        if (previous == null)
            state.outerRequest = wrapper;
        else
            ((ServletRequestWrapperprevious).setRequest(wrapper);
        state.wrapRequest = wrapper;
        return (wrapper);
    }


    
Create and return a response wrapper that has been inserted in the appropriate spot in the response chain.
    private ServletResponse wrapResponse(State state) {
        // Locate the response we should insert in front of
        ServletResponse previous = null;
        ServletResponse current = state.outerResponse;
        while (current != null) {
            if(state.hresponse == null && (current instanceof HttpServletResponse)) {
                state.hresponse = (HttpServletResponse)current;
                if(!state.including// Forward only needs hresponse
                    return null;
            }
            if (!(current instanceof ServletResponseWrapper))
                break;
            if (current instanceof ApplicationHttpResponse)
                break;
            if (current instanceof ApplicationResponse)
                break;
            previous = current;
            current = ((ServletResponseWrappercurrent).getResponse();
        }
        // Instantiate a new wrapper at this point and insert it in the chain
        ServletResponse wrapper = null;
        if (current instanceof HttpServletResponse) {
            wrapper =
                new ApplicationHttpResponse((HttpServletResponsecurrent,
                        state.including);
        } else {
            wrapper = new ApplicationResponse(currentstate.including);
        }
        if (previous == null)
            state.outerResponse = wrapper;
        else
            ((ServletResponseWrapperprevious).setResponse(wrapper);
        state.wrapResponse = wrapper;
        return (wrapper);
    }
    private void checkSameObjects(ServletRequest appRequest,
            ServletResponse appResponsethrows ServletException {
        ServletRequest originalRequest =
            ApplicationFilterChain.getLastServicedRequest();
        ServletResponse originalResponse =
            ApplicationFilterChain.getLastServicedResponse();
        
        // Some forwards, eg from valves will not set original values 
        if (originalRequest == null || originalResponse == null) {
            return;
        }
        
        boolean same = false;
        ServletRequest dispatchedRequest = appRequest;
        
        //find the request that was passed into the service method
        while (originalRequest instanceof ServletRequestWrapper &&
                ((ServletRequestWrapperoriginalRequest).getRequest()!=null ) {
            originalRequest =
                ((ServletRequestWrapperoriginalRequest).getRequest();
        }
        //compare with the dispatched request
        while (!same) {
            if (originalRequest.equals(dispatchedRequest)) {
                same = true;
            }
            if (!same && dispatchedRequest instanceof ServletRequestWrapper) {
                dispatchedRequest =
                    ((ServletRequestWrapperdispatchedRequest).getRequest();
            } else {
                break;
            }
        }
        if (!same) {
            throw new ServletException(.notOriginalRequestInDispatcher());
        }
        
        same = false;
        ServletResponse dispatchedResponse = appResponse;
        
        //find the response that was passed into the service method
        while (originalResponse instanceof ServletResponseWrapper &&
                ((ServletResponseWrapperoriginalResponse).getResponse() != 
                    null ) {
            originalResponse =
                ((ServletResponseWrapperoriginalResponse).getResponse();
        }
        //compare with the dispatched response
        while (!same) {
            if (originalResponse.equals(dispatchedResponse)) {
                same = true;
            }
            
            if (!same && dispatchedResponse instanceof ServletResponseWrapper) {
                dispatchedResponse =
                    ((ServletResponseWrapperdispatchedResponse).getResponse();
            } else {
                break;
            }
        }
        if (!same) {
            throw new ServletException(.notOriginalResponseInDispatcher());