KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > struts > faces > application > FacesRequestProcessor


1 /*
2  * Copyright 2002,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.struts.faces.application;
18
19
20 import java.io.IOException JavaDoc;
21 import javax.faces.FactoryFinder;
22 import javax.faces.application.ViewHandler;
23 import javax.faces.component.UICommand;
24 import javax.faces.component.UIComponent;
25 import javax.faces.context.FacesContext;
26 import javax.faces.context.FacesContextFactory;
27 import javax.faces.event.ActionEvent;
28 import javax.faces.lifecycle.Lifecycle;
29 import javax.faces.lifecycle.LifecycleFactory;
30 import javax.servlet.ServletException JavaDoc;
31 import javax.servlet.http.HttpServletRequest JavaDoc;
32 import javax.servlet.http.HttpServletResponse JavaDoc;
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.apache.struts.Globals;
36 import org.apache.struts.action.Action;
37 import org.apache.struts.action.ActionForm;
38 import org.apache.struts.action.ActionForward;
39 import org.apache.struts.action.ActionMapping;
40 import org.apache.struts.action.RequestProcessor;
41 import org.apache.struts.config.FormBeanConfig;
42 import org.apache.struts.config.ForwardConfig;
43 import org.apache.struts.faces.Constants;
44 import org.apache.struts.faces.component.FormComponent;
45
46
47
48 /**
49  * <p>Concrete implementation of <code>RequestProcessor</code> that
50  * implements the standard Struts request processing lifecycle on a
51  * request that was received as an <code>ActionEvent</code> by our
52  * associated <code>ActionListener</code>. It replaces the request processor
53  * instance normally configured by Struts, so it must support non-Faces
54  * requests as well.</p>
55  *
56  * @version $Rev: 157452 $ $Date: 2005-03-14 19:46:14 +0000 (Mon, 14 Mar 2005) $
57  */

58
59 public class FacesRequestProcessor extends RequestProcessor {
60
61
62     // ------------------------------------------------------ Instance Variables
63

64
65     /**
66      * <p>The log instance for this class.</p>
67      */

68     protected static Log log = LogFactory.getLog(FacesRequestProcessor.class);
69
70
71
72     // ------------------------------------------------------- Protected Methods
73

74
75     /**
76      * <p>Set up a Faces Request if we are not already processing one. Next,
77      * create a new view if the specified <code>uri</code> is different from
78      * the current view identifier. Finally, cause the new view to be
79      * rendered, and call <code>FacesContext.responseComplete()</code> to
80      * indicate that this has already been done.</p>
81      *
82      * @param uri Context-relative path to forward to
83      * @param request Current page request
84      * @param response Current page response
85      *
86      * @exception IOException if an input/output error occurs
87      * @exception ServletException if a servlet error occurs
88      */

89     protected void doForward(String JavaDoc uri,
90                              HttpServletRequest JavaDoc request,
91                              HttpServletResponse JavaDoc response)
92         throws IOException JavaDoc, ServletException JavaDoc {
93
94         if (log.isDebugEnabled()) {
95             log.debug("doForward(" + uri + ")");
96         }
97
98         // Remove the current ActionEvent (if any)
99
request.removeAttribute(Constants.ACTION_EVENT_KEY);
100
101         // Process a Struts controller request normally
102
if (isStrutsRequest(uri)) {
103             if (response.isCommitted()) {
104                 if (log.isTraceEnabled()) {
105                     log.trace(" super.doInclude(" + uri + ")");
106                 }
107                 super.doInclude(uri, request, response);
108             } else {
109                 if (log.isTraceEnabled()) {
110                     log.trace(" super.doForward(" + uri + ")");
111                 }
112                 super.doForward(uri, request, response);
113             }
114             return;
115         }
116
117         // Create a FacesContext for this request if necessary
118
LifecycleFactory lf = (LifecycleFactory)
119             FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
120         Lifecycle lifecycle = // FIXME - alternative lifecycle ids
121
lf.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
122         boolean created = false;
123         FacesContext context = FacesContext.getCurrentInstance();
124         if (context == null) {
125             if (log.isTraceEnabled()) {
126                 log.trace(" Creating new FacesContext for '" + uri + "'");
127             }
128             created = true;
129             FacesContextFactory fcf = (FacesContextFactory)
130                 FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
131             context = fcf.getFacesContext(servlet.getServletContext(),
132                                           request, response, lifecycle);
133         }
134
135         // Create a new view root
136
ViewHandler vh = context.getApplication().getViewHandler();
137         if (log.isTraceEnabled()) {
138             log.trace(" Creating new view for '" + uri + "'");
139         }
140         context.setViewRoot(vh.createView(context, uri));
141
142         // Cause the view to be rendered
143
if (log.isTraceEnabled()) {
144             log.trace(" Rendering view for '" + uri + "'");
145         }
146         try {
147             lifecycle.render(context);
148         } finally {
149             if (created) {
150                 if (log.isTraceEnabled()) {
151                     log.trace(" Releasing context for '" + uri + "'");
152                 }
153                 context.release();
154             } else {
155                 if (log.isTraceEnabled()) {
156                     log.trace(" Rendering completed");
157                 }
158             }
159         }
160
161     }
162
163
164     // Override default processing to provide logging
165
protected Action processActionCreate(HttpServletRequest JavaDoc request,
166                                          HttpServletResponse JavaDoc response,
167                                          ActionMapping mapping)
168         throws IOException JavaDoc {
169
170         if (log.isTraceEnabled()) {
171             log.trace("Performing standard action create");
172         }
173         Action result = super.processActionCreate(request, response, mapping);
174         if (log.isDebugEnabled()) {
175             log.debug("Standard action create returned " +
176                       result.getClass().getName() + " instance");
177         }
178         return (result);
179
180     }
181
182
183     // Override default processing to provide logging
184
protected ActionForm processActionForm(HttpServletRequest JavaDoc request,
185                                            HttpServletResponse JavaDoc response,
186                                            ActionMapping mapping) {
187         if (log.isTraceEnabled()) {
188             log.trace("Performing standard action form processing");
189             String JavaDoc attribute = mapping.getAttribute();
190             if (attribute != null) {
191                 String JavaDoc name = mapping.getName();
192                 FormBeanConfig fbc = moduleConfig.findFormBeanConfig(name);
193                 if (fbc != null) {
194                     if ("request".equals(mapping.getScope())) {
195                         log.trace(" Bean in request scope = " +
196                                   request.getAttribute(attribute));
197                     } else {
198                         log.trace(" Bean in session scope = " +
199                                   request.getSession().getAttribute(attribute));
200                     }
201                 } else {
202                     log.trace(" No FormBeanConfig for '" + name + "'");
203                 }
204             } else {
205                 log.trace(" No form bean for this action");
206             }
207         }
208         ActionForm result =
209             super.processActionForm(request, response, mapping);
210         if (log.isDebugEnabled()) {
211             log.debug("Standard action form returned " +
212                       result);
213         }
214         return (result);
215         
216
217     }
218
219
220     // Override default processing to provide logging
221
protected ActionForward processActionPerform(HttpServletRequest JavaDoc request,
222                                                  HttpServletResponse JavaDoc response,
223                                                  Action action,
224                                                  ActionForm form,
225                                                  ActionMapping mapping)
226         throws IOException JavaDoc, ServletException JavaDoc {
227
228         if (log.isTraceEnabled()) {
229             log.trace("Performing standard action perform");
230         }
231         ActionForward result =
232             super.processActionPerform(request, response, action,
233                                        form, mapping);
234         if (log.isDebugEnabled()) {
235             log.debug("Standard action perform returned " +
236                       (result == null ? "NULL" :
237                       result.getPath()) + " forward path");
238         }
239         return (result);
240
241     }
242
243
244     // Override default processing to provide logging
245
protected boolean processForward(HttpServletRequest JavaDoc request,
246                                      HttpServletResponse JavaDoc response,
247                                      ActionMapping mapping)
248         throws IOException JavaDoc, ServletException JavaDoc {
249
250         if (log.isTraceEnabled()) {
251             log.trace("Performing standard forward handling");
252         }
253         boolean result = super.processForward
254             (request, response, mapping);
255         if (log.isDebugEnabled()) {
256             log.debug("Standard forward handling returned " + result);
257         }
258         return (result);
259
260     }
261
262
263     // Override default processing to provide logging
264
protected void processForwardConfig(HttpServletRequest JavaDoc request,
265                                         HttpServletResponse JavaDoc response,
266                                         ForwardConfig forward)
267         throws IOException JavaDoc, ServletException JavaDoc {
268
269         if (log.isTraceEnabled()) {
270             log.trace("Performing standard forward config handling");
271         }
272         super.processForwardConfig(request, response, forward);
273         if (log.isDebugEnabled()) {
274             log.debug("Standard forward config handling completed");
275         }
276
277     }
278
279
280     // Override default processing to provide logging
281
protected boolean processInclude(HttpServletRequest JavaDoc request,
282                                      HttpServletResponse JavaDoc response,
283                                      ActionMapping mapping)
284         throws IOException JavaDoc, ServletException JavaDoc {
285
286         if (log.isTraceEnabled()) {
287             log.trace("Performing standard include handling");
288         }
289         boolean result = super.processInclude
290             (request, response, mapping);
291         if (log.isDebugEnabled()) {
292             log.debug("Standard include handling returned " + result);
293         }
294         return (result);
295
296     }
297
298
299     /**
300      * <p>Identify and return the path component (from the request URI for a
301      * non-Faces request, or from the form event for a Faces request)
302      * that we will use to select an ActionMapping to dispatch with.
303      * If no such path can be identified, create an error response and return
304      * <code>null</code>.</p>
305      *
306      * @param request The servlet request we are processing
307      * @param response The servlet response we are creating
308      *
309      * @exception IOException if an input/output error occurs
310      */

311     protected String JavaDoc processPath(HttpServletRequest JavaDoc request,
312                                  HttpServletResponse JavaDoc response)
313         throws IOException JavaDoc {
314
315         // Are we processing a Faces request?
316
ActionEvent event = (ActionEvent)
317             request.getAttribute(Constants.ACTION_EVENT_KEY);
318
319         // Handle non-Faces requests in the usual way
320
if (event == null) {
321             if (log.isTraceEnabled()) {
322                 log.trace("Performing standard processPath() processing");
323             }
324             return (super.processPath(request, response));
325         }
326
327         // Calculate the path from the form name
328
UIComponent component = event.getComponent();
329         if (log.isTraceEnabled()) {
330             log.trace("Locating form parent for command component " +
331                       event.getComponent());
332         }
333         while (!(component instanceof FormComponent)) {
334             component = component.getParent();
335             if (component == null) {
336                 log.warn("Command component was not nested in a Struts form!");
337                 return (null);
338             }
339         }
340         if (log.isDebugEnabled()) {
341             log.debug("Returning selected path of '" +
342                       ((FormComponent) component).getAction() + "'");
343         }
344         return (((FormComponent) component).getAction());
345
346     }
347
348
349     /**
350      * <p>Populate the properties of the specified <code>ActionForm</code>
351      * instance from the request parameters included with this request,
352      * <strong>IF</strong> this is a non-Faces request. For a Faces request,
353      * this will have already been done by the <em>Update Model Values</em>
354      * phase of the request processing lifecycle, so all we have to do is
355      * recognize whether the request was cancelled or not.</p>
356      *
357      * @param request The servlet request we are processing
358      * @param response The servlet response we are creating
359      * @param form The ActionForm instance we are populating
360      * @param mapping The ActionMapping we are using
361      *
362      * @exception ServletException if thrown by RequestUtils.populate()
363      */

364     protected void processPopulate(HttpServletRequest JavaDoc request,
365                                    HttpServletResponse JavaDoc response,
366                                    ActionForm form,
367                                    ActionMapping mapping)
368         throws ServletException JavaDoc {
369
370         // Are we processing a Faces request?
371
ActionEvent event = (ActionEvent)
372             request.getAttribute(Constants.ACTION_EVENT_KEY);
373
374         // Handle non-Faces requests in the usual way
375
if (event == null) {
376             if (log.isTraceEnabled()) {
377                 log.trace("Performing standard processPopulate() processing");
378             }
379             super.processPopulate(request, response, form, mapping);
380             return;
381         }
382
383         // Faces Requests require no processing for form bean population
384
// so we need only check for the cancellation command name
385
if (log.isTraceEnabled()) {
386             log.trace("Faces request, so no processPopulate() processing");
387         }
388         UIComponent source = event.getComponent();
389         if (source instanceof UICommand) {
390             if ("cancel".equals(((UICommand) source).getId())) {
391                 if (log.isTraceEnabled()) {
392                     log.trace("Faces request with cancel button pressed");
393                 }
394                 request.setAttribute(Globals.CANCEL_KEY, Boolean.TRUE);
395             }
396         }
397
398     }
399
400
401     // Override default processing to provide logging
402
protected boolean processValidate(HttpServletRequest JavaDoc request,
403                                       HttpServletResponse JavaDoc response,
404                                       ActionForm form,
405                                       ActionMapping mapping)
406         throws IOException JavaDoc, ServletException JavaDoc {
407
408         if (log.isTraceEnabled()) {
409             log.trace("Performing standard validation");
410         }
411         boolean result = super.processValidate
412             (request, response, form, mapping);
413         if (log.isDebugEnabled()) {
414             log.debug("Standard validation processing returned " + result);
415         }
416         return (result);
417
418     }
419
420
421     // --------------------------------------------------------- Private Methods
422

423
424     /**
425      * <p>Return <code>true</code> if the specified context-relative URI
426      * specifies a request to be processed by the Struts controller servlet.</p>
427      *
428      * @param uri URI to be checked
429      */

430     private boolean isStrutsRequest(String JavaDoc uri) {
431
432         int question = uri.indexOf("?");
433         if (question >= 0) {
434             uri = uri.substring(0, question);
435         }
436         String JavaDoc mapping = (String JavaDoc)
437             servlet.getServletContext().getAttribute(Globals.SERVLET_KEY);
438         if (mapping == null) {
439             return (false);
440         } else if (mapping.startsWith("*.")) {
441             return (uri.endsWith(mapping.substring(1)));
442         } else if (mapping.endsWith("/*")) {
443             return (uri.startsWith(mapping.substring(0, mapping.length() - 2)));
444         } else {
445             return (false);
446         }
447
448     }
449
450
451 }
452
Popular Tags