KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > myfaces > lifecycle > LifecycleImpl


1 /*
2  * Copyright 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 package org.apache.myfaces.lifecycle;
17
18 import org.apache.myfaces.util.DebugUtils;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22
23 import javax.faces.FacesException;
24 import javax.faces.application.Application;
25 import javax.faces.application.ViewHandler;
26 import javax.faces.component.UIComponent;
27 import javax.faces.component.UIInput;
28 import javax.faces.component.UIViewRoot;
29 import javax.faces.context.ExternalContext;
30 import javax.faces.context.FacesContext;
31 import javax.faces.el.ValueBinding;
32 import javax.faces.event.PhaseEvent;
33 import javax.faces.event.PhaseId;
34 import javax.faces.event.PhaseListener;
35 import javax.faces.lifecycle.Lifecycle;
36 import java.io.IOException JavaDoc;
37 import java.util.ArrayList JavaDoc;
38 import java.util.Arrays JavaDoc;
39 import java.util.Iterator JavaDoc;
40 import java.util.List JavaDoc;
41 import javax.portlet.PortletRequest;
42 import org.apache.myfaces.portlet.MyFacesGenericPortlet;
43 import org.apache.myfaces.portlet.PortletUtil;
44
45 /**
46  * Implements the lifecycle as described in Spec. 1.0 PFD Chapter 2
47  * @author Manfred Geiler (latest modification by $Author: matzew $)
48  * @version $Revision: 1.44 $ $Date: 2005/02/10 20:24:17 $
49  * $Log: LifecycleImpl.java,v $
50  * Revision 1.44 2005/02/10 20:24:17 matzew
51  * closed MYFACES-101 in Jira; Thanks to Stan Silvert (JBoss Group)
52  *
53  * Revision 1.43 2005/01/27 02:38:43 svieujot
54  * Remove portlet-api dependency while keeping portlet support.
55  *
56  * Revision 1.42 2005/01/26 17:03:11 matzew
57  * MYFACES-86. portlet support provided by Stan Silver (JBoss Group)
58  *
59  * Revision 1.41 2004/10/13 11:51:00 matze
60  * renamed packages to org.apache
61  *
62  * Revision 1.40 2004/08/25 13:54:02 manolito
63  * Log cvs keyword
64  *
65  */

66 public class LifecycleImpl
67         extends Lifecycle
68 {
69     private static final Log log = LogFactory.getLog(LifecycleImpl.class);
70
71     private List JavaDoc _phaseListenerList = new ArrayList JavaDoc();
72     private PhaseListener[] _phaseListenerArray = null;
73
74     public LifecycleImpl()
75     {
76         // hide from public access
77
}
78
79     public void execute(FacesContext facesContext)
80         throws FacesException
81     {
82         if (restoreView(facesContext))
83         {
84             return;
85         }
86
87         if (applyRequestValues(facesContext))
88         {
89             return;
90         }
91
92         if (processValidations(facesContext))
93         {
94             return;
95         }
96
97         if (updateModelValues(facesContext))
98         {
99             return;
100         }
101
102         if (invokeApplication(facesContext))
103         {
104             return;
105         }
106     }
107
108
109     // Phases
110

111     /**
112      * Restore View (JSF.2.2.1)
113      * @return true, if immediate rendering should occur
114      */

115     private boolean restoreView(FacesContext facesContext)
116         throws FacesException
117     {
118         if (log.isTraceEnabled()) log.trace("entering restoreView in " + LifecycleImpl.class.getName());
119
120         informPhaseListenersBefore(facesContext, PhaseId.RESTORE_VIEW);
121
122         // Derive view identifier
123
String JavaDoc viewId = deriveViewId(facesContext);
124
125         Application application = facesContext.getApplication();
126         ViewHandler viewHandler = application.getViewHandler();
127
128         boolean viewCreated = false;
129         UIViewRoot viewRoot = viewHandler.restoreView(facesContext, viewId);
130         if (viewRoot == null)
131         {
132             viewRoot = viewHandler.createView(facesContext, viewId);
133             facesContext.renderResponse();
134             viewCreated = true;
135         }
136
137         facesContext.setViewRoot(viewRoot);
138
139         if (log.isTraceEnabled())
140         {
141             //Note: DebugUtils Logger must also be in trace level
142
DebugUtils.traceView(viewCreated ? "Newly created view" : "Restored view");
143         }
144
145         if (facesContext.getExternalContext().getRequestParameterMap().isEmpty())
146         {
147             //no POST or query parameters --> set render response flag
148
facesContext.renderResponse();
149         }
150
151         recursivelyHandleComponentReferencesAndSetValid(facesContext, viewRoot);
152
153         informPhaseListenersAfter(facesContext, PhaseId.RESTORE_VIEW);
154
155         if (facesContext.getRenderResponse())
156         {
157             if (log.isDebugEnabled()) log.debug("exiting restoreView in " + LifecycleImpl.class.getName() + " (--> render response)");
158             return true;
159         }
160
161         if (log.isTraceEnabled()) log.trace("exiting restoreView in " + LifecycleImpl.class.getName());
162         return false;
163     }
164
165
166     /**
167      * Apply Request Values (JSF.2.2.2)
168      * @return true, if response is complete
169      */

170     private boolean applyRequestValues(FacesContext facesContext)
171         throws FacesException
172     {
173         if (log.isTraceEnabled()) log.trace("entering applyRequestValues in " + LifecycleImpl.class.getName());
174
175         informPhaseListenersBefore(facesContext, PhaseId.APPLY_REQUEST_VALUES);
176
177         facesContext.getViewRoot().processDecodes(facesContext);
178
179         informPhaseListenersAfter(facesContext, PhaseId.APPLY_REQUEST_VALUES);
180
181         if (facesContext.getResponseComplete())
182         {
183             if (log.isDebugEnabled()) log.debug("exiting applyRequestValues in " + LifecycleImpl.class.getName() + " (response complete)");
184             return true;
185         }
186
187         if (facesContext.getRenderResponse())
188         {
189             if (log.isDebugEnabled()) log.debug("exiting applyRequestValues in " + LifecycleImpl.class.getName() + " (--> render response)");
190             return true;
191         }
192
193         if (log.isTraceEnabled()) log.trace("exiting applyRequestValues in " + LifecycleImpl.class.getName());
194         return false;
195     }
196
197
198     /**
199      * Process Validations (JSF.2.2.3)
200      * @return true, if response is complete
201      */

202     private boolean processValidations(FacesContext facesContext) throws FacesException
203     {
204         if (log.isTraceEnabled()) log.trace("entering processValidations in " + LifecycleImpl.class.getName());
205
206         informPhaseListenersBefore(facesContext, PhaseId.PROCESS_VALIDATIONS);
207
208         facesContext.getViewRoot().processValidators(facesContext);
209
210         informPhaseListenersAfter(facesContext, PhaseId.PROCESS_VALIDATIONS);
211
212         if (facesContext.getResponseComplete())
213         {
214             if (log.isDebugEnabled()) log.debug("exiting processValidations in " + LifecycleImpl.class.getName() + " (response complete)");
215             return true;
216         }
217
218         if (facesContext.getRenderResponse())
219         {
220             if (log.isDebugEnabled()) log.debug("exiting processValidations in " + LifecycleImpl.class.getName() + " (--> render response)");
221             return true;
222         }
223
224         if (log.isTraceEnabled()) log.trace("exiting processValidations in " + LifecycleImpl.class.getName());
225         return false;
226     }
227
228
229     /**
230      * Update Model Values (JSF.2.2.4)
231      * @return true, if response is complete
232      */

233     private boolean updateModelValues(FacesContext facesContext) throws FacesException
234     {
235         if (log.isTraceEnabled()) log.trace("entering updateModelValues in " + LifecycleImpl.class.getName());
236
237         informPhaseListenersBefore(facesContext, PhaseId.UPDATE_MODEL_VALUES);
238
239         facesContext.getViewRoot().processUpdates(facesContext);
240
241         informPhaseListenersAfter(facesContext, PhaseId.UPDATE_MODEL_VALUES);
242
243         if (facesContext.getResponseComplete())
244         {
245             if (log.isDebugEnabled()) log.debug("exiting updateModelValues in " + LifecycleImpl.class.getName() + " (response complete)");
246             return true;
247         }
248
249         if (facesContext.getRenderResponse())
250         {
251             if (log.isDebugEnabled()) log.debug("exiting updateModelValues in " + LifecycleImpl.class.getName() + " (--> render response)");
252             return true;
253         }
254
255         if (log.isTraceEnabled()) log.trace("exiting updateModelValues in " + LifecycleImpl.class.getName());
256         return false;
257     }
258
259
260     /**
261      * Invoke Application (JSF.2.2.5)
262      * @return true, if response is complete
263      */

264     private boolean invokeApplication(FacesContext facesContext)
265         throws FacesException
266     {
267         if (log.isTraceEnabled()) log.trace("entering invokeApplication in " + LifecycleImpl.class.getName());
268
269         informPhaseListenersBefore(facesContext, PhaseId.INVOKE_APPLICATION);
270
271         facesContext.getViewRoot().processApplication(facesContext);
272
273         informPhaseListenersAfter(facesContext, PhaseId.INVOKE_APPLICATION);
274
275         if (facesContext.getResponseComplete())
276         {
277             if (log.isDebugEnabled()) log.debug("exiting invokeApplication in " + LifecycleImpl.class.getName() + " (response complete)");
278             return true;
279         }
280
281         if (log.isTraceEnabled()) log.trace("exiting invokeApplication in " + LifecycleImpl.class.getName());
282         return false;
283     }
284
285
286     public void render(FacesContext facesContext) throws FacesException
287     {
288         if (log.isTraceEnabled()) log.trace("entering renderResponse in " + LifecycleImpl.class.getName());
289
290         if (facesContext.getResponseComplete())
291         {
292             if (log.isDebugEnabled()) log.debug("exiting renderResponse in " + LifecycleImpl.class.getName() + " (response complete)");
293             return;
294         }
295         informPhaseListenersBefore(facesContext, PhaseId.RENDER_RESPONSE);
296         Application application = facesContext.getApplication();
297         ViewHandler viewHandler = application.getViewHandler();
298         try
299         {
300             viewHandler.renderView(facesContext, facesContext.getViewRoot());
301         }
302         catch (IOException JavaDoc e)
303         {
304             throw new FacesException(e.getMessage(), e);
305         }
306
307         informPhaseListenersAfter(facesContext, PhaseId.RENDER_RESPONSE);
308         if (log.isTraceEnabled())
309         {
310             //Note: DebugUtils Logger must also be in trace level
311
DebugUtils.traceView("View after rendering");
312         }
313
314         if (log.isTraceEnabled()) log.trace("exiting renderResponse in " + LifecycleImpl.class.getName());
315     }
316
317
318     private static String JavaDoc deriveViewId(FacesContext facesContext)
319     {
320         ExternalContext externalContext = facesContext.getExternalContext();
321         
322         if (PortletUtil.isPortletRequest(facesContext))
323         {
324             PortletRequest request = (PortletRequest)externalContext.getRequest();
325             return request.getParameter(MyFacesGenericPortlet.VIEW_ID);
326         }
327
328         String JavaDoc viewId = externalContext.getRequestPathInfo(); //getPathInfo
329
if (viewId == null)
330         {
331             //No extra path info found, so it is propably extension mapping
332
viewId = externalContext.getRequestServletPath(); //getServletPath
333
DebugUtils.assertError(viewId != null,
334                                    log, "RequestServletPath is null, cannot determine viewId of current page.");
335             //TODO: JSF Spec 2.2.1 - what do they mean by "if the default ViewHandler implementation is used..." ?
336
String JavaDoc defaultSuffix = externalContext.getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME);
337             String JavaDoc suffix = defaultSuffix != null ? defaultSuffix : ViewHandler.DEFAULT_SUFFIX;
338             DebugUtils.assertError(suffix.charAt(0) == '.',
339                                    log, "Default suffix must start with a dot!");
340
341             int dot = viewId.lastIndexOf('.');
342             if (dot == -1)
343             {
344                 log.error("Assumed extension mapping, but there is no extension in " + viewId);
345             }
346             else
347             {
348                 viewId = viewId.substring(0, dot) + suffix;
349             }
350         }
351
352         return viewId;
353     }
354
355
356     private static void recursivelyHandleComponentReferencesAndSetValid(FacesContext facesContext,
357                                                                         UIComponent root)
358     {
359         for (Iterator JavaDoc it = root.getFacetsAndChildren(); it.hasNext(); )
360         {
361             UIComponent component = (UIComponent)it.next();
362
363             ValueBinding binding = component.getValueBinding("binding"); //TODO: constant
364
if (binding != null && !binding.isReadOnly(facesContext))
365             {
366                 binding.setValue(facesContext, component);
367             }
368
369             if (component instanceof UIInput)
370             {
371                 ((UIInput)component).setValid(true);
372             }
373
374             recursivelyHandleComponentReferencesAndSetValid(facesContext, component);
375         }
376     }
377
378     public void addPhaseListener(PhaseListener phaseListener)
379     {
380         if (_phaseListenerList == null)
381         {
382             _phaseListenerList = new ArrayList JavaDoc();
383             if (_phaseListenerArray != null)
384             {
385                 _phaseListenerList.addAll(Arrays.asList(_phaseListenerArray));
386                 _phaseListenerArray = null;
387             }
388         }
389         _phaseListenerList.add(phaseListener);
390     }
391
392     public void removePhaseListener(PhaseListener phaseListener)
393     {
394         if (_phaseListenerList == null)
395         {
396             _phaseListenerList = new ArrayList JavaDoc();
397             if (_phaseListenerArray != null)
398             {
399                 _phaseListenerList.addAll(Arrays.asList(_phaseListenerArray));
400                 _phaseListenerArray = null;
401             }
402         }
403         _phaseListenerList.remove(phaseListener);
404     }
405
406     public PhaseListener[] getPhaseListeners()
407     {
408         if (_phaseListenerArray == null)
409         {
410             if (_phaseListenerList == null)
411             {
412                 _phaseListenerArray = new PhaseListener[0];
413             }
414             else
415             {
416                 _phaseListenerArray = (PhaseListener[])_phaseListenerList.toArray(new PhaseListener[_phaseListenerList.size()]);
417                 _phaseListenerList = null;
418             }
419         }
420         return _phaseListenerArray;
421     }
422
423
424     private void informPhaseListenersBefore(FacesContext facesContext, PhaseId phaseId)
425     {
426         PhaseListener[] phaseListeners = getPhaseListeners();
427         for (int i = 0; i < phaseListeners.length; i++)
428         {
429             PhaseListener phaseListener = phaseListeners[i];
430             int listenerPhaseId = phaseListener.getPhaseId().getOrdinal();
431             if (listenerPhaseId == PhaseId.ANY_PHASE.getOrdinal() ||
432                 listenerPhaseId == phaseId.getOrdinal())
433             {
434                 phaseListener.beforePhase(new PhaseEvent(facesContext, phaseId, this));
435             }
436         }
437
438     }
439
440     private void informPhaseListenersAfter(FacesContext facesContext, PhaseId phaseId)
441     {
442         PhaseListener[] phaseListeners = getPhaseListeners();
443         for (int i = 0; i < phaseListeners.length; i++)
444         {
445             PhaseListener phaseListener = phaseListeners[i];
446             int listenerPhaseId = phaseListener.getPhaseId().getOrdinal();
447             if (listenerPhaseId == PhaseId.ANY_PHASE.getOrdinal() ||
448                 listenerPhaseId == phaseId.getOrdinal())
449             {
450                 phaseListener.afterPhase(new PhaseEvent(facesContext, phaseId, this));
451             }
452         }
453
454     }
455
456 }
457
Popular Tags