private void doInclude(ServletRequest request, ServletResponse response)
throws ServletException, IOException
{
Request realRequest = ((HttpServletRequestFacade)request).
getRealRequest();
Response realResponse = realRequest.getResponse();
if( debug ) {
System.out.println("RDI: doInclude: " + path + " " + name +
" " + queryString );
}
// the strange case in a separate method
if( name!=null) {
includeNamed( request, response );
return;
}
// Implement the spec that "no changes in response, only write"
// can also be done by setting the response to 0.9 mode
// IncludedResponse iResponse = new IncludedResponse(realResponse);
boolean old_included=realResponse.isIncluded();
if( ! old_included ) {
realResponse.setIncluded( true );
}
// We need to pass the original request, with all the paths -
// and the new paths in special attributes.
// We still need to find out where do we want to go ( today )
// That means we create a subRequest with the new paths ( since
// the mapping and aliasing is done on Requests), and run it
// through prepare.
// That also means that some special cases ( like the invoker !! )
// will have to pay attention to the attributes, or we'll get a loop
Request subRequest=context.getContextManager().
createRequest( context, path );
subRequest.setParent( realRequest );
subRequest.getTop(); // control inclusion depth
// I hope no interceptor (or code) in processRequest use any
// of the original request info ( like Auth headers )
//
// XXX We need to clone the request, so that processRequest can
// make an informed mapping ( Auth, Authorization, etc)
//
// This will never work corectly unless we do a full clone - but
// for simple cases ( no auth, etc) it does
// note that we also need a dummy response - SessionInterceptors may
// change something !
subRequest.setResponse( realResponse );
context.getContextManager().processRequest(subRequest);
// Now subRequest containse the processed and aliased paths, plus
// the wrapper that will handle the request.
// We will use the stack a bit - save all path attributes, set the
// new values, and after return from wrapper revert to the original
Object old_request_uri=replaceAttribute(realRequest, A_REQUEST_URI,
context.getPath() + path );
Object old_context_path=replaceAttribute(realRequest, A_CONTEXT_PATH,
context.getPath());
Object old_servlet_path=replaceAttribute(realRequest, A_SERVLET_PATH,
subRequest.servletPath().toString());
Object old_path_info=replaceAttribute(realRequest, A_PATH_INFO,
subRequest.pathInfo().toString());
Object old_query_string=replaceAttribute(realRequest, A_QUERY_STRING,
queryString);
if( debug ) {
System.out.println("RDI: old " + old_request_uri + " " +
old_context_path + " " + old_servlet_path +
" " + old_path_info + " " + old_query_string);
System.out.println("RDI: new "+context.getPath() + " " + path + " "
+ subRequest.servletPath().toString() + " " +
subRequest.pathInfo().toString() + " " +
queryString);
}
if( queryString != null ) {
// the original parameters will be preserved, and a new
// child Parameters will be used for the included request.
realRequest.parameters().push();
Parameters child=realRequest.parameters().getCurrentSet();
child.processParameters( queryString );
}
Request old_child = realRequest.getChild();
subRequest.setParent( old_child );
realRequest.setChild( subRequest );
// now it's really strange: we call the wrapper on the subrequest
// for the realRequest ( since the real request will still have the
// original handler/wrapper )
Handler wr=subRequest.getHandler();
if( wr!=null ) {
try {
wr.service(realRequest, realResponse);
} catch( Exception ex ) {
realResponse.setErrorException(ex);
}
}
// After request, we want to restore the include attributes - for
// chained includes.
realRequest.setChild( old_child );
if( queryString != null ) {
// restore the parameters
realRequest.parameters().pop();
}
//realRequest.setParameters( old_parameters);
replaceAttribute( realRequest, A_REQUEST_URI, old_request_uri);
replaceAttribute( realRequest, A_CONTEXT_PATH,old_context_path);
replaceAttribute( realRequest, A_SERVLET_PATH, old_servlet_path);
replaceAttribute( realRequest, A_PATH_INFO, old_path_info);
replaceAttribute( realRequest, A_QUERY_STRING, old_query_string);
// revert to the response behavior
if( ! old_included ) {
realResponse.setIncluded( false );
}
// Rethrow original error if present
if ( realResponse.isExceptionPresent() ) {
// if error URI not set, set our URI
if ( null == realResponse.getErrorURI() )
realResponse.setErrorURI( context.getPath() + path );
Exception ex = realResponse.getErrorException();
wrapException( ex, sm.getString("dispatcher.includeException"));
}
}