001: /*
002: * Copyright 2005-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005: * in compliance with the License. You may obtain a copy of the License at
006: *
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software distributed under the License
010: * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011: * or implied. See the License for the specific language governing permissions and limitations under
012: * the License.
013: */
014:
015: package org.strecks.controller;
016:
017: import java.io.IOException;
018:
019: import javax.servlet.ServletContext;
020: import javax.servlet.ServletException;
021: import javax.servlet.http.HttpServletRequest;
022: import javax.servlet.http.HttpServletResponse;
023:
024: import org.apache.struts.Globals;
025: import org.apache.struts.action.Action;
026: import org.apache.struts.action.ActionForm;
027: import org.apache.struts.action.ActionForward;
028: import org.apache.struts.action.ActionMapping;
029: import org.apache.struts.action.ActionServlet;
030: import org.apache.struts.config.ModuleConfig;
031: import org.strecks.builder.Bootstrapper;
032: import org.strecks.builder.Builder;
033: import org.strecks.context.ActionContext;
034: import org.strecks.context.ActionContextFactory;
035: import org.strecks.form.controller.BindingForm;
036: import org.strecks.form.controller.ValidForm;
037: import org.strecks.form.handler.FormWrapper;
038: import org.strecks.form.handler.FormPopulateSource;
039: import org.strecks.form.handler.FormValidationHandler;
040: import org.strecks.preprocess.RequestPreprocessor;
041:
042: /**
043: * <p>Implementation of <code>TilesRequestProcessor</code> subclass for adding extension specific
044: * functionality using hooks provided by <code>BaseRequestProcessor</code></p
045: * <p><b>Note:</b> this class can be maintained by simply copying any updates from <code>BaseRequestProcessor</code>.
046: * The only difference is that it extends <code>TilesRequestProcessor</code>, not <code>RequestProcessor</code></p>
047:
048: * @author Phil Zoio
049: *
050: */
051: public class TilesControllerRequestProcessor extends
052: BaseTilesRequestProcessor {
053:
054: private ServletContext servletContext;
055:
056: private ControllerProcessorDelegate delegate;
057:
058: private FormWrapper formHandler;
059:
060: private ActionCreator actionCreator;
061:
062: private ActionContextFactory actionContextFactory;
063:
064: private FormValidationHandler formValidationHandler;
065:
066: private FormPopulateSource formPopulateSource;
067:
068: private RequestPreprocessor requestPreprocessor;
069:
070: /**
071: * Performs extension-specific configuration tasks
072: */
073: @Override
074: protected void postInit(ActionServlet servlet, ModuleConfig config) {
075: setServletContext(servlet.getServletContext());
076:
077: Bootstrapper bootstrapper = new Bootstrapper();
078: bootstrapper.bootStrap();
079: Builder builder = bootstrapper.getBuilder();
080: builder.build(config.getPrefix());
081:
082: setDelegate(builder.getControllerDelegate());
083: setFormHandler(builder.getFormHandler());
084: setActionCreator(builder.getActionCreator());
085: setActionContextFactory(builder.getActionContextFactory());
086: setFormValidationHandler(builder.getFormValidationHandler());
087: setFormPopulationSource(builder.getFormPopulateSource());
088: setRequestPreprocessor(builder.getRequestPreprocessor());
089: }
090:
091: /**
092: * Removes <code>Globals.ERROR_KEY</code> from session and adds as a request attribute. This
093: * allows errors to support redirect after post. The errors are added to the session
094: */
095: @Override
096: protected void preProcessCachedMessages(HttpServletRequest request) {
097: requestPreprocessor.preprocessRequest(request);
098: }
099:
100: /**
101: * Provides overriding behaviour of <code>ControllerRequestProcessor</code> for
102: * <code>processActionForm()</code>
103: * @return
104: */
105: @Override
106: protected ActionForm postProcessActionForm(
107: HttpServletRequest request, HttpServletResponse response,
108: ActionForm form) {
109:
110: if (form != null) {
111: form = formHandler.wrapForm(form, request);
112: }
113: if (form instanceof BindingForm) {
114: formHandler.handleBindingForm((BindingForm) form, request);
115: if (form instanceof ValidForm) {
116: formHandler.handleValidForm((ValidForm) form, request);
117: }
118: }
119: return form;
120: }
121:
122: @Override
123: protected ActionForm prePopulate(ActionForm form,
124: HttpServletRequest request) {
125: return formPopulateSource.prePopulate(form, request);
126: }
127:
128: @Override
129: protected void postValidate(HttpServletRequest request,
130: ActionMapping mapping, boolean validate) {
131: formValidationHandler.postValidate(request, mapping, validate);
132: }
133:
134: @Override
135: protected ActionForm preValidate(ActionForm form,
136: HttpServletRequest request) {
137: return formValidationHandler.preValidate(request, form);
138: }
139:
140: @SuppressWarnings("unchecked")
141: @Override
142: protected Action extendedProcessActionCreate(
143: HttpServletRequest request, HttpServletResponse response,
144: ActionMapping actionMapping) throws IOException {
145:
146: String className = actionMapping.getType();
147: Action action = null;
148:
149: boolean isNew = false;
150:
151: synchronized (actions) {
152:
153: action = (Action) actions.get(className);
154:
155: if (action == null) {
156:
157: try {
158:
159: // load the action class
160: Class clazz = Class.forName(className);
161:
162: // delegate action creation to ActionCreator
163: action = actionCreator.createAction(clazz);
164:
165: action.setServlet(this .servlet);
166: isNew = true;
167:
168: } catch (Exception e) {
169: log.error(getInternal().getMessage("actionCreate",
170: actionMapping.getPath()), e);
171:
172: // this is not ideal but is just a copy from the Struts superclass method
173: response
174: .sendError(
175: HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
176: getInternal().getMessage(
177: "actionCreate",
178: actionMapping.getPath()));
179:
180: return null;
181: }
182:
183: }
184:
185: if (isNew) {
186: actions.put(className, action);
187: }
188:
189: }
190:
191: return action;
192: }
193:
194: /**
195: * Handles request processing. If <code>Action</code> is instance of
196: * <code>ControllerAction</code> then control is passed on to the delegate. Otherwise,
197: * standard Struts action processing is carried out.<br>
198: * <br>
199: * Before execution, any configured <code>BeforeInterceptor</code>s are executed. Any
200: * exception thrown by these are handled by the Struts-configured exception handler. For
201: * example, if the second of three <code>BeforeInterceptor</code>s throws an exception, then
202: * the third will not be executed, and neither will the action's execute method or any
203: * <code>AfterInterceptors</code><br>
204: * <br>
205: * <code>AfterInterceptors</code>, by contrast will either all be executed or none executed.
206: * If an exception is thrown by any <code>AfterInterceptor</code>, it will be logged and
207: * ignored afterwards.
208: */
209: @Override
210: protected ActionForward extendedProcessActionPerform(
211: HttpServletRequest request, HttpServletResponse response,
212: Action action, ActionForm form, ActionMapping mapping)
213: throws IOException, ServletException {
214:
215: ActionContext actionContext = actionContextFactory
216: .createActionContext(request, response, servletContext,
217: form, mapping);
218:
219: ActionForward forward = null;
220:
221: try {
222:
223: if (action instanceof ControllerAction) {
224: // execute strecks specific processActionPerform
225: forward = delegate.handleActionPerform(
226: (ControllerAction) action, actionContext);
227: } else {
228: // execute regular Struts actions
229: forward = action.execute(mapping, form, request,
230: response);
231: }
232:
233: } catch (Exception e) {
234: request.setAttribute(Globals.EXCEPTION_KEY, e);
235: return (processException(request, response, e, form,
236: mapping));
237: }
238:
239: return forward;
240:
241: }
242:
243: /*
244: * ********************************************* package level setters and getters
245: * *************************************
246: */
247:
248: void setServletContext(ServletContext servletContext) {
249: this .servletContext = servletContext;
250: }
251:
252: void setActionCreator(ActionCreator actionCreator) {
253: this .actionCreator = actionCreator;
254: }
255:
256: void setDelegate(ControllerProcessorDelegate delegate) {
257: this .delegate = delegate;
258: }
259:
260: void setFormHandler(FormWrapper formHandler) {
261: this .formHandler = formHandler;
262: }
263:
264: void setFormValidationHandler(
265: FormValidationHandler formValidationHandler) {
266: this .formValidationHandler = formValidationHandler;
267: }
268:
269: void setFormPopulationSource(FormPopulateSource formPopulateSource) {
270: this .formPopulateSource = formPopulateSource;
271: }
272:
273: void setRequestPreprocessor(RequestPreprocessor requestPreprocessor) {
274: this .requestPreprocessor = requestPreprocessor;
275: }
276:
277: void setActionContextFactory(
278: ActionContextFactory actionContextFactory) {
279: this .actionContextFactory = actionContextFactory;
280: }
281:
282: ActionCreator getActionCreator() {
283: return actionCreator;
284: }
285:
286: ControllerProcessorDelegate getDelegate() {
287: return delegate;
288: }
289:
290: boolean hasAction(String className) {
291: return actions.get(className) != null;
292: }
293:
294: }
|