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