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 private String characterEncoding;
127
128
129 private boolean encodeURL = true;
130
131
132
133
134
135
136
137 public Redirect(final String path) {
138 this(path, null);
139 }
140
141
142
143
144
145
146
147
148
149
150 public Redirect(final String path, final String protocol) {
151 this(path, protocol, -1);
152 }
153
154
155
156
157
158
159
160
161
162
163
164
165 public Redirect(final String path, final String protocol, final int port) {
166 this.path = path;
167 this.protocol = protocol;
168 this.port = port;
169 }
170
171
172
173
174
175
176
177
178
179
180 public Redirect(final Class<? extends Action> actionClass) {
181 this(actionClass, "index");
182 }
183
184
185
186
187
188
189
190
191
192
193
194
195 public Redirect(final Class<? extends Action> actionClass,
196 final String methodName) {
197 this(actionClass, methodName, EMPTY_PARAMETERS);
198 }
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213 public Redirect(final Class<? extends Action> actionClass,
214 final String methodName, final Map<String, String[]> parameters) {
215 this(actionClass, methodName, parameters, null);
216 }
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233 public Redirect(final Class<? extends Action> actionClass,
234 final String methodName, final Map<String, String[]> parameters,
235 final String protocol) {
236 this(actionClass, methodName, parameters, protocol, -1);
237 }
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256 public Redirect(final Class<? extends Action> actionClass,
257 final String methodName, final Map<String, String[]> parameters,
258 final String protocol, final int port) {
259 this.actionClass = actionClass;
260 this.methodName = methodName;
261 this.parameters = parameters;
262 this.protocol = protocol;
263 this.port = port;
264 }
265
266
267
268
269
270
271
272
273 public String getPath(final String characterEncoding) {
274 if (isReverseLookupRedirect()) {
275 final S2Container container = SingletonS2ContainerFactory
276 .getContainer();
277 final PathResolver pathResolver = (PathResolver) container
278 .getComponent(PathResolver.class);
279 final String redirectPath = pathResolver.reverseLookup(actionClass,
280 methodName, parameters, characterEncoding);
281 this.path = redirectPath;
282 }
283 return this.path;
284 }
285
286
287
288
289
290
291 private boolean isReverseLookupRedirect() {
292 return this.actionClass != null && this.methodName != null
293 && this.parameters != null;
294 }
295
296
297
298
299 public void execute(final Action action,
300 final Class<? extends Action> actionClass, final Method method,
301 final HttpServletRequest request, final HttpServletResponse response)
302 throws Exception {
303 final String characterEncoding;
304 if (this.characterEncoding == null) {
305 characterEncoding = request.getCharacterEncoding();
306 } else {
307 characterEncoding = this.characterEncoding;
308 }
309 final String redirectURL = calculateRedirectURL(
310 getPath(characterEncoding), actionClass, request);
311 final String encodedRedirectURL = encodeURL(redirectURL, response);
312 if (logger.isDebugEnabled()) {
313 logger.log("DCUB0003", new String[] { encodedRedirectURL });
314 }
315 response.sendRedirect(encodedRedirectURL);
316 }
317
318
319
320
321
322
323
324
325
326
327
328
329 protected String calculateRedirectURL(final String path,
330 final Class<? extends Action> actionClass,
331 final HttpServletRequest request) {
332 try {
333 final String redirectURL = new URL(path).toExternalForm();
334 return redirectURL;
335 } catch (MalformedURLException e) {
336 final String redirectURL = calculateInternalRedirectURL(path,
337 actionClass, request);
338 return redirectURL;
339 }
340 }
341
342
343
344
345
346
347
348
349
350
351
352
353 private String calculateInternalRedirectURL(final String path,
354 final Class<? extends Action> actionClass,
355 final HttpServletRequest request) {
356 final String redirectPath;
357 final String contextPath;
358 if ("/".equals(request.getContextPath())) {
359 contextPath = "";
360 } else {
361 contextPath = request.getContextPath();
362 }
363 if (path.startsWith("/")) {
364 redirectPath = contextPath + path;
365 } else {
366 final String actionDirectory = CubbyUtils
367 .getActionDirectory(actionClass);
368 if (StringUtil.isEmpty(actionDirectory)) {
369 final StringBuilder builder = new StringBuilder();
370 builder.append(contextPath);
371 if (!contextPath.endsWith("/")) {
372 builder.append("/");
373 }
374 builder.append(path);
375 redirectPath = builder.toString();
376 } else {
377 final StringBuilder builder = new StringBuilder();
378 builder.append(contextPath);
379 if (!contextPath.endsWith("/")
380 && !actionDirectory.startsWith("/")) {
381 builder.append("/");
382 }
383 builder.append(actionDirectory);
384 if (!actionDirectory.endsWith("/")) {
385 builder.append("/");
386 }
387 builder.append(path);
388 redirectPath = builder.toString();
389 }
390 }
391
392 if (protocol == null) {
393 return redirectPath;
394 } else {
395 try {
396 final URL currentURL = new URL(request.getRequestURL()
397 .toString());
398 final String redirectProtocol = this.protocol == null ? currentURL
399 .getProtocol()
400 : this.protocol;
401 final int redirectPort = this.port < 0 ? currentURL.getPort()
402 : this.port;
403 final URL redirectURL = new URL(redirectProtocol, currentURL
404 .getHost(), redirectPort, redirectPath);
405 return redirectURL.toExternalForm();
406 } catch (MalformedURLException e) {
407 throw new IORuntimeException(e);
408 }
409 }
410 }
411
412
413
414
415
416
417
418
419
420
421
422 protected String encodeURL(final String url,
423 final HttpServletResponse response) {
424 if (encodeURL) {
425 return response.encodeRedirectURL(url);
426 } else {
427 return url;
428 }
429 }
430
431
432
433
434
435
436
437
438
439
440
441 public Redirect noEncodeURL() {
442 this.encodeURL = false;
443 return this;
444 }
445
446
447
448
449
450
451
452
453
454
455
456 public Redirect param(String paramName, Object paramValue) {
457 return param(paramName, new String[] { paramValue.toString() });
458 }
459
460
461
462
463
464
465
466
467
468
469
470 public Redirect param(final String paramName, final Object[] paramValues) {
471 return param(paramName, toStringArray(paramValues));
472 }
473
474
475
476
477
478
479
480
481
482
483
484 public Redirect param(final String paramName, final String[] paramValues) {
485 if (isReverseLookupRedirect()) {
486 if (this.parameters == EMPTY_PARAMETERS) {
487 this.parameters = new HashMap<String, String[]>();
488 }
489 this.parameters.put(paramName, paramValues);
490 } else {
491 QueryStringBuilder builder = new QueryStringBuilder(this.path);
492 builder.addParam(paramName, paramValues);
493 this.path = builder.toString();
494 }
495 return this;
496 }
497
498
499
500
501
502
503
504
505
506
507
508 private String[] toStringArray(final Object[] paramValues) {
509 String[] values = new String[paramValues.length];
510 for (int i = 0; i < paramValues.length; i++) {
511 values[i] = paramValues[i].toString();
512 }
513 return values;
514 }
515
516
517
518
519
520
521
522
523
524 public Redirect characterEncoding(final String characterEncoding) {
525 this.characterEncoding = characterEncoding;
526 return this;
527 }
528
529
530
531
532
533
534
535 @Deprecated
536 public String getPath() {
537 return getPath("UTF-8");
538 }
539
540 }