1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.seasar.cubby.action;
17
18 import java.lang.reflect.Method;
19 import java.net.MalformedURLException;
20 import java.net.URL;
21 import java.util.Collections;
22 import java.util.HashMap;
23 import java.util.Map;
24
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.http.HttpServletResponse;
27
28 import org.seasar.cubby.routing.PathResolver;
29 import org.seasar.cubby.util.CubbyUtils;
30 import org.seasar.cubby.util.QueryStringBuilder;
31 import org.seasar.framework.container.S2Container;
32 import org.seasar.framework.container.factory.SingletonS2ContainerFactory;
33 import org.seasar.framework.exception.IORuntimeException;
34 import org.seasar.framework.log.Logger;
35 import org.seasar.framework.util.StringUtil;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 public class Redirect implements ActionResult {
99
100
101 private static final Logger logger = Logger.getLogger(Redirect.class);
102
103
104 private static final Map<String, String[]> EMPTY_PARAMETERS = Collections
105 .emptyMap();
106
107
108 private String path;
109
110
111 private final String protocol;
112
113
114 private final int port;
115
116
117 private Class<? extends Action> actionClass;
118
119
120 private String methodName;
121
122
123 private Map<String, String[]> parameters;
124
125
126
127
128
129
130
131 public Redirect(final String path) {
132 this(path, null);
133 }
134
135
136
137
138
139
140
141
142
143
144 public Redirect(final String path, final String protocol) {
145 this(path, protocol, -1);
146 }
147
148
149
150
151
152
153
154
155
156
157
158
159 public Redirect(final String path, final String protocol, final int port) {
160 this.path = path;
161 this.protocol = protocol;
162 this.port = port;
163 }
164
165
166
167
168
169
170
171
172
173
174
175
176 public Redirect(final Class<? extends Action> actionClass,
177 final String methodName) {
178 this(actionClass, methodName, EMPTY_PARAMETERS);
179 }
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194 public Redirect(final Class<? extends Action> actionClass,
195 final String methodName, final Map<String, String[]> parameters) {
196 this(actionClass, methodName, parameters, null);
197 }
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214 public Redirect(final Class<? extends Action> actionClass,
215 final String methodName, final Map<String, String[]> parameters,
216 final String protocol) {
217 this(actionClass, methodName, parameters, protocol, -1);
218 }
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237 public Redirect(final Class<? extends Action> actionClass,
238 final String methodName, final Map<String, String[]> parameters,
239 final String protocol, final int port) {
240 this.actionClass = actionClass;
241 this.methodName = methodName;
242 this.parameters = parameters;
243 this.protocol = protocol;
244 this.port = port;
245 }
246
247
248
249
250
251
252 public String getPath() {
253 if (isReverseLookupRedirect()) {
254 final S2Container container = SingletonS2ContainerFactory
255 .getContainer();
256 final PathResolver pathResolver = (PathResolver) container
257 .getComponent(PathResolver.class);
258 final String redirectPath = pathResolver.reverseLookup(actionClass,
259 methodName, parameters);
260 this.path = redirectPath;
261 }
262 return this.path;
263 }
264
265
266
267
268
269 private boolean isReverseLookupRedirect() {
270 return this.actionClass != null && this.methodName != null && this.parameters != null;
271 }
272
273
274
275
276 public void execute(final Action action,
277 final Class<? extends Action> actionClass, final Method method,
278 final HttpServletRequest request, final HttpServletResponse response)
279 throws Exception {
280 final String redirectURL = calculateRedirectURL(getPath(), actionClass,
281 request);
282 final String encodedRedirectURL = encodeURL(redirectURL, response);
283 if (logger.isDebugEnabled()) {
284 logger.log("DCUB0003", new String[] { encodedRedirectURL });
285 }
286 response.sendRedirect(encodedRedirectURL);
287 }
288
289
290
291
292
293
294
295
296
297
298
299
300 protected String calculateRedirectURL(final String path,
301 final Class<? extends Action> actionClass,
302 final HttpServletRequest request) {
303 try {
304 final String redirectURL = new URL(path).toExternalForm();
305 return redirectURL;
306 } catch (MalformedURLException e) {
307 final String redirectURL = calculateInternalRedirectURL(path,
308 actionClass, request);
309 return redirectURL;
310 }
311 }
312
313
314
315
316
317
318
319
320
321
322
323
324 private String calculateInternalRedirectURL(final String path,
325 final Class<? extends Action> actionClass,
326 final HttpServletRequest request) {
327 final String redirectPath;
328 final String contextPath;
329 if ("/".equals(request.getContextPath())) {
330 contextPath = "";
331 } else {
332 contextPath = request.getContextPath();
333 }
334 if (path.startsWith("/")) {
335 redirectPath = contextPath + path;
336 } else {
337 final String actionDirectory = CubbyUtils
338 .getActionDirectory(actionClass);
339 if (StringUtil.isEmpty(actionDirectory)) {
340 final StringBuilder builder = new StringBuilder();
341 builder.append(contextPath);
342 if (!contextPath.endsWith("/")) {
343 builder.append("/");
344 }
345 builder.append(path);
346 redirectPath = builder.toString();
347 } else {
348 final StringBuilder builder = new StringBuilder();
349 builder.append(contextPath);
350 if (!contextPath.endsWith("/")
351 && !actionDirectory.startsWith("/")) {
352 builder.append("/");
353 }
354 builder.append(actionDirectory);
355 if (!actionDirectory.endsWith("/")) {
356 builder.append("/");
357 }
358 builder.append(path);
359 redirectPath = builder.toString();
360 }
361 }
362
363 if (protocol == null) {
364 return redirectPath;
365 } else {
366 try {
367 final URL currentURL = new URL(request.getRequestURL()
368 .toString());
369 final String redirectProtocol = this.protocol == null ? currentURL
370 .getProtocol()
371 : this.protocol;
372 final int redirectPort = this.port < 0 ? currentURL.getPort()
373 : this.port;
374 final URL redirectURL = new URL(redirectProtocol, currentURL
375 .getHost(), redirectPort, redirectPath);
376 return redirectURL.toExternalForm();
377 } catch (MalformedURLException e) {
378 throw new IORuntimeException(e);
379 }
380 }
381 }
382
383
384
385
386
387
388
389
390
391
392
393 protected String encodeURL(final String url,
394 final HttpServletResponse response) {
395 return response.encodeRedirectURL(url);
396 }
397
398
399
400
401
402
403
404
405
406
407
408 public ActionResult noEncodeURL() {
409 return new Redirect(path, protocol, port) {
410 @Override
411 protected String encodeURL(final String url,
412 final HttpServletResponse response) {
413 return url;
414 }
415 };
416 }
417
418
419
420
421
422
423
424 public Redirect param(String paramName, Object paramValue) {
425 return param(paramName, new String[] { paramValue.toString() });
426 }
427
428
429
430
431
432
433
434 public Redirect param(final String paramName, final Object[] paramValues) {
435 return param(paramName, toStringArray(paramValues));
436 }
437
438
439
440
441
442
443
444 public Redirect param(final String paramName, final String[] paramValues) {
445 if (isReverseLookupRedirect()) {
446 if (this.parameters == EMPTY_PARAMETERS) {
447 this.parameters = new HashMap<String, String[]>();
448 }
449 this.parameters.put(paramName, paramValues);
450 } else {
451 QueryStringBuilder builder = new QueryStringBuilder(this.path);
452 builder.addParam(paramName, paramValues);
453 this.path = builder.toString();
454 }
455 return this;
456 }
457
458
459
460
461
462
463
464
465
466 private String[] toStringArray(final Object[] paramValues) {
467 String[] values = new String[paramValues.length];
468 for (int i = 0; i < paramValues.length; i++) {
469 values[i] = paramValues[i].toString();
470 }
471 return values;
472 }
473 }