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