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
235 action.getFlash().clear();
236 }
237
238
239
240
241
242
243
244
245
246
247 protected String calculateForwardPath(final String path,
248 final Class<? extends Action> actionClass,
249 final String characterEncoding) {
250 final String absolutePath;
251 if (getPath(characterEncoding).startsWith("/")) {
252 absolutePath = path;
253 } else {
254 final String actionDirectory = CubbyUtils
255 .getActionDirectory(actionClass);
256 if (StringUtil.isEmpty(actionDirectory)) {
257 absolutePath = "/" + path;
258 } else {
259 final StringBuilder builder = new StringBuilder();
260 if (!actionDirectory.startsWith("/")) {
261 builder.append("/");
262 }
263 builder.append(actionDirectory);
264 if (!actionDirectory.endsWith("/")) {
265 builder.append("/");
266 }
267 builder.append(path);
268 absolutePath = builder.toString();
269 }
270 }
271 return absolutePath;
272 }
273
274
275
276
277
278
279
280
281
282
283 public Forward param(String paramName, Object paramValue) {
284 return param(paramName, new String[] { paramValue.toString() });
285 }
286
287
288
289
290
291
292
293
294
295
296 public Forward param(final String paramName, final Object[] paramValues) {
297 return param(paramName, toStringArray(paramValues));
298 }
299
300
301
302
303
304
305
306
307
308
309 public Forward param(final String paramName, final String[] paramValues) {
310 if (isReverseLookupRedirect()) {
311 if (this.parameters == EMPTY_PARAMETERS) {
312 this.parameters = new HashMap<String, String[]>();
313 }
314 this.parameters.put(paramName, paramValues);
315 } else {
316 QueryStringBuilder builder = new QueryStringBuilder(this.path);
317 builder.addParam(paramName, paramValues);
318 this.path = builder.toString();
319 }
320 return this;
321 }
322
323
324
325
326
327
328
329
330
331
332
333 private String[] toStringArray(final Object[] paramValues) {
334 String[] values = new String[paramValues.length];
335 for (int i = 0; i < paramValues.length; i++) {
336 values[i] = paramValues[i].toString();
337 }
338 return values;
339 }
340
341
342
343
344
345
346
347 @Deprecated
348 public String getPath() {
349 return getPath("UTF-8");
350 }
351
352
353
354
355
356
357
358 private static class ForwardRouting implements Routing {
359
360
361 private Class<? extends Action> actionClass;
362
363
364 private Method method;
365
366
367
368
369 private ForwardRouting(final Class<? extends Action> actionClass,
370 final Method method) {
371 this.actionClass = actionClass;
372 this.method = method;
373 }
374
375
376
377
378 public Class<? extends Action> getActionClass() {
379 return actionClass;
380 }
381
382
383
384
385 public Method getMethod() {
386 return method;
387 }
388
389
390
391
392 public String getActionPath() {
393 return null;
394 }
395
396
397
398
399 public List<String> getUriParameterNames() {
400 return null;
401 }
402
403
404
405
406 public Pattern getPattern() {
407 return null;
408 }
409
410
411
412
413 public RequestMethod getRequestMethod() {
414 return null;
415 }
416
417
418
419
420 public String getOnSubmit() {
421 return null;
422 }
423
424
425
426
427 public int getPriority() {
428 return 0;
429 }
430
431
432
433
434 public boolean isAuto() {
435 return false;
436 }
437
438
439
440
441 public boolean isAcceptable(final String requestMethod) {
442 return true;
443 }
444
445
446
447
448 @Override
449 public String toString() {
450 return new StringBuilder().append("[").append(method).append("]")
451 .toString();
452 }
453
454 }
455
456 }