KickJava   Java API By Example, From Geeks To Geeks.

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


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.config.FormBeanConfig;
41 import org.apache.struts.config.ForwardConfig;
42 import org.apache.struts.faces.Constants;
43 import org.apache.struts.faces.component.FormComponent;
44 import org.apache.struts.tiles.TilesRequestProcessor;
45
46
47 /**
48  * <p>Concrete implementation of <code>RequestProcessor</code> that
49  * implements the standard Struts request processing lifecycle on a
50  * request that was received as an <code>ActionEvent</code> by our
51  * associated <code>ActionListener</code>. It replaces the request processor
52  * instance normally configured by Struts+Tiles, so it must support non-Faces
53  * requests as well.</p>
54  *
55  * @version $Rev: 157452 $ $Date: 2005-03-14 19:46:14 +0000 (Mon, 14 Mar 2005) $
56  */

57
58 public class FacesTilesRequestProcessor extends TilesRequestProcessor {
59
60
61     // ------------------------------------------------------ Instance Variables
62

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

67     protected static Log log =
68         LogFactory.getLog(FacesTilesRequestProcessor.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 void internalModuleRelativeForward
166         (String JavaDoc uri, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
167         throws IOException JavaDoc, ServletException JavaDoc {
168
169         if (log.isTraceEnabled()) {
170             log.trace("Performing internal module relative forward to '" +
171                       uri + "'");
172         }
173         super.internalModuleRelativeForward(uri, request, response);
174
175     }
176
177
178     // Override default processing to provide logging
179
protected Action processActionCreate(HttpServletRequest JavaDoc request,
180                                          HttpServletResponse JavaDoc response,
181                                          ActionMapping mapping)
182         throws IOException JavaDoc {
183
184         if (log.isTraceEnabled()) {
185             log.trace("Performing standard action create");
186         }
187         Action result = super.processActionCreate(request, response, mapping);
188         if (log.isDebugEnabled()) {
189             log.debug("Standard action create returned " +
190                       result.getClass().getName() + " instance");
191         }
192         return (result);
193
194     }
195
196
197     // Override default processing to provide logging
198
protected ActionForm processActionForm(HttpServletRequest JavaDoc request,
199                                            HttpServletResponse JavaDoc response,
200                                            ActionMapping mapping) {
201         if (log.isTraceEnabled()) {
202             log.trace("Performing standard action form processing");
203             String JavaDoc attribute = mapping.getAttribute();
204             if (attribute != null) {
205                 String JavaDoc name = mapping.getName();
206                 FormBeanConfig fbc = moduleConfig.findFormBeanConfig(name);
207                 if (fbc != null) {
208                     if ("request".equals(mapping.getScope())) {
209                         log.trace(" Bean in request scope = " +
210                                   request.getAttribute(attribute));
211                     } else {
212                         log.trace(" Bean in session scope = " +
213                                   request.getSession().getAttribute(attribute));
214                     }
215                 } else {
216                     log.trace(" No FormBeanConfig for '" + name + "'");
217                 }
218             } else {
219                 log.trace(" No form bean for this action");
220             }
221         }
222         ActionForm result =
223             super.processActionForm(request, response, mapping);
224         if (log.isDebugEnabled()) {
225             log.debug("Standard action form returned " +
226                       result);
227         }
228         return (result);
229         
230
231     }
232
233
234     // Override default processing to provide logging
235
protected ActionForward processActionPerform(HttpServletRequest JavaDoc request,
236                                                  HttpServletResponse JavaDoc response,
237                                                  Action action,
238                                                  ActionForm form,
239                                                  ActionMapping mapping)
240         throws IOException JavaDoc, ServletException JavaDoc {
241
242         if (log.isTraceEnabled()) {
243             log.trace("Performing standard action perform");
244         }
245         ActionForward result =
246             super.processActionPerform(request, response, action,
247                                        form, mapping);
248         if (log.isDebugEnabled()) {
249             log.debug("Standard action perform returned " +
250                       (result == null ? "NULL" :
251                       result.getPath()) + " forward path");
252         }
253         return (result);
254
255     }
256
257
258     // Override default processing to provide logging
259
protected boolean processForward(HttpServletRequest JavaDoc request,
260                                      HttpServletResponse JavaDoc response,
261                                      ActionMapping mapping)
262         throws IOException JavaDoc, ServletException JavaDoc {
263
264         if (log.isTraceEnabled()) {
265             log.trace("Performing standard forward handling");
266         }
267         boolean result = super.processForward
268             (request, response, mapping);
269         if (log.isDebugEnabled()) {
270             log.debug("Standard forward handling returned " + result);
271         }
272         return (result);
273
274     }
275
276
277     // Override default processing to provide logging
278
protected void processForwardConfig(HttpServletRequest JavaDoc request,
279                                         HttpServletResponse JavaDoc response,
280                                         ForwardConfig forward)
281         throws IOException JavaDoc, ServletException JavaDoc {
282
283         if (log.isTraceEnabled()) {
284             log.trace("Performing standard forward config handling");
285         }
286         super.processForwardConfig(request, response, forward);
287         if (log.isDebugEnabled()) {
288             log.debug("Standard forward config handling completed");
289         }
290
291     }
292
293
294     // Override default processing to provide logging
295
protected boolean processInclude(HttpServletRequest JavaDoc request,
296                                      HttpServletResponse JavaDoc response,
297                                      ActionMapping mapping)
298         throws IOException JavaDoc, ServletException JavaDoc {
299
300         if (log.isTraceEnabled()) {
301             log.trace("Performing standard include handling");
302         }
303         boolean result = super.processInclude
304             (request, response, mapping);
305         if (log.isDebugEnabled()) {
306             log.debug("Standard include handling returned " + result);
307         }
308         return (result);
309
310     }
311
312
313     /**
314      * <p>Identify and return the path component (from the request URI for a
315      * non-Faces request, or from the form event for a Faces request)
316      * that we will use to select an ActionMapping to dispatch with.
317      * If no such path can be identified, create an error response and return
318      * <code>null</code>.</p>
319      *
320      * @param request The servlet request we are processing
321      * @param response The servlet response we are creating
322      *
323      * @exception IOException if an input/output error occurs
324      */

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

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

437
438     /**
439      * <p>Return <code>true</code> if the specified context-relative URI
440      * specifies a request to be processed by the Struts controller servlet.</p>
441      *
442      * @param uri URI to be checked
443      */

444     private boolean isStrutsRequest(String JavaDoc uri) {
445
446         int question = uri.indexOf("?");
447         if (question >= 0) {
448             uri = uri.substring(0, question);
449         }
450         String JavaDoc mapping = (String JavaDoc)
451             servlet.getServletContext().getAttribute(Globals.SERVLET_KEY);
452         if (mapping == null) {
453             return (false);
454         } else if (mapping.startsWith("*.")) {
455             return (uri.endsWith(mapping.substring(1)));
456         } else if (mapping.endsWith("/*")) {
457             return (uri.startsWith(mapping.substring(0, mapping.length() - 2)));
458         } else {
459             return (false);
460         }
461
462     }
463
464
465 }
466
Popular Tags