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