Source code: org/apache/struts/action/ActionRedirect.java
1 /*
2 * $Id: ActionRedirect.java 164747 2005-04-26 05:47:48Z hrabago $
3 *
4 * Copyright 2000-2005 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
19 package org.apache.struts.action;
20
21 import org.apache.struts.config.ForwardConfig;
22 import org.apache.struts.util.ResponseUtils;
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25
26 import java.util.Map;
27 import java.util.HashMap;
28 import java.util.Arrays;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.Iterator;
32
33 /**
34 * A subclass of {@link ActionForward} which is designed for use
35 * in redirecting requests, with support for adding parameters
36 * at runtime.
37 * <br/>
38 * An {@link ForwardConfig} (or subclass) can be passed to the constructor
39 * to copy its configuration:
40 * <br/>
41 * <code>
42 * public ActionForward execute(ActionMapping mapping,
43 * ActionForm form,
44 * HttpServletRequest request,
45 * HttpServletResponse response)
46 * throws Exception {
47 * ActionRedirect redirect =
48 * new ActionRedirect(mapping.findForward("doRedirect"));
49 * redirect.addParameter("param1","value1");
50 * redirect.addParameter("param2","2");
51 * redirect.addParameter("param3","3.0");
52 * return redirect;
53 * }
54 * </code>
55 * <p/>
56 *
57 * @since Struts 1.2.7
58 * @version $Rev: 164747 $ $Date: 2005-04-26 06:47:48 +0100 (Tue, 26 Apr 2005) $
59 */
60 public class ActionRedirect extends ActionForward {
61
62 // ----------------------------------------------------- Static variables
63
64 /**
65 * <p>Commons logging instance.</p>
66 */
67 protected static final Log log = LogFactory.getLog(ActionRedirect.class);
68
69
70 // ----------------------------------------------------- Instance variables
71
72 /**
73 * <p>Holds the redirect parameters.
74 * Each entry is either a String or a String[] depending on whether
75 * it has one or more entries.</p>
76 */
77 protected Map parameterValues = null;
78
79
80 // ----------------------------------------------------- Constructors
81
82 /**
83 * <p>Construct a new instance with redirect set to true
84 * and initialize parameter lists.</p>
85 */
86 public ActionRedirect() {
87 setRedirect(true);
88 initializeParameters();
89 }
90
91 /**
92 * <p>Construct a new instance with the specified path
93 * and initialize parameter lists.</p>
94 *
95 * @param path Path for this instance
96 */
97 public ActionRedirect(String path) {
98 super(path);
99 setRedirect(true);
100 initializeParameters();
101 }
102
103 /**
104 * <p>Construct a new instance with the specified values
105 * and initialize parameter lists.</p>
106 *
107 * @param name Name of this instance
108 * @param path Path for this instance
109 * @param module Module prefix, if any
110 */
111 public ActionRedirect(String name, String path, String module) {
112 super(name, path, true);
113 setModule(module);
114 initializeParameters();
115 }
116
117
118 /**
119 * <p>Construct a new instance with a {@link ForwardConfig} object
120 * to copy name, path, and contextRelative values from.</p>
121 *
122 * @param baseConfig the {@link ForwardConfig}
123 * to copy configuration values from
124 */
125 public ActionRedirect(ForwardConfig baseConfig) {
126 setName(baseConfig.getName());
127 setPath(baseConfig.getPath());
128 setContextRelative(baseConfig.getContextRelative());
129 setModule(baseConfig.getModule());
130 setRedirect(true);
131 initializeParameters();
132 }
133
134
135
136 // ----------------------------------------------------- Private methods
137
138 /**
139 * <p>Initializes the internal objects
140 * used to hold parameter values.</p>
141 */
142 private void initializeParameters() {
143 parameterValues = new HashMap();
144 }
145
146
147 // ----------------------------------------------------- Public methods
148
149 /**
150 * <p>Adds the object's toString() to the list of parameters if it's
151 * not null, or an empty string with the given fieldName if it is.</p>
152 *
153 * @param fieldName the name to use for the parameter
154 * @param valueObj the value for this parameter
155 */
156 public void addParameter(String fieldName, Object valueObj) {
157
158 String value = (valueObj != null) ? valueObj.toString() : "";
159 if (parameterValues == null) {
160 initializeParameters();
161 }
162
163 //try {
164 value = ResponseUtils.encodeURL(value);
165 //} catch (UnsupportedEncodingException uce) {
166 // this shouldn't happen since UTF-8 is the W3C Recommendation
167 // String errorMsg = "UTF-8 Character Encoding not supported";
168 // log.error(errorMsg, uce);
169 // throw new RuntimeException(errorMsg, uce);
170 // }
171
172 Object currentValue = parameterValues.get(fieldName);
173 if (currentValue == null) {
174 // there's no value for this param yet; add it to the map
175 parameterValues.put(fieldName, value);
176
177 } else if (currentValue instanceof String) {
178 // there's already a value; let's use an array for these parameters
179 String[] newValue = new String[2];
180 newValue[0] = (String) currentValue;
181 newValue[1] = value;
182 parameterValues.put(fieldName, newValue);
183
184 } else if (currentValue instanceof String[]) {
185 // add the value to the list of existing values
186 List newValues = new ArrayList(Arrays.asList((Object[]) currentValue));
187 newValues.add(value);
188 parameterValues.put(fieldName, (String[]) newValues.toArray(new String[newValues.size()]));
189 }
190 }
191
192
193 /**
194 * <p>Get the original path without the parameters added at runtime.</p>
195 *
196 * @return the original path as configured.
197 */
198 public String getOriginalPath() {
199 return super.getPath();
200 }
201
202
203 /**
204 * <p>Get the path for this object, including any parameters
205 * that may have been added at runtime.</p>
206 */
207 public String getPath() {
208 // get the original path and the parameter string that was formed
209 String originalPath = getOriginalPath();
210 String parameterString = getParameterString();
211
212 StringBuffer result = new StringBuffer(originalPath);
213
214 if ((parameterString != null) && (parameterString.length() > 0)) {
215 // the parameter separator we're going to use
216 String paramSeparator = "?";
217
218 // true if we need to use a parameter separator after originalPath
219 boolean needsParamSeparator = true;
220
221 // does the original path already have a "?"?
222 int paramStartIndex = originalPath.indexOf("?");
223 if (paramStartIndex > 0) {
224 // did the path end with "?"?
225 needsParamSeparator =
226 (paramStartIndex != originalPath.length() - 1);
227 if (needsParamSeparator) {
228 paramSeparator = "&";
229 }
230 }
231
232 if (needsParamSeparator) {
233 result.append(paramSeparator);
234 }
235 result.append(parameterString);
236 }
237
238 return result.toString();
239 }
240
241
242 /**
243 * <p>Forms the string containing the parameters
244 * passed onto this object thru calls to addParameter().</p>
245 *
246 * @return a string which can be appended to the URLs. The
247 * return string does not include a leading question
248 * mark (?).
249 */
250 public String getParameterString() {
251 StringBuffer strParam = new StringBuffer(256);
252
253 // loop through all parameters
254 Iterator iterator = parameterValues.keySet().iterator();
255 while (iterator.hasNext()) {
256 // get the parameter name
257 String name = (String) iterator.next();
258
259 // get the value for this parameter
260 Object value = parameterValues.get(name);
261
262 if (value instanceof String) {
263 // just one value for this param
264 strParam.append(name)
265 .append("=")
266 .append(value);
267
268 } else if (value instanceof String[]) {
269 // loop through all values for this param
270 String[] values = (String[]) value;
271 for (int i = 0; i < values.length; i++) {
272 strParam.append(name)
273 .append("=")
274 .append(values[i]);
275 if (i < values.length - 1)
276 strParam.append("&");
277 }
278 }
279
280 if (iterator.hasNext()) {
281 strParam.append("&");
282 }
283 }
284
285 return strParam.toString();
286 }
287
288
289 // ----------------------------------------------------- toString()
290
291 /**
292 * <p>Return a string description of this object.</p>
293 *
294 * @return a string containing the original path for this object
295 * and the parameters it currently holds
296 */
297 public String toString() {
298 StringBuffer result = new StringBuffer(256);
299 result.append("ActionRedirect [");
300 result.append("originalPath=").append(getOriginalPath()).append(";");
301 result.append("parameterString=")
302 .append(getParameterString()).append("]");
303 return result.toString();
304 }
305
306
307 }