View Javadoc

1   /*
2    * $Id: ServletActionRedirectResult.java 462586 2006-10-10 21:35:35Z mrdon $
3    *
4    * Copyright 2006 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.struts2.dispatcher;
19  
20  import java.util.Arrays;
21  import java.util.HashMap;
22  import java.util.Iterator;
23  import java.util.List;
24  import java.util.Map;
25  
26  import org.apache.struts2.dispatcher.mapper.ActionMapper;
27  import org.apache.struts2.dispatcher.mapper.ActionMapperFactory;
28  import org.apache.struts2.dispatcher.mapper.ActionMapping;
29  import org.apache.struts2.views.util.UrlHelper;
30  
31  import com.opensymphony.xwork2.ActionInvocation;
32  import com.opensymphony.xwork2.config.entities.ResultConfig;
33  
34  /***
35   * <!-- START SNIPPET: description -->
36   *
37   * This result uses the {@link ActionMapper} provided by the {@link ActionMapperFactory} to redirect the browser to a
38   * URL that invokes the specified action and (optional) namespace. This is better than the {@link ServletRedirectResult}
39   * because it does not require you to encode the URL patterns processed by the {@link ActionMapper} in to your struts.xml
40   * configuration files. This means you can change your URL patterns at any point and your application will still work.
41   * It is strongly recommended that if you are redirecting to another action, you use this result rather than the
42   * standard redirect result.
43   *
44   * <p/>
45   *
46   * To pass parameters, the &lt;param&gt; ... &lt;/param&gt; tag. The following parameters will not be
47   * passable becuase they are part of the config param for this particular result.
48   *
49   * <ul>
50   * 	<li>actionName</li>
51   *  <li>namespace</li>
52   *  <li>method</li>
53   *  <li>encode</li>
54   *  <li>parse</li>
55   *  <li>location</li>
56   *  <li>prependServletContext</li>
57   * </ul>
58   *
59   * See examples below for an example of how request parameters could be passed in.
60   *
61   * <!-- END SNIPPET: description -->
62   *
63   * <b>This result type takes the following parameters:</b>
64   *
65   * <!-- START SNIPPET: params -->
66   *
67   * <ul>
68   *
69   * <li><b>actionName (default)</b> - the name of the action that will be redirect to</li>
70   *
71   * <li><b>namespace</b> - used to determine which namespace the action is in that we're redirecting to . If namespace is
72   * null, this defaults to the current namespace</li>
73   *
74   * </ul>
75   *
76   * <!-- END SNIPPET: params -->
77   *
78   * <b>Example:</b>
79   *
80   * <pre><!-- START SNIPPET: example -->
81   * &lt;package name="public" extends="struts-default"&gt;
82   *     &lt;action name="login" class="..."&gt;
83   *         &lt;!-- Redirect to another namespace --&gt;
84   *         &lt;result type="redirect-action"&gt;
85   *             &lt;param name="actionName"&gt;dashboard&lt;/param&gt;
86   *             &lt;param name="namespace"&gt;/secure&lt;/param&gt;
87   *         &lt;/result&gt;
88   *     &lt;/action&gt;
89   * &lt;/package&gt;
90   *
91   * &lt;package name="secure" extends="struts-default" namespace="/secure"&gt;
92   *     &lt;-- Redirect to an action in the same namespace --&gt;
93   *     &lt;action name="dashboard" class="..."&gt;
94   *         &lt;result&gt;dashboard.jsp&lt;/result&gt;
95   *         &lt;result name="error" type="redirect-action&gt;error&lt;/result&gt;
96   *     &lt;/action&gt;
97   *
98   *     &lt;action name="error" class="..."&gt;
99   *         &lt;result&gt;error.jsp&lt;/result&gt;
100  *     &lt;/action&gt;
101  * &lt;/package&gt;
102  *
103  * &lt;package name="passingRequestParameters" extends="struts-default" namespace="/passingRequestParameters"&gt;
104  * 	  &lt;-- Pass parameters (reportType, width and height) --&gt;
105  *    &lt;!--
106  *    The redirect-action url generated will be :
107  *    /genReport/generateReport.action?reportType=pie&width=100&height=100
108  *    --&gt;
109  *    &lt;action name="gatherReportInfo" class="..."&gt;
110  *       &lt;result name="showReportResult" type="redirect-action"&gt;
111  *       	&lt;param name="actionName"&gt;generateReport&lt;/param&gt;
112  *          &lt;param name="namespace="&gt;/genReport&lt;/param&gt;
113  *          &lt;param name="reportType"&gt;pie&lt;/param&gt;
114  *          &lt;param name="width"&gt;100&lt;/param&gt;
115  *          &lt;param name="height"&gt;100&lt;/param&gt;
116  *       &lt;/result&gt;
117  *    &lt;/action&gt;
118  * &lt;/package&gt;
119  *
120  *
121  * <!-- END SNIPPET: example --></pre>
122  *
123  * @see ActionMapper
124  */
125 public class ServletActionRedirectResult extends ServletRedirectResult {
126 
127 	private static final long serialVersionUID = -9042425229314584066L;
128 
129     /*** The default parameter */
130 	public static final String DEFAULT_PARAM = "actionName";
131 
132     protected String actionName;
133     protected String namespace;
134     protected String method;
135     
136     private Map<String, String> requestParameters = new HashMap<String, String>();
137 
138     public ServletActionRedirectResult() {
139     	super();
140     }
141     
142     public ServletActionRedirectResult(String actionName) {
143     	this(null, actionName, null);
144     }
145     
146     public ServletActionRedirectResult(String actionName, String method) {
147     	this(null, actionName, method);
148     }
149     
150 	public ServletActionRedirectResult(String namespace, String actionName, String method) {
151 		super(null);
152 		this.namespace = namespace;
153 		this.actionName = actionName;
154 		this.method = method;
155 	}
156     
157     protected List<String> prohibitedResultParam = Arrays.asList(new String[] {
158     		DEFAULT_PARAM, "namespace", "method", "encode", "parse", "location",
159     		"prependServletContext" });
160 
161     /***
162      * @see com.opensymphony.xwork2.Result#execute(com.opensymphony.xwork2.ActionInvocation)
163      */
164     public void execute(ActionInvocation invocation) throws Exception {
165         actionName = conditionalParse(actionName, invocation);
166         if (namespace == null) {
167             namespace = invocation.getProxy().getNamespace();
168         } else {
169             namespace = conditionalParse(namespace, invocation);
170         }
171         if (method == null) {
172         	method = "";
173         }
174         else {
175         	method = conditionalParse(method, invocation);
176         }
177 
178         String resultCode = invocation.getResultCode();
179         if (resultCode != null) {
180 	        ResultConfig resultConfig = invocation.getProxy().getConfig().getResults().get(
181 	        		resultCode);
182 	        Map resultConfigParams = resultConfig.getParams();
183 	        for (Iterator i = resultConfigParams.entrySet().iterator(); i.hasNext(); ) {
184 	        	Map.Entry e = (Map.Entry) i.next();
185 	        	if (! prohibitedResultParam.contains(e.getKey())) {
186 	        		requestParameters.put(e.getKey().toString(),
187 	        				e.getValue() == null ? "":
188 	        					conditionalParse(e.getValue().toString(), invocation));
189 	        	}
190 	        }
191         }
192 
193         ActionMapper mapper = ActionMapperFactory.getMapper();
194         StringBuffer tmpLocation = new StringBuffer(mapper.getUriFromActionMapping(new ActionMapping(actionName, namespace, method, null)));
195         UrlHelper.buildParametersString(requestParameters, tmpLocation, "&");
196 
197         setLocation(tmpLocation.toString());
198 
199         super.execute(invocation);
200     }
201 
202     /***
203      * Sets the action name
204      *
205      * @param actionName The name
206      */
207     public void setActionName(String actionName) {
208         this.actionName = actionName;
209     }
210 
211     /***
212      * Sets the namespace
213      *
214      * @param namespace The namespace
215      */
216     public void setNamespace(String namespace) {
217         this.namespace = namespace;
218     }
219 
220     /***
221      * Sets the method
222      *
223      * @param method The method
224      */
225     public void setMethod(String method) {
226     	this.method = method;
227     }
228     
229     /***
230      * Adds a request parameter to be added to the redirect url
231      * 
232      * @param key The parameter name
233      * @param value The parameter value
234      */
235     public ServletActionRedirectResult addParameter(String key, Object value) {
236     	requestParameters.put(key, String.valueOf(value));
237     	return this;
238     }
239 
240 }