001: /*
002: * Copyright (c) 2002-2003 by OpenSymphony
003: * All rights reserved.
004: */
005: package com.opensymphony.webwork.dispatcher;
006:
007: import java.io.UnsupportedEncodingException;
008: import java.net.URLEncoder;
009:
010: import org.apache.commons.logging.Log;
011: import org.apache.commons.logging.LogFactory;
012:
013: import com.opensymphony.webwork.WebWorkStatics;
014: import com.opensymphony.xwork.ActionInvocation;
015: import com.opensymphony.xwork.Result;
016: import com.opensymphony.xwork.util.TextParseUtil;
017:
018: /**
019: * <!-- START SNIPPET: javadoc -->
020: *
021: * A base class for all WebWork action execution results.
022: * The "location" param is the default parameter, meaning the most common usage of this result would be:
023: * <p/>
024: * This class provides two common parameters for any subclass:
025: * <ul>
026: * <li>location - the location to go to after execution (could be a jsp page or another action).
027: * It can be parsed as per the rules definied in the
028: * {@link TextParseUtil#translateVariables(java.lang.String, com.opensymphony.xwork.util.OgnlValueStack) translateVariables}
029: * method</li>
030: * <li>parse - true by default. If set to false, the location param will not be parsed for expressions</li>
031: * <li>encode - false by default. If set to false, the location param will not be url encoded. This only have effect when parse is true</li>
032: * </ul>
033: *
034: * <b>NOTE:</b>
035: * The encode param will only have effect when parse is true
036: *
037: * <p/>
038: *
039: * <!-- END SNIPPET: javadoc -->
040: *
041: *
042: * <!-- START SNIPPET: example -->
043: *
044: * <p/>
045: * In the xwork.xml configuration file, these would be included as:
046: * <p/>
047: * <pre>
048: * <result name="success" type="redirect">
049: * <param name="<b>location</b>">foo.jsp</param>
050: * </result></pre>
051: * <p/>
052: * or
053: * <p/>
054: * <pre>
055: * <result name="success" type="redirect" >
056: * <param name="<b>location</b>">foo.jsp?url=${myUrl}</param>
057: * <param name="<b>parse</b>">true</param>
058: * <param name="<b>encode</b>">true</param>
059: * </result></pre>
060: * <p/>
061: * In the above case, myUrl will be parsed against Ognl Value Stack and then
062: * URL encoded.
063: * <p/>
064: * or when using the default parameter feature
065: * <p/>
066: * <pre>
067: * <result name="success" type="redirect"><b>foo.jsp</b></result></pre>
068: * <p/>
069: * You should subclass this class if you're interested in adding more parameters or functionality
070: * to your Result. If you do subclass this class you will need to
071: * override {@link #doExecute(String, ActionInvocation)}.<p>
072: * <p/>
073: * Any custom result can be defined in xwork.xml as:
074: * <p/>
075: * <pre>
076: * <result-types>
077: * ...
078: * <result-type name="myresult" class="com.foo.MyResult" />
079: * </result-types></pre>
080: * <p/>
081: * Please see the {@link com.opensymphony.xwork.Result} class for more info on Results in general.
082: *
083: * <!-- END SNIPPET: example -->
084: *
085: * @author Jason Carreira
086: * @author Bill Lynch (docs)
087: * @author tm_jee
088: * @see com.opensymphony.xwork.Result
089: */
090: public abstract class WebWorkResultSupport implements Result,
091: WebWorkStatics {
092:
093: private static final Log _log = LogFactory
094: .getLog(WebWorkResultSupport.class);
095:
096: public static final String DEFAULT_PARAM = "location";
097:
098: protected boolean parse = true;
099: protected boolean encode = false;
100: protected String location;
101:
102: /**
103: * The location to go to after action execution. This could be a JSP page or another action.
104: * The location can contain OGNL expressions which will be evaulated if the <tt>parse</tt>
105: * parameter is set to <tt>true</tt>.
106: *
107: * @param location the location to go to after action execution.
108: * @see #setParse(boolean)
109: */
110: public void setLocation(String location) {
111: this .location = location;
112: }
113:
114: /**
115: * Set parse to <tt>true</tt> to indicate that the location should be parsed as an OGNL expression. This
116: * is set to <tt>true</tt> by default.
117: *
118: * @param parse <tt>true</tt> if the location parameter is an OGNL expression, <tt>false</tt> otherwise.
119: */
120: public void setParse(boolean parse) {
121: this .parse = parse;
122: }
123:
124: /**
125: * Set encode to <tt>true</tt> to indicate that the location should be url encoded. This is set to
126: * <tt>true</tt> by default
127: *
128: * @param encode <tt>true</tt> if the location parameter should be url encode, <tt>false</tt> otherwise.
129: */
130: public void setEncode(boolean encode) {
131: this .encode = encode;
132: }
133:
134: /**
135: * Implementation of the <tt>execute</tt> method from the <tt>Result</tt> interface. This will call
136: * the abstract method {@link #doExecute(String, ActionInvocation)} after optionally evaluating the
137: * location as an OGNL evaluation.
138: *
139: * @param invocation the execution state of the action.
140: * @throws Exception if an error occurs while executing the result.
141: */
142: public void execute(ActionInvocation invocation) throws Exception {
143: doExecute(conditionalParse(location, invocation), invocation);
144: }
145:
146: protected String conditionalParse(String param,
147: ActionInvocation invocation) {
148: if (parse && param != null && invocation != null) {
149: return TextParseUtil.translateVariables(param, invocation
150: .getStack(),
151: new TextParseUtil.ParsedValueEvaluator() {
152: public Object evaluate(Object parsedValue) {
153: if (encode) {
154: if (parsedValue != null) {
155: try {
156: // use UTF-8 as this is the recommended encoding by W3C to
157: // avoid incompatibilities.
158: return URLEncoder.encode(
159: parsedValue.toString(),
160: "UTF-8");
161: } catch (UnsupportedEncodingException e) {
162: _log.warn(
163: "error while trying to encode ["
164: + parsedValue
165: + "]", e);
166: }
167: }
168: }
169: return parsedValue;
170: }
171: });
172: } else {
173: return param;
174: }
175: }
176:
177: /**
178: * Executes the result given a final location (jsp page, action, etc) and the action invocation
179: * (the state in which the action was executed). Subclasses must implement this class to handle
180: * custom logic for result handling.
181: *
182: * @param finalLocation the location (jsp page, action, etc) to go to.
183: * @param invocation the execution state of the action.
184: * @throws Exception if an error occurs while executing the result.
185: */
186: protected abstract void doExecute(String finalLocation,
187: ActionInvocation invocation) throws Exception;
188: }
|