001: /*
002: * Copyright (c) 2002-2003 by OpenSymphony
003: * All rights reserved.
004: */
005: package com.opensymphony.webwork.dispatcher;
006:
007: import com.opensymphony.webwork.ServletActionContext;
008: import com.opensymphony.xwork.ActionInvocation;
009: import org.apache.commons.logging.Log;
010: import org.apache.commons.logging.LogFactory;
011:
012: import javax.servlet.RequestDispatcher;
013: import javax.servlet.http.HttpServletRequest;
014: import javax.servlet.http.HttpServletResponse;
015: import javax.servlet.jsp.PageContext;
016:
017: /**
018: * <!-- START SNIPPET: description -->
019: *
020: * Includes or forwards to a view (usually a jsp). Behind the scenes WebWork
021: * will use a RequestDispatcher, where the target servlet/JSP receives the same
022: * request/response objects as the original servlet/JSP. Therefore, you can pass
023: * data between them using request.setAttribute() - the WebWork action is
024: * available.
025: * <p/>
026: * There are three possible ways the result can be executed:
027: *
028: * <ul>
029: *
030: * <li>If we are in the scope of a JSP (a PageContext is available), PageContext's
031: * {@link PageContext#include(String) include} method is called.</li>
032: *
033: * <li>If there is no PageContext and we're not in any sort of include (there is no
034: * "javax.servlet.include.servlet_path" in the request attributes), then a call to
035: * {@link RequestDispatcher#forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse) forward}
036: * is made.</li>
037: *
038: * <li>Otherwise, {@link RequestDispatcher#include(javax.servlet.ServletRequest, javax.servlet.ServletResponse) include}
039: * is called.</li>
040: *
041: * </ul>
042: * <!-- END SNIPPET: description -->
043: *
044: * <b>This result type takes the following parameters:</b>
045: *
046: * <!-- START SNIPPET: params -->
047: *
048: * <ul>
049: *
050: * <li><b>location (default)</b> - the location to go to after execution (ex. jsp).</li>
051: *
052: * <li><b>parse</b> - true by default. If set to false, the location param will not be parsed for Ognl expressions.</li>
053: *
054: * </ul>
055: *
056: * <!-- END SNIPPET: params -->
057: *
058: * <b>Example:</b>
059: *
060: * <pre><!-- START SNIPPET: example -->
061: * <result name="success" type="dispatcher">
062: * <param name="location">foo.jsp</param>
063: * </result>
064: * <!-- END SNIPPET: example --></pre>
065: *
066: * This result follows the same rules from {@link WebWorkResultSupport}.
067: *
068: * @author Patrick Lightbody
069: * @see javax.servlet.RequestDispatcher
070: */
071: public class ServletDispatcherResult extends WebWorkResultSupport {
072:
073: private static final Log log = LogFactory
074: .getLog(ServletDispatcherResult.class);
075:
076: /**
077: * Dispatches to the given location. Does its forward via a RequestDispatcher. If the
078: * dispatch fails a 404 error will be sent back in the http response.
079: *
080: * @param finalLocation the location to dispatch to.
081: * @param invocation the execution state of the action
082: * @throws Exception if an error occurs. If the dispatch fails the error will go back via the
083: * HTTP request.
084: */
085: public void doExecute(String finalLocation,
086: ActionInvocation invocation) throws Exception {
087: if (log.isDebugEnabled()) {
088: log.debug("Forwarding to location " + finalLocation);
089: }
090:
091: PageContext pageContext = ServletActionContext.getPageContext();
092:
093: if (pageContext != null) {
094: pageContext.include(finalLocation);
095: } else {
096: HttpServletRequest request = ServletActionContext
097: .getRequest();
098: HttpServletResponse response = ServletActionContext
099: .getResponse();
100: RequestDispatcher dispatcher = request
101: .getRequestDispatcher(finalLocation);
102:
103: // if the view doesn't exist, let's do a 404
104: if (dispatcher == null) {
105: response.sendError(404, "result '" + finalLocation
106: + "' not found");
107:
108: return;
109: }
110:
111: // If we're included, then include the view
112: // Otherwise do forward
113: // This allow the page to, for example, set content type
114: if (!response.isCommitted()
115: && (request
116: .getAttribute("javax.servlet.include.servlet_path") == null)) {
117: request.setAttribute("webwork.view_uri", finalLocation);
118: request.setAttribute("webwork.request_uri", request
119: .getRequestURI());
120:
121: dispatcher.forward(request, response);
122: } else {
123: dispatcher.include(request, response);
124: }
125: }
126: }
127: }
|