1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.seasar.cubby.internal.controller.impl;
18
19 import static org.seasar.cubby.CubbyConstants.ATTR_ACTION;
20 import static org.seasar.cubby.CubbyConstants.ATTR_ACTION_CONTEXT;
21 import static org.seasar.cubby.CubbyConstants.ATTR_CONVERSION_FAILURES;
22 import static org.seasar.cubby.CubbyConstants.ATTR_ERRORS;
23 import static org.seasar.cubby.CubbyConstants.ATTR_FLASH;
24 import static org.seasar.cubby.CubbyConstants.ATTR_PARAMS;
25 import static org.seasar.cubby.CubbyConstants.ATTR_VALIDATION_FAIL;
26 import static org.seasar.cubby.CubbyConstants.ATTR_WRAPEE_REQUEST;
27 import static org.seasar.cubby.internal.util.LogMessages.format;
28 import static org.seasar.cubby.validator.ValidationUtils.getValidation;
29 import static org.seasar.cubby.validator.ValidationUtils.getValidationRules;
30
31 import java.lang.reflect.InvocationTargetException;
32 import java.lang.reflect.Method;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.Map;
36
37 import javax.servlet.ServletRequest;
38 import javax.servlet.http.HttpServletRequest;
39 import javax.servlet.http.HttpServletResponse;
40
41 import org.seasar.cubby.action.ActionContext;
42 import org.seasar.cubby.action.ActionErrors;
43 import org.seasar.cubby.action.ActionException;
44 import org.seasar.cubby.action.ActionResult;
45 import org.seasar.cubby.action.Validation;
46 import org.seasar.cubby.internal.controller.ActionProcessor;
47 import org.seasar.cubby.internal.controller.ActionResultWrapper;
48 import org.seasar.cubby.internal.controller.ConversionFailure;
49 import org.seasar.cubby.internal.controller.RequestParameterBinder;
50 import org.seasar.cubby.internal.util.RequestUtils;
51 import org.seasar.cubby.plugin.ActionInvocation;
52 import org.seasar.cubby.plugin.Plugin;
53 import org.seasar.cubby.plugin.PluginRegistry;
54 import org.seasar.cubby.plugin.ValidationInvocation;
55 import org.seasar.cubby.routing.Routing;
56 import org.seasar.cubby.spi.ContainerProvider;
57 import org.seasar.cubby.spi.ProviderFactory;
58 import org.seasar.cubby.spi.container.Container;
59 import org.seasar.cubby.validator.ValidationException;
60 import org.seasar.cubby.validator.ValidationFailBehaviour;
61 import org.seasar.cubby.validator.ValidationRules;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
64
65
66
67
68
69
70 public class ActionProcessorImpl implements ActionProcessor {
71
72
73 private static final Logger logger = LoggerFactory
74 .getLogger(ActionProcessorImpl.class);
75
76
77
78
79 public ActionResultWrapper process(final HttpServletRequest request,
80 final HttpServletResponse response, final Routing routing)
81 throws Exception {
82
83 final Method actionMethod = routing.getActionMethod();
84 if (logger.isDebugEnabled()) {
85 logger.debug(format("DCUB0004", request.getRequestURI()));
86 logger.debug(format("DCUB0005", actionMethod));
87 }
88
89 final Class<?> actionClass = routing.getActionClass();
90
91 final Container container = ProviderFactory
92 .get(ContainerProvider.class).getContainer();
93
94 final Object action = container.lookup(actionClass);
95 request.setAttribute(ATTR_ACTION, action);
96
97 final HttpServletRequest wrapeeRequest = (HttpServletRequest) request
98 .getAttribute(ATTR_WRAPEE_REQUEST);
99 final ActionErrors actionErrors = setupActionErrors(wrapeeRequest);
100 final Map<String, Object> flashMap = setupFlashMap(wrapeeRequest);
101 final ActionContext actionContext = new ActionContextImpl(request,
102 action, actionClass, actionMethod, actionErrors, flashMap);
103 request.setAttribute(ATTR_ACTION_CONTEXT, actionContext);
104
105 actionContext.invokeInitializeMethod();
106
107 final ActionInvocation actionInvocation = new ActionInvocationImpl(
108 request, response, actionContext);
109 final ActionResult actionResult = actionInvocation.proceed();
110 if (actionResult == null) {
111 throw new ActionException(format("ECUB0101", actionMethod));
112 }
113
114 final ActionResultWrapper actionResultWrapper = new ActionResultWrapperImpl(
115 actionResult, actionContext);
116 return actionResultWrapper;
117 }
118
119 private ActionErrors setupActionErrors(final ServletRequest request) {
120 final ActionErrors actionErrors = (ActionErrors) request
121 .getAttribute(ATTR_ERRORS);
122 if (actionErrors != null) {
123 return actionErrors;
124 }
125
126 final ActionErrors newActionErrors = new ActionErrorsImpl();
127 request.setAttribute(ATTR_ERRORS, newActionErrors);
128 return newActionErrors;
129 }
130
131 private Map<String, Object> setupFlashMap(final ServletRequest request) {
132 @SuppressWarnings("unchecked")
133 final Map<String, Object> flashMap = (Map<String, Object>) request
134 .getAttribute(ATTR_FLASH);
135 if (flashMap != null) {
136 return flashMap;
137 }
138
139 final Map<String, Object> newFlashMap = new FlashMapImpl(
140 (HttpServletRequest) request);
141 request.setAttribute(ATTR_FLASH, newFlashMap);
142 return newFlashMap;
143 }
144
145
146
147
148
149
150 static class ActionInvocationImpl implements ActionInvocation {
151
152
153 private final HttpServletRequest request;
154
155
156 private final HttpServletResponse response;
157
158
159 private final ActionContext actionContext;
160
161
162 private final Iterator<Plugin> pluginsIterator;
163
164
165
166
167
168
169
170
171
172
173
174 public ActionInvocationImpl(final HttpServletRequest request,
175 final HttpServletResponse response,
176 final ActionContext actionContext) {
177 this.request = request;
178 this.response = response;
179 this.actionContext = actionContext;
180
181 final PluginRegistry pluginRegistry = PluginRegistry.getInstance();
182 this.pluginsIterator = pluginRegistry.getPlugins().iterator();
183 }
184
185
186
187
188 public ActionResult proceed() throws Exception {
189 final ActionResult actionResult;
190 if (pluginsIterator.hasNext()) {
191 final Plugin plugin = pluginsIterator.next();
192 actionResult = plugin.invokeAction(this);
193 } else {
194 final ValidationInvocation validationInvocation = new ValidationInvocationImpl(
195 request, response, actionContext);
196 return validationInvocation.proceed();
197 }
198 return actionResult;
199 }
200
201
202
203
204 public HttpServletRequest getRequest() {
205 return request;
206 }
207
208
209
210
211 public HttpServletResponse getResponse() {
212 return response;
213 }
214
215
216
217
218 public ActionContext getActionContext() {
219 return actionContext;
220 }
221
222 }
223
224
225
226
227
228
229 static class ValidationInvocationImpl implements ValidationInvocation {
230
231
232 private final RequestParameterBinder requestParameterBinder = new RequestParameterBinderImpl();
233
234
235 private final HttpServletRequest request;
236
237
238 private final HttpServletResponse response;
239
240
241 private final ActionContext actionContext;
242
243
244 private final Iterator<Plugin> pluginsIterator;
245
246
247
248
249
250
251
252
253
254
255
256 public ValidationInvocationImpl(final HttpServletRequest request,
257 final HttpServletResponse response,
258 final ActionContext actionContext) {
259 this.request = request;
260 this.response = response;
261 this.actionContext = actionContext;
262
263 final PluginRegistry pluginRegistry = PluginRegistry.getInstance();
264 this.pluginsIterator = pluginRegistry.getPlugins().iterator();
265 }
266
267
268
269
270 public ActionResult proceed() throws Exception {
271 final ActionResult actionResult;
272 if (pluginsIterator.hasNext()) {
273 final Plugin plugin = pluginsIterator.next();
274 actionResult = plugin.invokeValidation(this);
275 } else {
276 final Map<String, Object[]> parameterMap = RequestUtils
277 .getAttribute(request, ATTR_PARAMS);
278 final Object formBean = actionContext.getFormBean();
279
280 if (formBean != null) {
281 final List<ConversionFailure> conversionFailures = requestParameterBinder
282 .bind(parameterMap, formBean, actionContext);
283 request.setAttribute(ATTR_CONVERSION_FAILURES,
284 conversionFailures);
285 }
286
287 try {
288 final Validation validation = getValidation(actionContext
289 .getActionMethod());
290 if (validation != null) {
291 final ValidationRules validationRules = getValidationRules(
292 actionContext.getAction(), validation.rules());
293 validationRules.validate(parameterMap, formBean,
294 actionContext.getActionErrors());
295 }
296 try {
297 final Object action = actionContext.getAction();
298 final Method actionMethod = actionContext
299 .getActionMethod();
300 actionResult = (ActionResult) actionMethod
301 .invoke(action);
302 } catch (final InvocationTargetException e) {
303 final Throwable cause = e.getCause();
304 if (cause instanceof ValidationException) {
305 throw (ValidationException) cause;
306 }
307 throw e;
308 }
309 } catch (final ValidationException e) {
310 request.setAttribute(ATTR_VALIDATION_FAIL, Boolean.TRUE);
311 final ValidationFailBehaviour behaviour = e.getBehaviour();
312 return behaviour
313 .getValidationErrorActionResult(actionContext);
314 }
315 }
316 return actionResult;
317 }
318
319
320
321
322 public HttpServletRequest getRequest() {
323 return request;
324 }
325
326
327
328
329 public HttpServletResponse getResponse() {
330 return response;
331 }
332
333
334
335
336 public ActionContext getActionContext() {
337 return actionContext;
338 }
339
340 }
341
342 }