Added: tomcat/sandbox/java/org/apache/coyote/servlet/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/coyote/servlet/LocalStrings.properties?rev=407939&view=auto ============================================================================== --- tomcat/sandbox/java/org/apache/coyote/servlet/LocalStrings.properties (added) +++ tomcat/sandbox/java/org/apache/coyote/servlet/LocalStrings.properties Fri May 19 19:12:51 2006 @@ -0,0 +1,187 @@ +applicationContext.attributeEvent=Exception thrown by attributes event listener +applicationContext.mapping.error=Error during mapping +applicationContext.requestDispatcher.iae=Path {0} does not start with a "/" character +applicationContext.resourcePaths.iae=Path {0} does not start with a "/" character +applicationContext.setAttribute.namenull=Name cannot be null +applicationDispatcher.allocateException=Allocate exception for servlet {0} +applicationDispatcher.deallocateException=Deallocate exception for servlet {0} +applicationDispatcher.forward.ise=Cannot forward after response has been committed +applicationDispatcher.forward.throw=Forwarded resource threw an exception +applicationDispatcher.include.throw=Included resource threw an exception +applicationDispatcher.isUnavailable=Servlet {0} is currently unavailable +applicationDispatcher.serviceException=Servlet.service() for servlet {0} threw exception +applicationRequest.badParent=Cannot locate parent Request implementation +applicationRequest.badRequest=Request is not a javax.servlet.ServletRequestWrapper +applicationResponse.badParent=Cannot locate parent Response implementation +applicationResponse.badResponse=Response is not a javax.servlet.ServletResponseWrapper +aprListener.aprInit=The Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: {0} +aprListener.tcnInvalid=An incompatible version {0} of the Apache Tomcat Native library is installed, while Tomcat requires version {1} +aprListener.aprDestroy=Failed shutdown of Apache Portable Runtime +containerBase.addDefaultMapper=Exception configuring default mapper of class {0} +containerBase.alreadyStarted=Container {0} has already been started +containerBase.notConfigured=No basic Valve has been configured +containerBase.notStarted=Container {0} has not been started +containerBase.backgroundProcess.cluster=Exception processing cluster {0} background process +containerBase.backgroundProcess.loader=Exception processing loader {0} background process +containerBase.backgroundProcess.manager=Exception processing manager {0} background process +containerBase.backgroundProcess.realm=Exception processing realm {0} background process +containerBase.backgroundProcess.valve=Exception processing valve {0} background process +fastEngineMapper.alreadyStarted=FastEngineMapper {0} has already been started +fastEngineMapper.notStarted=FastEngineMapper {0} has not yet been started +filterChain.filter=Filter execution threw an exception +filterChain.servlet=Servlet execution threw an exception +httpContextMapper.container=This container is not a StandardContext +httpEngineMapper.container=This container is not a StandardEngine +httpHostMapper.container=This container is not a StandardHost +interceptorValve.alreadyStarted=InterceptorValve has already been started +interceptorValve.notStarted=InterceptorValve has not yet been started +naming.bindFailed=Failed to bind object: {0} +naming.jmxRegistrationFailed=Failed to register in JMX: {0} +naming.unbindFailed=Failed to unbind object: {0} +naming.invalidEnvEntryType=Environment entry {0} has an invalid type +naming.invalidEnvEntryValue=Environment entry {0} has an invalid value +naming.namingContextCreationFailed=Creation of the naming context failed: {0} +standardContext.invalidWrapperClass={0} is not a subclass of StandardWrapper +standardContext.alreadyStarted=Context has already been started +standardContext.applicationListener=Error configuring application listener of class {0} +standardContext.applicationSkipped=Skipped installing application listeners due to previous error(s) +standardContext.badRequest=Invalid request path ({0}). +standardContext.crlfinurl=The URL pattern "{0}" contains a CR or LF and so can never be matched. +standardContext.errorPage.error=Error page location {0} must start with a ''/'' +standardContext.errorPage.required=ErrorPage cannot be null +standardContext.errorPage.warning=WARNING: Error page location {0} must start with a ''/'' in Servlet 2.4 +standardContext.filterMap.either=Filter mapping must specify either a <url-pattern> or a <servlet-name> +standardContext.filterMap.name=Filter mapping specifies an unknown filter name {0} +standardContext.filterMap.pattern=Invalid <url-pattern> {0} in filter mapping +standardContext.filterStart=Exception starting filter {0} +standardContext.filterStartFailed=Failed to start application Filters successfully +standardContext.requestListenerStartFailed=Failed to start request listener valve successfully +standardContext.requestListenerConfig.added=Added request listener Valve +standardContext.requestListenerConfig.error=Exception adding request listener Valve: {0} +standardContext.isUnavailable=This application is not currently available +standardContext.listenerStart=Exception sending context initialized event to listener instance of class {0} +standardContext.listenerStartFailed=Failed to start application Listeners successfully +standardContext.listenerStop=Exception sending context destroyed event to listener instance of class {0} +standardContext.loginConfig.errorPage=Form error page {0} must start with a ''/' +standardContext.loginConfig.errorWarning=WARNING: Form error page {0} must start with a ''/'' in Servlet 2.4 +standardContext.loginConfig.loginPage=Form login page {0} must start with a ''/' +standardContext.loginConfig.loginWarning=WARNING: Form login page {0} must start with a ''/'' in Servlet 2.4 +standardContext.loginConfig.required=LoginConfig cannot be null +standardContext.mappingError=MAPPING configuration error for relative URI {0} +standardContext.notFound=The requested resource ({0}) is not available. +standardContext.notReloadable=Reloading is disabled on this Context +standardContext.notStarted=Context has not yet been started +standardContext.notWrapper=Child of a Context must be a Wrapper +standardContext.parameter.duplicate=Duplicate context initialization parameter {0} +standardContext.parameter.required=Both parameter name and parameter value are required +standardContext.reloadingCompleted=Reloading this Context is completed +standardContext.reloadingFailed=Reloading this Context failed due to previous errors +standardContext.reloadingStarted=Reloading this Context has started +standardContext.resourcesStart=Error starting static Resources +standardContext.securityConstraint.pattern=Invalid <url-pattern> {0} in security constraint +standardContext.servletMap.name=Servlet mapping specifies an unknown servlet name {0} +standardContext.servletMap.pattern=Invalid <url-pattern> {0} in servlet mapping +standardContext.startCleanup=Exception during cleanup after start failed +standardContext.startFailed=Context [{0}] startup failed due to previous errors +standardContext.startingLoader=Exception starting Loader +standardContext.startingManager=Exception starting Manager +standardContext.startingWrapper=Exception starting Wrapper for servlet {0} +standardContext.stoppingContext=Exception stopping Context +standardContext.stoppingLoader=Exception stopping Loader +standardContext.stoppingManager=Exception stopping Manager +standardContext.stoppingWrapper=Exception stopping Wrapper for servlet {0} +standardContext.urlDecode=Cannot URL decode request path {0} +standardContext.urlPattern.patternWarning=WARNING: URL pattern {0} must start with a ''/'' in Servlet 2.4 +standardContext.urlValidate=Cannot validate URL decoded request path {0} +standardContext.wrapper.error=JSP file {0} must start with a ''/' +standardContext.wrapper.warning=WARNING: JSP file {0} must start with a ''/'' in Servlet 2.4 +standardEngine.alreadyStarted=Engine has already been started +standardEngine.mappingError=MAPPING configuration error for server name {0} +standardEngine.noHost=No Host matches server name {0} +standardEngine.noHostHeader=HTTP/1.1 request with no Host: header +standardEngine.notHost=Child of an Engine must be a Host +standardEngine.notParent=Engine cannot have a parent Container +standardEngine.notStarted=Engine has not yet been started +standardEngine.unfoundHost=Virtual host {0} not found +standardEngine.unknownHost=No server host specified in this request +standardEngine.unregister.mbeans.failed=Error in destroy() for mbean file {0} +standardHost.accessBase=Cannot access document base directory {0} +standardHost.alreadyStarted=Host has already been started +standardHost.appBase=Application base directory {0} does not exist +standardHost.clientAbort=Remote Client Aborted Request, IOException: {0} +standardHost.configRequired=URL to configuration file is required +standardHost.configNotAllowed=Use of configuration file is not allowed +standardHost.installBase=Only web applications in the Host web application directory can be installed +standardHost.installing=Installing web application at context path {0} from URL {1} +standardHost.installingWAR=Installing web application from URL {0} +standardHost.installingXML=Processing Context configuration file URL {0} +standardHost.installError=Error deploying application at context path {0} +standardHost.invalidErrorReportValveClass=Couldn''t load specified error report valve class: {0} +standardHost.docBase=Document base directory {0} already exists +standardHost.mappingError=MAPPING configuration error for request URI {0} +standardHost.noContext=No Context configured to process this request +standardHost.noHost=No Host configured to process this request +standardHost.notContext=Child of a Host must be a Context +standardHost.notStarted=Host has not yet been started +standardHost.nullName=Host name is required +standardHost.pathFormat=Invalid context path: {0} +standardHost.pathMatch=Context path {0} must match the directory or WAR file name: {1} +standardHost.pathMissing=Context path {0} is not currently in use +standardHost.pathRequired=Context path is required +standardHost.pathUsed=Context path {0} is already in use +standardHost.removing=Removing web application at context path {0} +standardHost.removeError=Error removing application at context path {0} +standardHost.start=Starting web application at context path {0} +standardHost.stop=Stopping web application at context path {0} +standardHost.unfoundContext=Cannot find context for request URI {0} +standardHost.warRequired=URL to web application archive is required +standardHost.warURL=Invalid URL for web application archive: {0} +standardHost.validationEnabled=XML validation enabled +standardHost.validationDisabled=XML validation disabled +standardPipeline.alreadyStarted=Pipeline has already been started +standardPipeline.notStarted=Pipeline has not been started +standardPipeline.noValve=No more Valves in the Pipeline processing this request +standardServer.addContainer.ise=No connectors available to associate this container with +standardServer.initialize.initialized=This server has already been initialized +standardServer.start.connectors=At least one connector is not associated with any container +standardServer.start.started=This server has already been started +standardServer.stop.notStarted=This server has not yet been started +standardService.initialize.initialized=This service has already been initialized +standardService.initialize.failed=Service initializing at {0} failed +standardService.register.failed=Error registering Service at domain {0} +standardService.start.name=Starting service {0} +standardService.start.started=This service has already been started +standardService.stop.name=Stopping service {0} +standardService.stop.notStarted=This service has not yet been started +standardWrapper.allocate=Error allocating a servlet instance +standardWrapper.allocateException=Allocate exception for servlet {0} +standardWrapper.containerServlet=Loading container servlet {0} +standardWrapper.createFilters=Create filters exception for servlet {0} +standardWrapper.deallocateException=Deallocate exception for servlet {0} +standardWrapper.destroyException=Servlet.destroy() for servlet {0} threw exception +standardWrapper.exception0=Tomcat Exception Report +standardWrapper.exception1=A Servlet Exception Has Occurred +standardWrapper.exception2=Exception Report: +standardWrapper.exception3=Root Cause: +standardWrapper.initException=Servlet.init() for servlet {0} threw exception +standardWrapper.instantiate=Error instantiating servlet class {0} +standardWrapper.isUnavailable=Servlet {0} is currently unavailable +standardWrapper.jasperLoader=Using Jasper classloader for servlet {0} +standardWrapper.jspFile.format=JSP file {0} does not start with a ''/'' character +standardWrapper.loadException=Servlet {0} threw load() exception +standardWrapper.missingClass=Wrapper cannot find servlet class {0} or a class it depends on +standardWrapper.missingLoader=Wrapper cannot find Loader for servlet {0} +standardWrapper.notChild=Wrapper container may not have child containers +standardWrapper.notClass=No servlet class has been specified for servlet {0} +standardWrapper.notContext=Parent container of a Wrapper must be a Context +standardWrapper.notFound=Servlet {0} is not available +standardWrapper.notServlet=Class {0} is not a Servlet +standardWrapper.privilegedServlet=Servlet of class {0} is privileged and cannot be loaded by this web application +standardWrapper.releaseFilters=Release filters exception for servlet {0} +standardWrapper.serviceException=Servlet.service() for servlet {0} threw exception +standardWrapper.statusHeader=HTTP Status {0} - {1} +standardWrapper.statusTitle=Tomcat Error Report +standardWrapper.unavailable=Marking servlet {0} as unavailable +standardWrapper.unloadException=Servlet {0} threw unload() exception +standardWrapper.unloading=Cannot allocate servlet {0} because it is being unloaded +standardWrapper.waiting=Waiting for {0} instance(s) to be deallocated
Added: tomcat/sandbox/java/org/apache/coyote/servlet/RequestDispatcherImpl.java URL: http://svn.apache.org/viewvc/tomcat/sandbox/java/org/apache/coyote/servlet/RequestDispatcherImpl.java?rev=407939&view=auto ============================================================================== --- tomcat/sandbox/java/org/apache/coyote/servlet/RequestDispatcherImpl.java (added) +++ tomcat/sandbox/java/org/apache/coyote/servlet/RequestDispatcherImpl.java Fri May 19 19:12:51 2006 @@ -0,0 +1,1047 @@ +/* + * 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.coyote.servlet; + +import java.io.IOException; +import java.io.PrintWriter; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; + +import javax.servlet.RequestDispatcher; +import javax.servlet.Servlet; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.ServletRequest; +import javax.servlet.ServletRequestWrapper; +import javax.servlet.ServletResponse; +import javax.servlet.ServletResponseWrapper; +import javax.servlet.UnavailableException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +//import org.apache.catalina.Globals; +//import org.apache.catalina.InstanceEvent; +//import org.apache.catalina.connector.ClientAbortException; +//import org.apache.catalina.util.InstanceSupport; +//import org.apache.catalina.util.StringManager; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +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 { + + + protected class PrivilegedForward implements PrivilegedExceptionAction { + private ServletRequest request; + private ServletResponse response; + + PrivilegedForward(ServletRequest request, ServletResponse response) + { + this.request = request; + this.response = response; + } + + public Object run() throws java.lang.Exception { + doForward(request,response); + return null; + } + } + + protected class PrivilegedInclude implements PrivilegedExceptionAction { + private ServletRequest request; + private ServletResponse response; + + PrivilegedInclude(ServletRequest request, ServletResponse response) + { + this.request = request; + this.response = response; + } + + public Object run() throws ServletException, IOException { + doInclude(request,response); + return null; + } + } + + // ----------------------------------------------------------- Constructors + + + /** + * 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, String name) { + + super(); + + // Save all of our configuration parameters + this.wrapper = wrapper; + this.context = (ServletContextImpl) wrapper.getParent(); + this.requestURI = requestURI; + this.servletPath = servletPath; + this.origServletPath = servletPath; + this.pathInfo = pathInfo; + this.queryString = queryString; + this.name = name; +// if (wrapper instanceof StandardWrapper) +// this.support = ((StandardWrapper) wrapper).getInstanceSupport(); +// else +// this.support = new InstanceSupport(wrapper); + + if ( log.isDebugEnabled() ) + log.debug("servletPath=" + this.servletPath + ", pathInfo=" + + this.pathInfo + ", queryString=" + queryString + + ", name=" + this.name); + + } + + /** + * The request attribute under which the original servlet path is stored + * on an forwarded dispatcher request. + */ + public static final String FORWARD_SERVLET_PATH_ATTR = + "javax.servlet.forward.servlet_path"; + + + /** + * The request attribute under which the original query string is stored + * on an forwarded dispatcher request. + */ + public static final String FORWARD_QUERY_STRING_ATTR = + "javax.servlet.forward.query_string"; + + /** + * The request attribute under which the original request URI is stored + * on an forwarded dispatcher request. + */ + public static final String FORWARD_REQUEST_URI_ATTR = + "javax.servlet.forward.request_uri"; + + + /** + * The request attribute under which the original context path is stored + * on an forwarded dispatcher request. + */ + public static final String FORWARD_CONTEXT_PATH_ATTR = + "javax.servlet.forward.context_path"; + + + /** + * The request attribute under which the original path info is stored + * on an forwarded dispatcher request. + */ + public static final String FORWARD_PATH_INFO_ATTR = + "javax.servlet.forward.path_info"; + + /** + * The request attribute under which we store the servlet name on a + * named dispatcher request. + */ + public static final String NAMED_DISPATCHER_ATTR = + "org.apache.catalina.NAMED"; + + /** + * The request attribute under which the request URI of the included + * servlet is stored on an included dispatcher request. + */ + public static final String INCLUDE_REQUEST_URI_ATTR = + "javax.servlet.include.request_uri"; + + + /** + * The request attribute under which the context path of the included + * servlet is stored on an included dispatcher request. + */ + public static final String INCLUDE_CONTEXT_PATH_ATTR = + "javax.servlet.include.context_path"; + + + /** + * The request attribute under which the path info of the included + * servlet is stored on an included dispatcher request. + */ + public static final String INCLUDE_PATH_INFO_ATTR = + "javax.servlet.include.path_info"; + + + /** + * The request attribute under which the servlet path of the included + * servlet is stored on an included dispatcher request. + */ + public static final String INCLUDE_SERVLET_PATH_ATTR = + "javax.servlet.include.servlet_path"; + + + /** + * The request attribute under which the query string of the included + * servlet is stored on an included dispatcher request. + */ + public static final String INCLUDE_QUERY_STRING_ATTR = + "javax.servlet.include.query_string"; + + /** + * The request attribute under which we expose the value of the + * <code><jsp-file></code> value associated with this servlet, + * if any. + */ + public static final String JSP_FILE_ATTR = + "org.apache.catalina.jsp_file"; + + + // ----------------------------------------------------- Instance Variables + + private static Log log = LogFactory.getLog(RequestDispatcherImpl.class); + + /** + * The request specified by the dispatching application. + */ + private ServletRequest appRequest = null; + + + /** + * The response specified by the dispatching application. + */ + private ServletResponse appResponse = null; + + + /** + * The Context this RequestDispatcher is associated with. + */ + private ServletContextImpl context = null; + + + /** + * Are we performing an include() instead of a forward()? + */ + private boolean including = false; + + + /** + * 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 outermost request that will be passed on to the invoked servlet. + */ + private ServletRequest outerRequest = null; + + + /** + * The outermost response that will be passed on to the invoked servlet. + */ + private ServletResponse outerResponse = 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 URI for this RequestDispatcher. + */ + private String requestURI = null; + + /** + * The servlet path for this RequestDispatcher. + */ + private String servletPath = null; + + private String origServletPath = null; + + /** + * The StringManager for this package. + */ + private static final StringManager sm = + StringManager.getManager("org.apache.coyote.servlet"); + + + /** + * 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 ServletConfigImpl wrapper = null; + + + /** + * The request wrapper we have created and installed (if any). + */ + private ServletRequest wrapRequest = null; + + + /** + * The response wrapper we have created and installed (if any). + */ + private ServletResponse wrapResponse = null; + + + // ------------------------------------------------------------- Properties + + + /** + * Return the descriptive information about this implementation. + */ + public String getInfo() { + + return (info); + + } + + + // --------------------------------------------------------- Public Methods + + + /** + * 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. + * + * @param request The servlet request to be forwarded + * @param response The servlet response to be forwarded + * + * @exception IOException if an input/output error occurs + * @exception ServletException if a servlet exception occurs + */ + public void forward(ServletRequest request, ServletResponse response) + throws ServletException, IOException + { + if (System.getSecurityManager() != null) { + try { + PrivilegedForward dp = new PrivilegedForward(request,response); + AccessController.doPrivileged(dp); + } catch (PrivilegedActionException pe) { + Exception e = pe.getException(); + if (e instanceof ServletException) + throw (ServletException) e; + throw (IOException) e; + } + } else { + doForward(request,response); + } + } + + private void doForward(ServletRequest request, ServletResponse response) + throws ServletException, IOException + { + + // 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")); + } + try { + response.resetBuffer(); + } catch (IllegalStateException e) { + if ( log.isDebugEnabled() ) + log.debug(" Forward resetBuffer() returned ISE: " + e); + throw e; + } + + // Set up to handle the specified request and response + setup(request, response, false); + + // Identify the HTTP-specific request and response objects (if any) + HttpServletRequest hrequest = null; + if (request instanceof HttpServletRequest) + hrequest = (HttpServletRequest) request; + HttpServletResponse hresponse = null; + if (response instanceof HttpServletResponse) + hresponse = (HttpServletResponse) response; + + // Handle a non-HTTP forward by passing the existing request/response + if ((hrequest == null) || (hresponse == null)) { + + if ( log.isDebugEnabled() ) + log.debug(" Non-HTTP Forward"); + + processRequest(hrequest,hresponse); + + } + + // Handle an HTTP named dispatcher forward + else if ((servletPath == null) && (pathInfo == null)) { + + if ( log.isDebugEnabled() ) + log.debug(" Named Dispatcher Forward"); + + ServletRequestWrapperImpl wrequest = + (ServletRequestWrapperImpl) wrapRequest(); + 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(); + + } + + // Handle an HTTP path-based forward + else { + + if ( log.isDebugEnabled() ) + log.debug(" Path Based Forward"); + + ServletRequestWrapperImpl wrequest = + (ServletRequestWrapperImpl) wrapRequest(); + String contextPath = context.getPath(); + + if (hrequest.getAttribute(FORWARD_REQUEST_URI_ATTR) == null) { + wrequest.setAttribute(FORWARD_REQUEST_URI_ATTR, + hrequest.getRequestURI()); + wrequest.setAttribute(FORWARD_CONTEXT_PATH_ATTR, + hrequest.getContextPath()); + wrequest.setAttribute(FORWARD_SERVLET_PATH_ATTR, + hrequest.getServletPath()); + wrequest.setAttribute(FORWARD_PATH_INFO_ATTR, + hrequest.getPathInfo()); + wrequest.setAttribute(FORWARD_QUERY_STRING_ATTR, + hrequest.getQueryString()); + } + + wrequest.setContextPath(contextPath); + wrequest.setRequestURI(requestURI); + wrequest.setServletPath(servletPath); + wrequest.setPathInfo(pathInfo); + if (queryString != null) { + wrequest.setQueryString(queryString); + wrequest.setQueryParams(queryString); + } + + processRequest(request,response); + + 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(); + } else { + // Servlet SRV.6.2.2. The Resquest/Response may have been wrapped + // and may no longer be instance of RequestFacade + if (log.isDebugEnabled()){ + log.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. + * @param request The servlet request we are processing + * @param response The servlet response we are creating + * + * @exception IOException if an input/output error occurs + * @exception ServletException if a servlet error occurs + */ + private void processRequest(ServletRequest request, + ServletResponse response) + throws IOException, ServletException { + + Integer disInt = (Integer) request.getAttribute + (ApplicationFilterFactory.DISPATCHER_TYPE_ATTR); + if (disInt != null) { + if (disInt.intValue() != ApplicationFilterFactory.ERROR) { + outerRequest.setAttribute + (ApplicationFilterFactory.DISPATCHER_REQUEST_PATH_ATTR, + origServletPath); + outerRequest.setAttribute + (ApplicationFilterFactory.DISPATCHER_TYPE_ATTR, + new Integer(ApplicationFilterFactory.FORWARD)); + invoke(outerRequest, response); + } else { + invoke(outerRequest, response); + } + } + + } + + + + /** + * 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. + * + * @param request The servlet request that is including this one + * @param response The servlet response to be appended to + * + * @exception IOException if an input/output error occurs + * @exception ServletException if a servlet exception occurs + */ + public void include(ServletRequest request, ServletResponse response) + throws ServletException, IOException + { + if (System.getSecurityManager() != null) { + try { + PrivilegedInclude dp = new PrivilegedInclude(request,response); + AccessController.doPrivileged(dp); + } catch (PrivilegedActionException pe) { + Exception e = pe.getException(); + + if (e instanceof ServletException) + throw (ServletException) e; + throw (IOException) e; + } + } else { + doInclude(request,response); + } + } + + private void doInclude(ServletRequest request, ServletResponse response) + throws ServletException, IOException + { + // Set up to handle the specified request and response + setup(request, response, true); + + // Create a wrapped response to use for this request + // ServletResponse wresponse = null; + ServletResponse wresponse = wrapResponse(); + + // Handle a non-HTTP include + if (!(request instanceof HttpServletRequest) || + !(response instanceof HttpServletResponse)) { + + if ( log.isDebugEnabled() ) + log.debug(" Non-HTTP Include"); + request.setAttribute(ApplicationFilterFactory.DISPATCHER_TYPE_ATTR, + new Integer(ApplicationFilterFactory.INCLUDE)); + request.setAttribute(ApplicationFilterFactory.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(); + wrequest.setAttribute(NAMED_DISPATCHER_ATTR, name); + if (servletPath != null) + wrequest.setServletPath(servletPath); + wrequest.setAttribute(ApplicationFilterFactory.DISPATCHER_TYPE_ATTR, + new Integer(ApplicationFilterFactory.INCLUDE)); + wrequest.setAttribute(ApplicationFilterFactory.DISPATCHER_REQUEST_PATH_ATTR, origServletPath); + invoke(outerRequest, outerResponse); + + wrequest.recycle(); + } + + // Handle an HTTP path based include + else { + + if ( log.isDebugEnabled() ) + log.debug(" Path Based Include"); + + ServletRequestWrapperImpl wrequest = + (ServletRequestWrapperImpl) wrapRequest(); + String contextPath = context.getPath(); + if (requestURI != null) + wrequest.setAttribute(INCLUDE_REQUEST_URI_ATTR, + requestURI); + if (contextPath != null) + wrequest.setAttribute(INCLUDE_CONTEXT_PATH_ATTR, + contextPath); + if (servletPath != null) + wrequest.setAttribute(INCLUDE_SERVLET_PATH_ATTR, + servletPath); + if (pathInfo != null) + wrequest.setAttribute(INCLUDE_PATH_INFO_ATTR, + pathInfo); + if (queryString != null) { + wrequest.setAttribute(INCLUDE_QUERY_STRING_ATTR, + queryString); + wrequest.setQueryParams(queryString); + } + + wrequest.setAttribute(ApplicationFilterFactory.DISPATCHER_TYPE_ATTR, + new Integer(ApplicationFilterFactory.INCLUDE)); + wrequest.setAttribute(ApplicationFilterFactory.DISPATCHER_REQUEST_PATH_ATTR, origServletPath); + invoke(outerRequest, outerResponse); + + wrequest.recycle(); + } + + } + + + // -------------------------------------------------------- Private Methods + + + /** + * Ask the resource represented by this RequestDispatcher to process + * the associated request, and create (or append to) the associated + * response. + * <p> + * <strong>IMPLEMENTATION NOTE</strong>: This implementation assumes + * that no filters are applied to a forwarded or included resource, + * because they were already done for the original request. + * + * @param request The servlet request we are processing + * @param response The servlet response we are creating + * + * @exception IOException if an input/output error occurs + * @exception ServletException if a servlet error occurs + */ + private void invoke(ServletRequest request, ServletResponse response) + throws IOException, ServletException { + + // 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 = context.getClassLoader(); + + if (oldCCL != contextClassLoader) { + Thread.currentThread().setContextClassLoader(contextClassLoader); + } else { + oldCCL = null; + } + + // Initialize local variables we may need + HttpServletRequest hrequest = (HttpServletRequest) request; + HttpServletResponse hresponse = (HttpServletResponse) response; + Servlet servlet = null; + IOException ioException = null; + ServletException servletException = null; + RuntimeException runtimeException = null; + boolean unavailable = false; + + // Check for the servlet being marked unavailable + if (wrapper.isUnavailable()) { + wrapper.getLogger().warn( + sm.getString("applicationDispatcher.isUnavailable", + wrapper.getName())); + long available = wrapper.getAvailable(); + if ((available > 0L) && (available < Long.MAX_VALUE)) + hresponse.setDateHeader("Retry-After", available); + hresponse.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, sm + .getString("applicationDispatcher.isUnavailable", wrapper + .getName())); + unavailable = true; + } + + // Allocate a servlet instance to process this request + try { + if (!unavailable) { + servlet = wrapper.allocate(); + } + } catch (ServletException e) { + wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException", + wrapper.getName()), ServletConfigImpl.getRootCause(e)); + servletException = e; + servlet = null; + } catch (Throwable e) { + wrapper.getLogger().error(sm.getString("applicationDispatcher.allocateException", + wrapper.getName()), e); + servletException = new ServletException + (sm.getString("applicationDispatcher.allocateException", + wrapper.getName()), e); + servlet = null; + } + + // Get the FilterChain Here + ApplicationFilterFactory factory = ApplicationFilterFactory.getInstance(); + FilterChainImpl filterChain = factory.createFilterChain(request, + wrapper,servlet); + // Call the service() method for the allocated servlet instance + try { + String jspFile = wrapper.getJspFile(); + if (jspFile != null) + request.setAttribute(JSP_FILE_ATTR, jspFile); + else + request.removeAttribute(JSP_FILE_ATTR); +// support.fireInstanceEvent(InstanceEvent.BEFORE_DISPATCH_EVENT, +// servlet, request, response); + // for includes/forwards + if ((servlet != null) && (filterChain != null)) { + filterChain.doFilter(request, response); + } + // Servlet Service Method is called by the FilterChain + request.removeAttribute(JSP_FILE_ATTR); +// support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, +// servlet, request, response); +// } catch (ClientAbortException e) { +// request.removeAttribute(Globals.JSP_FILE_ATTR); +// support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, +// servlet, request, response); +// ioException = e; + } catch (IOException e) { + request.removeAttribute(JSP_FILE_ATTR); +// support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, +// servlet, request, response); + wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", + wrapper.getName()), e); + ioException = e; + } catch (UnavailableException e) { + request.removeAttribute(JSP_FILE_ATTR); +// support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, +// servlet, request, response); + wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", + wrapper.getName()), e); + servletException = e; + wrapper.unavailable(e); + } catch (ServletException e) { + request.removeAttribute(JSP_FILE_ATTR); +// support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, +// servlet, request, response); + Throwable rootCause = ServletConfigImpl.getRootCause(e); +// if (!(rootCause instanceof ClientAbortException)) { +// wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", +// wrapper.getName()), rootCause); +// } + servletException = e; + } catch (RuntimeException e) { + request.removeAttribute(JSP_FILE_ATTR); +// support.fireInstanceEvent(InstanceEvent.AFTER_DISPATCH_EVENT, +// servlet, request, response); + wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException", + wrapper.getName()), e); + runtimeException = e; + } + + // Release the filter chain (if any) for this request + try { + if (filterChain != null) + filterChain.release(); + } catch (Throwable e) { + log.error(sm.getString("standardWrapper.releaseFilters", + wrapper.getName()), e); + //FIXME Exception handling needs to be simpiler to what is in the StandardWrapperValue + } + + // Deallocate the allocated servlet instance + try { + if (servlet != null) { + wrapper.deallocate(servlet); + } + } catch (ServletException e) { + wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException", + wrapper.getName()), e); + servletException = e; + } catch (Throwable e) { + wrapper.getLogger().error(sm.getString("applicationDispatcher.deallocateException", + wrapper.getName()), e); + servletException = new ServletException + (sm.getString("applicationDispatcher.deallocateException", + wrapper.getName()), e); + } + + // Reset the old context class loader + if (oldCCL != null) + Thread.currentThread().setContextClassLoader(oldCCL); + + // Unwrap request/response if needed + // See Bugzilla 30949 + unwrapRequest(); + unwrapResponse(); + + // 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; + + } + + + /** + * Set up to handle the specified request and response + * + * @param request The servlet request specified by the caller + * @param response The servlet response specified by the caller + * @param including Are we performing an include() as opposed to + * a forward()? + */ + private void setup(ServletRequest request, ServletResponse response, + boolean including) { + + this.appRequest = request; + this.appResponse = response; + this.outerRequest = request; + this.outerResponse = response; + this.including = including; + + } + + + /** + * Unwrap the request if we have wrapped it. + */ + private void unwrapRequest() { + + if (wrapRequest == null) + return; + + ServletRequest previous = null; + ServletRequest current = outerRequest; + while (current != null) { + + // If we run into the container request we are done + if (current instanceof ServletRequestImpl) + break; + + // Remove the current request if it is our wrapper + if (current == wrapRequest) { + ServletRequest next = + ((ServletRequestWrapper) current).getRequest(); + if (previous == null) + outerRequest = next; + else + ((ServletRequestWrapper) previous).setRequest(next); + break; + } + + // Advance to the next request in the chain + previous = current; + current = ((ServletRequestWrapper) current).getRequest(); + + } + + } + + + /** + * Unwrap the response if we have wrapped it. + */ + private void unwrapResponse() { + + if (wrapResponse == null) + return; + + ServletResponse previous = null; + ServletResponse current = outerResponse; + while (current != null) { + + // If we run into the container response we are done + if (current instanceof ServletResponseImpl) + break; + + // Remove the current response if it is our wrapper + if (current == wrapResponse) { + ServletResponse next = + ((ServletResponseWrapper) current).getResponse(); + if (previous == null) + outerResponse = next; + else + ((ServletResponseWrapper) previous).setResponse(next); + break; + } + + // Advance to the next response in the chain + previous = current; + current = ((ServletResponseWrapper) current).getResponse(); + + } + + } + + + /** + * Create and return a request wrapper that has been inserted in the + * appropriate spot in the request chain. + */ + private ServletRequest wrapRequest() { + + // Locate the request we should insert in front of + ServletRequest previous = null; + ServletRequest current = outerRequest; + while (current != null) { + if ("org.apache.catalina.servlets.InvokerHttpRequest". + equals(current.getClass().getName())) + break; // KLUDGE - Make nested RD.forward() using invoker work + if (!(current instanceof ServletRequestWrapper)) + break; + if (current instanceof ServletRequestWrapperImpl) + break; +// if (current instanceof ApplicationRequest) +// break; + if (current instanceof ServletRequestImpl) + break; + previous = current; + current = ((ServletRequestWrapper) current).getRequest(); + } + + // Instantiate a new wrapper at this point and insert it in the chain + ServletRequest wrapper = null; +// if ((current instanceof ApplicationHttpRequest) || +// (current instanceof Request) || +// (current instanceof HttpServletRequest)) { + // Compute a crossContext flag + HttpServletRequest hcurrent = (HttpServletRequest) current; + boolean crossContext = false; + if ((outerRequest instanceof ServletRequestWrapperImpl) || + (outerRequest instanceof ServletRequestImpl) || + (outerRequest instanceof HttpServletRequest)) { + HttpServletRequest houterRequest = + (HttpServletRequest) outerRequest; + Object contextPath = houterRequest.getAttribute + (INCLUDE_CONTEXT_PATH_ATTR); + if (contextPath == null) { + // Forward + contextPath = houterRequest.getContextPath(); + } + crossContext = !(context.getPath().equals(contextPath)); + } + wrapper = new ServletRequestWrapperImpl + (hcurrent, context, crossContext); +// } else { +// wrapper = new ApplicationRequest(current); +// } + if (previous == null) + outerRequest = wrapper; + else + ((ServletRequestWrapper) previous).setRequest(wrapper); + 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() { + + // 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 ApplicationResponse) +// break; + if (current instanceof ServletResponseImpl) + break; + previous = current; + current = ((ServletResponseWrapper) current).getResponse(); + } + + // Instantiate a new wrapper at this point and insert it in the chain + ServletResponse wrapper = null; +// if ((current instanceof ApplicationHttpResponse) || +// (current instanceof Response) || +// (current instanceof HttpServletResponse)) + wrapper = + new ServletResponseWrapperImpl((HttpServletResponse) current, + including); +// else +// wrapper = new ApplicationResponse(current, including); + if (previous == null) + outerResponse = wrapper; + else + ((ServletResponseWrapper) previous).setResponse(wrapper); + wrapResponse = wrapper; + return (wrapper); + + } + + +} --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]