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