1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.seasar.cubby.action;
17
18 import static org.seasar.cubby.CubbyConstants.ATTR_ROUTINGS;
19
20 import java.io.IOException;
21 import java.lang.reflect.Method;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.regex.Pattern;
27
28 import javax.servlet.RequestDispatcher;
29 import javax.servlet.ServletException;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32
33 import org.seasar.cubby.routing.PathResolver;
34 import org.seasar.cubby.routing.Routing;
35 import org.seasar.cubby.util.CubbyUtils;
36 import org.seasar.cubby.util.QueryStringBuilder;
37 import org.seasar.framework.container.S2Container;
38 import org.seasar.framework.container.factory.SingletonS2ContainerFactory;
39 import org.seasar.framework.log.Logger;
40 import org.seasar.framework.util.ClassUtil;
41 import org.seasar.framework.util.StringUtil;
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 public class Forward implements ActionResult {
98
99
100 private static final Logger logger = Logger.getLogger(Forward.class);
101
102
103 private static final Map<String, String[]> EMPTY_PARAMETERS = Collections
104 .emptyMap();
105
106
107 private String path;
108
109
110 private final Map<String, Routing> routings;
111
112
113 private Class<? extends Action> actionClass;
114
115
116 private String methodName;
117
118
119 private Map<String, String[]> parameters;
120
121
122
123
124
125
126
127 public Forward(final String path) {
128 this.path = path;
129 this.routings = null;
130 }
131
132
133
134
135
136
137
138
139
140
141
142
143 public Forward(final Class<? extends Action> actionClass,
144 final String methodName, final Map<String, String[]> parameters) {
145 this.actionClass = actionClass;
146 this.methodName = methodName;
147 this.parameters = parameters;
148 final Method method = ClassUtil.getMethod(actionClass, methodName,
149 new Class[0]);
150 final Routing routing = new ForwardRouting(actionClass, method);
151 this.routings = Collections.singletonMap(null, routing);
152 }
153
154
155
156
157
158
159
160
161 public Forward(final Class<? extends Action> actionClass) {
162 this(actionClass, "index");
163 }
164
165
166
167
168
169
170
171
172
173
174 public Forward(final Class<? extends Action> actionClass,
175 final String methodName) {
176 this(actionClass, methodName, EMPTY_PARAMETERS);
177 }
178
179
180
181
182
183
184
185
186 public String getPath(final String characterEncoding) {
187 if (isReverseLookupRedirect()) {
188 final S2Container container = SingletonS2ContainerFactory
189 .getContainer();
190 final PathResolver pathResolver = PathResolver.class.cast(container
191 .getComponent(PathResolver.class));
192 this.path = pathResolver.buildInternalForwardPath(parameters,
193 characterEncoding);
194 }
195 return this.path;
196 }
197
198
199
200
201
202
203 private boolean isReverseLookupRedirect() {
204 return this.actionClass != null && this.methodName != null
205 && this.parameters != null;
206 }
207
208
209
210
211 public void execute(final Action action,
212 final Class<? extends Action> actionClass, final Method method,
213 final HttpServletRequest request, final HttpServletResponse response)
214 throws ServletException, IOException {
215 action.invokePreRenderMethod(method);
216
217 final String forwardPath = calculateForwardPath(getPath(request
218 .getCharacterEncoding()), actionClass, request
219 .getCharacterEncoding());
220 if (this.routings != null) {
221 request.setAttribute(ATTR_ROUTINGS, this.routings);
222 }
223 if (logger.isDebugEnabled()) {
224 logger.log("DCUB0001", new Object[] { forwardPath, routings });
225 }
226 final RequestDispatcher dispatcher = request
227 .getRequestDispatcher(forwardPath);
228 dispatcher.forward(request, response);
229 if (logger.isDebugEnabled()) {
230 logger.log("DCUB0002", new Object[] { forwardPath });
231 }
232
233 action.invokePostRenderMethod(method);
234 if (action.getFlash() != null) {
235 action.getFlash().clear();
236 }
237 }
238
239
240
241
242
243
244
245
246
247
248 protected String calculateForwardPath(final String path,
249 final Class<? extends Action> actionClass,
250 final String characterEncoding) {
251 final String absolutePath;
252 if (getPath(characterEncoding).startsWith("/")) {
253 absolutePath = path;
254 } else {
255 final String actionDirectory = CubbyUtils
256 .getActionDirectory(actionClass);
257 if (StringUtil.isEmpty(actionDirectory)) {
258 absolutePath = "/" + path;
259 } else {
260 final StringBuilder builder = new StringBuilder();
261 if (!actionDirectory.startsWith("/")) {
262 builder.append("/");
263 }
264 builder.append(actionDirectory);
265 if (!actionDirectory.endsWith("/")) {
266 builder.append("/");
267 }
268 builder.append(path);
269 absolutePath = builder.toString();
270 }
271 }
272 return absolutePath;
273 }
274
275
276
277
278
279
280
281
282
283
284 public Forward param(String paramName, Object paramValue) {
285 return param(paramName, new String[] { paramValue.toString() });
286 }
287
288
289
290
291
292
293
294
295
296
297 public Forward param(final String paramName, final Object[] paramValues) {
298 return param(paramName, toStringArray(paramValues));
299 }
300
301
302
303
304
305
306
307
308
309
310 public Forward param(final String paramName, final String[] paramValues) {
311 if (isReverseLookupRedirect()) {
312 if (this.parameters == EMPTY_PARAMETERS) {
313 this.parameters = new HashMap<String, String[]>();
314 }
315 this.parameters.put(paramName, paramValues);
316 } else {
317 QueryStringBuilder builder = new QueryStringBuilder(this.path);
318 builder.addParam(paramName, paramValues);
319 this.path = builder.toString();
320 }
321 return this;
322 }
323
324
325
326
327
328
329
330
331
332
333
334 private String[] toStringArray(final Object[] paramValues) {
335 String[] values = new String[paramValues.length];
336 for (int i = 0; i < paramValues.length; i++) {
337 values[i] = paramValues[i].toString();
338 }
339 return values;
340 }
341
342
343
344
345
346
347
348 @Deprecated
349 public String getPath() {
350 return getPath("UTF-8");
351 }
352
353
354
355
356
357
358
359 private static class ForwardRouting implements Routing {
360
361
362 private Class<? extends Action> actionClass;
363
364
365 private Method method;
366
367
368
369
370 private ForwardRouting(final Class<? extends Action> actionClass,
371 final Method method) {
372 this.actionClass = actionClass;
373 this.method = method;
374 }
375
376
377
378
379 public Class<? extends Action> getActionClass() {
380 return actionClass;
381 }
382
383
384
385
386 public Method getMethod() {
387 return method;
388 }
389
390
391
392
393 public String getActionPath() {
394 return null;
395 }
396
397
398
399
400 public List<String> getUriParameterNames() {
401 return null;
402 }
403
404
405
406
407 public Pattern getPattern() {
408 return null;
409 }
410
411
412
413
414 public RequestMethod getRequestMethod() {
415 return null;
416 }
417
418
419
420
421 public String getOnSubmit() {
422 return null;
423 }
424
425
426
427
428 public int getPriority() {
429 return 0;
430 }
431
432
433
434
435 public boolean isAuto() {
436 return false;
437 }
438
439
440
441
442 public boolean isAcceptable(final String requestMethod) {
443 return true;
444 }
445
446
447
448
449 @Override
450 public String toString() {
451 return new StringBuilder().append("[").append(method).append("]")
452 .toString();
453 }
454
455 }
456
457 }