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.cubby.util.LinkBuilder;
32 import org.seasar.framework.container.S2Container;
33 import org.seasar.framework.container.factory.SingletonS2ContainerFactory;
34 import org.seasar.framework.exception.IORuntimeException;
35 import org.seasar.framework.log.Logger;
36 import org.seasar.framework.util.StringUtil;
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
99 public class Redirect implements ActionResult {
100
101
102 private static final Logger logger = Logger.getLogger(Redirect.class);
103
104
105 private static final Map<String, String[]> EMPTY_PARAMETERS = Collections
106 .emptyMap();
107
108
109 private final LinkBuilder linkBuilder = new LinkBuilder();
110
111
112 private String path;
113
114
115 private Class<? extends Action> actionClass;
116
117
118 private String methodName;
119
120
121 private Map<String, String[]> parameters;
122
123
124 private String characterEncoding;
125
126
127 private boolean encodeURL = true;
128
129
130
131
132
133
134
135 public Redirect(final String path) {
136 this.path = path;
137 }
138
139
140
141
142
143
144
145
146
147
148 public Redirect(final String path, final String protocol) {
149 this(path);
150 linkBuilder.setProtocol(protocol);
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164 public Redirect(final String path, final String protocol, final int port) {
165 this(path);
166 linkBuilder.setProtocol(protocol);
167 linkBuilder.setPort(port);
168 }
169
170
171
172
173
174
175
176
177
178
179 public Redirect(final Class<? extends Action> actionClass) {
180 this(actionClass, "index");
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) {
196 this(actionClass, methodName, EMPTY_PARAMETERS);
197 }
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212 public Redirect(final Class<? extends Action> actionClass,
213 final String methodName, final Map<String, String[]> parameters) {
214 this.actionClass = actionClass;
215 this.methodName = methodName;
216 this.parameters = parameters;
217 }
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234 public Redirect(final Class<? extends Action> actionClass,
235 final String methodName, final Map<String, String[]> parameters,
236 final String protocol) {
237 this(actionClass, methodName, parameters);
238 linkBuilder.setProtocol(protocol);
239 }
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258 public Redirect(final Class<? extends Action> actionClass,
259 final String methodName, final Map<String, String[]> parameters,
260 final String protocol, final int port) {
261 this(actionClass, methodName, parameters);
262 linkBuilder.setProtocol(protocol);
263 linkBuilder.setPort(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 try {
393 return linkBuilder.file(redirectPath).toLink(request);
394 } catch (final MalformedURLException e) {
395 throw new IORuntimeException(e);
396 }
397 }
398
399
400
401
402
403
404
405
406
407
408
409 protected String encodeURL(final String url,
410 final HttpServletResponse response) {
411 if (encodeURL) {
412 return response.encodeRedirectURL(url);
413 } else {
414 return url;
415 }
416 }
417
418
419
420
421
422
423
424
425
426
427
428 public Redirect noEncodeURL() {
429 this.encodeURL = false;
430 return this;
431 }
432
433
434
435
436
437
438
439
440
441
442
443 public Redirect param(String paramName, Object paramValue) {
444 return param(paramName, new String[] { paramValue.toString() });
445 }
446
447
448
449
450
451
452
453
454
455
456
457 public Redirect param(final String paramName, final Object[] paramValues) {
458 return param(paramName, toStringArray(paramValues));
459 }
460
461
462
463
464
465
466
467
468
469
470
471 public Redirect param(final String paramName, final String[] paramValues) {
472 if (isReverseLookupRedirect()) {
473 if (this.parameters == EMPTY_PARAMETERS) {
474 this.parameters = new HashMap<String, String[]>();
475 }
476 this.parameters.put(paramName, paramValues);
477 } else {
478 QueryStringBuilder builder = new QueryStringBuilder(this.path);
479 builder.addParam(paramName, paramValues);
480 this.path = builder.toString();
481 }
482 return this;
483 }
484
485
486
487
488
489
490
491
492
493
494
495 private String[] toStringArray(final Object[] paramValues) {
496 String[] values = new String[paramValues.length];
497 for (int i = 0; i < paramValues.length; i++) {
498 values[i] = paramValues[i].toString();
499 }
500 return values;
501 }
502
503
504
505
506
507
508
509
510
511 public Redirect characterEncoding(final String characterEncoding) {
512 this.characterEncoding = characterEncoding;
513 return this;
514 }
515
516
517
518
519
520
521
522 @Deprecated
523 public String getPath() {
524 return getPath("UTF-8");
525 }
526
527 }