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