You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ja...@apache.org on 2009/03/08 17:31:07 UTC

svn commit: r751462 - in /myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component: UIComponent.java UIComponentBase.java UIViewRoot.java

Author: jankeesvanandel
Date: Sun Mar  8 16:31:07 2009
New Revision: 751462

URL: http://svn.apache.org/viewvc?rev=751462&view=rev
Log:
MYFACES-2146: Fixed issue and cleaned up algorithm of the pop* and push* methods.

Modified:
    myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponent.java
    myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponentBase.java
    myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIViewRoot.java

Modified: myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponent.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponent.java?rev=751462&r1=751461&r2=751462&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponent.java (original)
+++ myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponent.java Sun Mar  8 16:31:07 2009
@@ -59,31 +59,32 @@
 
 /**
  * see Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a>
- * 
+ *
  * @author Manfred Geiler (latest modification by $Author$)
  * @version $Revision$ $Date$
  */
 @JSFComponent(type = "javax.faces.Component", family = "javax.faces.Component", desc = "abstract base component", configExcluded = true)
 public abstract class UIComponent implements StateHolder, SystemEventListenerHolder, ComponentSystemEventListener
 {
-    public static final String BEANINFO_KEY = "javax.faces.component.BEANINFO_KEY";
-    public static final String COMPOSITE_COMPONENT_TYPE_KEY = "javax.faces.component.COMPOSITE_COMPONENT_TYPE";
-    public static final String COMPOSITE_FACET_NAME = "javax.faces.component.COMPOSITE_FACET_NAME";
     public static final String CURRENT_COMPONENT = "javax.faces.component.CURRENT_COMPONENT";
     public static final String CURRENT_COMPOSITE_COMPONENT = "javax.faces.component.CURRENT_COMPOSITE_COMPONENT";
+    public static final String BEANINFO_KEY = "javax.faces.component.BEANINFO_KEY";
     public static final String FACETS_KEY = "javax.faces.component.FACETS_KEY";
+    public static final String COMPOSITE_COMPONENT_TYPE_KEY = "javax.faces.component.COMPOSITE_COMPONENT_TYPE";
+    public static final String COMPOSITE_FACET_NAME = "javax.faces.component.COMPOSITE_FACET_NAME";
+
     private static final String _COMPONENT_STACK = "componentStack:" + UIComponent.class.getName();
 
     private Map<Class<? extends SystemEvent>, List<SystemEventListener>> _systemEventListenerClassMap;
-    
+
     protected Map<String, ValueExpression> bindings;
-    
+
     /**
      * Used to cache the map created using getResourceBundleMap() method,
      * since this method could be called several times when rendering the
      * composite component. This attribute may not be serialized,
-     * so transient is used (There are some very few special cases when 
-     * UIComponent instances are serializable like t:schedule, so it 
+     * so transient is used (There are some very few special cases when
+     * UIComponent instances are serializable like t:schedule, so it
      * is better if transient is used).
      */
     private transient Map<String,String> _resourceBundleMap = null;
@@ -198,7 +199,7 @@
 
     /**
      * Invokes the <code>invokeContextCallback</code> method with the component, specified by <code>clientId</code>.
-     * 
+     *
      * @param context
      *            <code>FacesContext</code> for the current request
      * @param clientId
@@ -270,7 +271,7 @@
                 listeners = Collections.unmodifiableList(listeners);
             }
         }
-        
+
         return listeners;
     }
 
@@ -305,7 +306,7 @@
             FacesContext context = getFacesContext();
             Locale locale = context.getViewRoot().getLocale();
             ClassLoader loader = Thread.currentThread().getContextClassLoader();
-    
+
             try
             {
                 // looks for a ResourceBundle with a base name equal to the fully qualified class
@@ -322,16 +323,16 @@
                     Resource componentResource = (Resource) getAttributes().get(Resource.COMPONENT_RESOURCE_KEY);
                     // Let resourceName be the resourceName of the Resource for this composite component,
                     // replacing the file extension with ".properties"
-                    int extensionIndex = componentResource.getResourceName().lastIndexOf('.');                
+                    int extensionIndex = componentResource.getResourceName().lastIndexOf('.');
                     String resourceName =  (extensionIndex < 0 ? componentResource.getResourceName()
                             : componentResource.getResourceName().substring(0,extensionIndex) )+ ".properties" ;
-                    
-                    // Let libraryName be the libraryName of the the Resource for this composite component.                
+
+                    // Let libraryName be the libraryName of the the Resource for this composite component.
                     // Call ResourceHandler.createResource(java.lang.String,java.lang.String), passing the derived resourceName and
                     // libraryName.
-                    Resource bundleResource = context.getApplication().getResourceHandler().createResource(resourceName, 
+                    Resource bundleResource = context.getApplication().getResourceHandler().createResource(resourceName,
                             componentResource.getLibraryName());
-    
+
                     if (bundleResource != null)
                     {
                         // If the resultant Resource exists and can be found, the InputStream for the resource
@@ -339,7 +340,7 @@
                         // for this component is successful, the ResourceBundle is wrapped in a Map<String, String> and returned.
                         try
                         {
-                            _resourceBundleMap = new BundleMap(new PropertyResourceBundle(bundleResource.getInputStream())); 
+                            _resourceBundleMap = new BundleMap(new PropertyResourceBundle(bundleResource.getInputStream()));
                         }
                         catch (IOException e1)
                         {
@@ -373,7 +374,7 @@
     public abstract void broadcast(FacesEvent event) throws AbortProcessingException;
 
     public abstract void decode(FacesContext context);
-    
+
     public void doTreeTraversal(FacesContext context, ContextCallback nodeCallback)
     {
         try
@@ -435,16 +436,16 @@
     public abstract void processRestoreState(FacesContext context, Object state);
 
     public abstract void processDecodes(FacesContext context);
-    
+
     public void processEvent(ComponentSystemEvent event) throws AbortProcessingException
     {
-        // The default implementation performs the following action. If the argument event is an instance of 
-        // AfterRestoreStateEvent, 
+        // The default implementation performs the following action. If the argument event is an instance of
+        // AfterRestoreStateEvent,
         if (event instanceof AfterRestoreStateEvent)
         {
             // call this.getValueExpression(java.lang.String) passing the literal string “binding”
             ValueExpression expression = getValueExpression("binding");
-            
+
             // If the result is non-null, set the value of the ValueExpression to be this.
             if (expression != null)
             {
@@ -461,16 +462,16 @@
 
     public void subscribeToEvent(Class<? extends SystemEvent> eventClass, ComponentSystemEventListener componentListener)
     {
-        // The default implementation creates an inner SystemEventListener instance that wraps argument 
+        // The default implementation creates an inner SystemEventListener instance that wraps argument
         // componentListener as the listener argument.
         SystemEventListener listener = new EventListenerWrapper(this, componentListener);
-        
+
         // Make sure the map exists
         if (_systemEventListenerClassMap == null)
         {
             _systemEventListenerClassMap = new HashMap<Class<? extends SystemEvent>, List<SystemEventListener>>();
         }
-        
+
         List<SystemEventListener> listeners = _systemEventListenerClassMap.get(eventClass);
         // Make sure the list for class exists
         if (listeners == null)
@@ -478,7 +479,7 @@
             listeners = new ArrayList<SystemEventListener>(2);
             _systemEventListenerClassMap.put(eventClass, listeners);
         }
-        
+
         // Deal with contains? Spec is silent
         listeners.add(listener);
     }
@@ -487,15 +488,15 @@
                                      ComponentSystemEventListener componentListener)
     {
         /*
-         * When doing the comparison to determine if an existing listener is equal to the argument 
-         * componentListener (and thus must be removed), the equals() method on the existing listener must be 
+         * When doing the comparison to determine if an existing listener is equal to the argument
+         * componentListener (and thus must be removed), the equals() method on the existing listener must be
          * invoked, passing the argument componentListener, rather than the other way around.
-         * 
+         *
          * What is that supposed to mean? Are we supposed to keep an internal map of created listener wrappers?
          * TODO: Check with the EG what's the meaning of this, equals should be commutative -= Simon Lessard =-
          */
         SystemEventListener listener = new EventListenerWrapper(this, componentListener);
-        
+
         getFacesContext().getApplication().unsubscribeFromEvent(eventClass, listener);
     }
 
@@ -505,40 +506,27 @@
 
     @SuppressWarnings("unchecked")
     protected void popComponentFromEL(FacesContext context)
-    {        
-        Map<Object, Object> contextAttributes = context.getAttributes();        
-        
-        // Pop the current UIComponent from the FacesContext attributes map so that the previous 
+    {
+        Map<Object, Object> contextAttributes = context.getAttributes();
+
+        // Pop the current UIComponent from the FacesContext attributes map so that the previous
         // UIComponent, if any, becomes the current component.
         Deque<UIComponent> componentStack = (Deque<UIComponent>) contextAttributes.get(UIComponent._COMPONENT_STACK);
-        
-        UIComponent newCurrent = null;
-        if (componentStack != null && !componentStack.isEmpty())
-        {
-            newCurrent = componentStack.pop();
-        }
+
+        UIComponent newCurrent = componentStack.pop();
         UIComponent oldCurrent = (UIComponent)contextAttributes.put(UIComponent.CURRENT_COMPONENT, newCurrent);
-        
+
         if (oldCurrent != null && oldCurrent._isCompositeComponent())
         {
-            // Recalculate the current composite component
-            if (newCurrent != null)
-            {
-                if (newCurrent._isCompositeComponent())
-                {
-                    contextAttributes.put(UIComponent.CURRENT_COMPOSITE_COMPONENT, newCurrent);
-                }
-                else
-                {
-                    for (UIComponent component : componentStack)
-                    {
-                        if (component._isCompositeComponent())
-                        {
-                            contextAttributes.put(UIComponent.CURRENT_COMPOSITE_COMPONENT, component);
-                            break;
-                        }
-                    }
-                }
+            newCurrent = componentStack.peek();
+        }
+        contextAttributes.put(UIComponent.CURRENT_COMPONENT, newCurrent);
+
+        // Find and put (if exists) the current composite component into the EL.
+        for (UIComponent component : componentStack) {
+            if (component._isCompositeComponent()) {
+                contextAttributes.put(UIComponent.CURRENT_COMPOSITE_COMPONENT, component);
+                break;
             }
         }
     }
@@ -546,26 +534,16 @@
     @SuppressWarnings("unchecked")
     protected void pushComponentToEL(FacesContext context, UIComponent component)
     {
-        Map<Object, Object> contextAttributes = context.getAttributes();        
-        UIComponent currentComponent = (UIComponent) contextAttributes.get(UIComponent.CURRENT_COMPONENT);
-        
-        if(currentComponent != null)
-        {
-            Deque<UIComponent> componentStack = (Deque<UIComponent>) contextAttributes.get(UIComponent._COMPONENT_STACK);
-            if(componentStack == null)
-            {
-                componentStack = new ArrayDeque<UIComponent>();
-                contextAttributes.put(UIComponent._COMPONENT_STACK, componentStack);
-            }
-            
-            componentStack.push(currentComponent);
-        }
-        
-        // Push the current UIComponent this to the FacesContext  attribute map using the key CURRENT_COMPONENT 
-        // saving the previous UIComponent associated with CURRENT_COMPONENT for a subsequent call to 
-        // popComponentFromEL(javax.faces.context.FacesContext).
+        Map<Object, Object> contextAttributes = context.getAttributes();
+        Deque<UIComponent> componentStack = (Deque<UIComponent>) contextAttributes.get(_COMPONENT_STACK);
+        if (componentStack == null)
+        {
+            componentStack = new ArrayDeque<UIComponent>();
+            contextAttributes.put(_COMPONENT_STACK, componentStack);
+        }
+
+        componentStack.push(component);
         contextAttributes.put(UIComponent.CURRENT_COMPONENT, component);
- 
         if (component._isCompositeComponent())
         {
             contextAttributes.put(UIComponent.CURRENT_COMPOSITE_COMPONENT, component);
@@ -594,7 +572,7 @@
 
         return getClientId(ctx);
     }
-    
+
     private void _doTreeTraversalInternal(FacesContext context, ContextCallback nodeCallback)
     {
         // The default implementation must call the callback on this instance before traversing the children
@@ -607,7 +585,7 @@
             }
         }
     }
-    
+
     private boolean _isCompositeComponent()
     {
         return getAttributes().get(Resource.COMPONENT_RESOURCE_KEY) != null;
@@ -741,21 +719,21 @@
         }
 
     }
-    
+
     private class EventListenerWrapper implements SystemEventListener
     {
         private UIComponent component;
         private ComponentSystemEventListener listener;
-        
+
         public EventListenerWrapper(UIComponent component, ComponentSystemEventListener listener)
         {
             assert component != null;
             assert listener != null;
-            
+
             this.component = component;
             this.listener = listener;
         }
-        
+
         @Override
         public boolean equals(Object o)
         {
@@ -773,28 +751,28 @@
                 return false;
             }
         }
-        
+
         @Override
         public int hashCode()
         {
             return component.hashCode() + listener.hashCode();
         }
-        
+
         public boolean isListenerForSource(Object source)
         {
-            // and its implementation of SystemEventListener.isListenerForSource(java.lang.Object) must return true 
+            // and its implementation of SystemEventListener.isListenerForSource(java.lang.Object) must return true
             // if the instance class of this UIComponent is assignable from the argument to isListenerForSource.
-            
+
             return source.getClass().isAssignableFrom(component.getClass());
         }
 
         public void processEvent(SystemEvent event)
         {
-            // This inner class must call through to the argument componentListener in its implementation of 
+            // This inner class must call through to the argument componentListener in its implementation of
             // SystemEventListener.processEvent(javax.faces.event.SystemEvent)
-            
+
             assert event instanceof ComponentSystemEvent;
-            
+
             listener.processEvent((ComponentSystemEvent)event);
         }
     }

Modified: myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponentBase.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponentBase.java?rev=751462&r1=751461&r2=751462&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponentBase.java (original)
+++ myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponentBase.java Sun Mar  8 16:31:07 2009
@@ -53,10 +53,10 @@
  * <i>Disclaimer</i>: The official definition for the behaviour of this class is the JSF 1.1 specification but for legal
  * reasons the specification cannot be replicated here. Any javadoc here therefore describes the current implementation
  * rather than the spec, though this class has been verified as correctly implementing the spec.
- * 
+ *
  * see Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a> for
  * more.
- * 
+ *
  * @author Manfred Geiler (latest modification by $Author$)
  * @version $Revision$ $Date$
  */
@@ -128,7 +128,7 @@
         {
             _attributesMap = new _ComponentAttributesMap(this);
         }
-        
+
         return _attributesMap;
     }
 
@@ -138,7 +138,7 @@
      * Value-bindings are stored in a map associated with the component, though there is commonly a property
      * (setter/getter methods) of the same name defined on the component itself which evaluates the value-binding when
      * called.
-     * 
+     *
      * @deprecated Replaced by getValueExpression
      */
     @Deprecated
@@ -159,7 +159,7 @@
 
     /**
      * Put the provided value-binding into a map of value-bindings associated with this component.
-     * 
+     *
      * @deprecated Replaced by setValueExpression
      */
     @Deprecated
@@ -290,7 +290,7 @@
      * Null is allowed as a parameter, and will reset the id to null.
      * <p>
      * The clientId of this component is reset by this method; see getClientId for more info.
-     * 
+     *
      * @throws IllegalArgumentException
      *             if the id is not valid.
      */
@@ -383,7 +383,7 @@
      * <li>Otherwise, the search starts from the nearest ancestor NamingContainer (or the root component if there is no
      * NamingContainer ancestor).
      * </ul>
-     * 
+     *
      * @param expr
      *            is of form "id1:id2:id3".
      * @return UIComponent or null if no component with the specified id is found.
@@ -504,7 +504,7 @@
      * ValueChangeEvent events by the component's validate method. In either case the event's source property references
      * a component. At some later time the UIViewRoot component iterates over its queued events and invokes the
      * broadcast method on each event's source object.
-     * 
+     *
      * @param event
      *            must not be null.
      */
@@ -567,23 +567,23 @@
         {
             throw new NullPointerException("context");
         }
-        
+
         // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
         pushComponentToEL(context, this);
-        
+
         if (isRendered())
         {
-            // If our rendered property is true, render the beginning of the current state of this UIComponent to the 
+            // If our rendered property is true, render the beginning of the current state of this UIComponent to the
             // response contained in the specified FacesContext.
-            
-            // Call Application.publishEvent(java.lang.Class, java.lang.Object), passing BeforeRenderEvent.class as 
+
+            // Call Application.publishEvent(java.lang.Class, java.lang.Object), passing BeforeRenderEvent.class as
             // the first argument and the component instance to be rendered as the second argument.
             context.getApplication().publishEvent(BeforeRenderEvent.class, this);
-            
+
             Renderer renderer = getRenderer(context);
             if (renderer != null)
             {
-                // If a Renderer is associated with this UIComponent, the actual encoding will be delegated to 
+                // If a Renderer is associated with this UIComponent, the actual encoding will be delegated to
                 // Renderer.encodeBegin(FacesContext, UIComponent).
                 renderer.encodeBegin(context, this);
             }
@@ -597,15 +597,15 @@
         {
             throw new NullPointerException("context");
         }
-        
+
         if (isRendered())
         {
             // If our rendered property is true, render the child UIComponents of this UIComponent.
-            
+
             Renderer renderer = getRenderer(context);
             if (renderer == null)
             {
-                // If no Renderer is associated with this UIComponent, iterate over each of the children of this 
+                // If no Renderer is associated with this UIComponent, iterate over each of the children of this
                 // component and call UIComponent.encodeAll(javax.faces.context.FacesContext).
                 if (getChildCount() > 0)
                 {
@@ -617,7 +617,7 @@
             }
             else
             {
-                // If a Renderer is associated with this UIComponent, the actual encoding will be delegated to 
+                // If a Renderer is associated with this UIComponent, the actual encoding will be delegated to
                 // Renderer.encodeChildren(FacesContext, UIComponent).
                 renderer.encodeChildren(context, this);
             }
@@ -627,26 +627,30 @@
     @Override
     public void encodeEnd(FacesContext context) throws IOException
     {
-        if (context == null)
-        {
-            throw new NullPointerException("context");
-        }
-        
-        if (isRendered())
+        try
         {
-            // If our rendered property is true, render the ending of the current state of this UIComponent.
-            Renderer renderer = getRenderer(context);
-            if (renderer != null)
+            if (context == null)
             {
-                // If a Renderer is associated with this UIComponent, the actual encoding will be delegated to 
-                // Renderer.encodeEnd(FacesContext, UIComponent).
-                renderer.encodeEnd(context, this);
+                throw new NullPointerException("context");
             }
+            if (isRendered())
+            {
+                // If our rendered property is true, render the ending of the current state of this UIComponent.
+                Renderer renderer = getRenderer(context);
+                if (renderer != null)
+                {
+                    // If a Renderer is associated with this UIComponent, the actual encoding will be delegated to
+                    // Renderer.encodeEnd(FacesContext, UIComponent).
+                    renderer.encodeEnd(context, this);
+                }
+            }
+        }
+        finally
+        {
+            // Call UIComponent.popComponentFromEL(javax.faces.context.FacesContext). before returning regardless
+            // of the value of the rendered property.
+            popComponentFromEL(context);
         }
-        
-        // Call UIComponent.popComponentFromEL(javax.faces.context.FacesContext). before returning regardless 
-        // of the value of the rendered property.
-        popComponentFromEL(context);
     }
 
     @Override
@@ -730,16 +734,16 @@
         {
             // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
             pushComponentToEL(context, this);
-            
+
             try
             {
-                // Call the processDecodes() method of all facets and children of this UIComponent, in the order 
+                // Call the processDecodes() method of all facets and children of this UIComponent, in the order
                 // determined by a call to getFacetsAndChildren().
                 for (Iterator<UIComponent> it = getFacetsAndChildren(); it.hasNext();)
                 {
                     it.next().processDecodes(context);
                 }
-                
+
                 try
                 {
                     // Call the decode() method of this component.
@@ -747,7 +751,7 @@
                 }
                 catch (RuntimeException e)
                 {
-                    // If a RuntimeException is thrown during decode processing, call FacesContext.renderResponse() 
+                    // If a RuntimeException is thrown during decode processing, call FacesContext.renderResponse()
                     // and re-throw the exception.
                     context.renderResponse();
                     throw e;
@@ -755,9 +759,9 @@
             }
             finally
             {
-                // Call UIComponent.popComponentFromEL(javax.faces.context.FacesContext) from inside of a finally 
+                // Call UIComponent.popComponentFromEL(javax.faces.context.FacesContext) from inside of a finally
                 // block, just before returning.
-                
+
                 popComponentFromEL(context);
             }
         }
@@ -770,8 +774,8 @@
         {
             // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
             pushComponentToEL(context, this);
-            
-            // Call the processValidators() method of all facets and children of this UIComponent, in the order 
+
+            // Call the processValidators() method of all facets and children of this UIComponent, in the order
             // determined by a call to getFacetsAndChildren().
             for (Iterator<UIComponent> it = getFacetsAndChildren(); it.hasNext();)
             {
@@ -796,14 +800,19 @@
             // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
             pushComponentToEL(context, this);
 
-            // Call the processUpdates() method of all facets and children of this UIComponent, in the order 
-            // determined by a call to getFacetsAndChildren().
-            for (Iterator<UIComponent> it = getFacetsAndChildren(); it.hasNext();)
+            try
             {
-                it.next().processUpdates(context);
-                // After returning from the processUpdates() method on a child or facet, call 
+                // Call the processUpdates() method of all facets and children of this UIComponent, in the order
+                // determined by a call to getFacetsAndChildren().
+                for (Iterator<UIComponent> it = getFacetsAndChildren(); it.hasNext();)
+                {
+                    it.next().processUpdates(context);
+                }
+            }
+            finally
+            {
+                // After returning from the processUpdates() method on a child or facet, call
                 // UIComponent.popComponentFromEL(javax.faces.context.FacesContext)
-                
                 popComponentFromEL(context);
             }
         }
@@ -816,75 +825,81 @@
         {
             throw new NullPointerException("context");
         }
-            
+
         if (isTransient())
         {
             // consult the transient property of this component. If true, just return null.
             return null;
         }
-        
+
         // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
         pushComponentToEL(context, this);
-        
-        Map<String, Object> facetMap = null;
-        
-        int facetCount = getFacetCount();
-        if (facetCount > 0)
-        {
-            // Call the processSaveState() method of all facets and children of this UIComponent in the order 
-            // determined by a call to getFacetsAndChildren(), skipping children and facets that are transient. 
-            
-            // To improve speed and robustness, the facets and children processing is splited to maintain the
-            // facet --> state coherence based on the facet's name
-            for (Map.Entry<String, UIComponent> entry : getFacets().entrySet())
-            {
-                UIComponent component = entry.getValue();
-                if (!component.isTransient())
+
+        Map<String, Object> facetMap;
+
+        List<Object> childrenList;
+        try
+        {
+            facetMap = null;
+            int facetCount = getFacetCount();
+            if (facetCount > 0)
+            {
+                // Call the processSaveState() method of all facets and children of this UIComponent in the order
+                // determined by a call to getFacetsAndChildren(), skipping children and facets that are transient.
+
+                // To improve speed and robustness, the facets and children processing is splited to maintain the
+                // facet --> state coherence based on the facet's name
+                for (Map.Entry<String, UIComponent> entry : getFacets().entrySet())
                 {
-                    if (facetMap == null)
+                    UIComponent component = entry.getValue();
+                    if (!component.isTransient())
                     {
-                        facetMap = new HashMap<String, Object>(facetCount, 1);
+                        if (facetMap == null)
+                        {
+                            facetMap = new HashMap<String, Object>(facetCount, 1);
+                        }
+
+                        facetMap.put(entry.getKey(), component.processSaveState(context));
+
+                        // Ensure that UIComponent.popComponentFromEL(javax.faces.context.FacesContext) is called
+                        // correctly after each child or facet.
+                        //popComponentFromEL(context);
                     }
-                    
-                    facetMap.put(entry.getKey(), component.processSaveState(context));
-                    
-                    // Ensure that UIComponent.popComponentFromEL(javax.faces.context.FacesContext) is called 
-                    // correctly after each child or facet.
-                    popComponentFromEL(context);
                 }
             }
-        }
-        
-        List<Object> childrenList = null;
-        int childCount = getChildCount();
-        if (childCount > 0)
-        {
-            // Call the processSaveState() method of all facets and children of this UIComponent in the order 
-            // determined by a call to getFacetsAndChildren(), skipping children and facets that are transient. 
-            
-            // To improve speed and robustness, the facets and children processing is splited to maintain the
-            // facet --> state coherence based on the facet's name
-            for (UIComponent child : getChildren())
-            {
-                if (!child.isTransient())
-                {
-                    if (childrenList == null)
+            childrenList = null;
+            int childCount = getChildCount();
+            if (childCount > 0)
+            {
+                // Call the processSaveState() method of all facets and children of this UIComponent in the order
+                // determined by a call to getFacetsAndChildren(), skipping children and facets that are transient.
+
+                // To improve speed and robustness, the facets and children processing is splited to maintain the
+                // facet --> state coherence based on the facet's name
+                for (UIComponent child : getChildren()) {
+                    if (!child.isTransient())
                     {
-                        childrenList = new ArrayList<Object>(childCount);
-                    }
-                    
-                    Object childState = child.processSaveState(context);
-                    if (childState != null)
-                    { // FIXME: Isn't that check dangerous for restoration since the child isn't marked transient?
-                        childrenList.add(childState);
+                        if (childrenList == null)
+                        {
+                            childrenList = new ArrayList<Object>(childCount);
+                        }
+
+                        Object childState = child.processSaveState(context);
+                        if (childState != null)
+                        { // FIXME: Isn't that check dangerous for restoration since the child isn't marked transient?
+                            childrenList.add(childState);
+                        }
+
+                        // Ensure that UIComponent.popComponentFromEL(javax.faces.context.FacesContext) is called
+                        // correctly after each child or facet.
                     }
-                    
-                    // Ensure that UIComponent.popComponentFromEL(javax.faces.context.FacesContext) is called 
-                    // correctly after each child or facet.
                 }
             }
         }
-
+        finally
+        {
+            popComponentFromEL(context);
+        }
         // Call the saveState() method of this component.
         Object savedState = saveState(context);
 
@@ -900,69 +915,79 @@
         {
             throw new NullPointerException("context");
         }
-        
+
         Object[] stateValues = (Object[])state;
-        
+
         // Call the restoreState() method of this component.
         restoreState(context, stateValues[0]);
-        
+
         // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
         pushComponentToEL(context, this);
-        
-        Map<String, Object> facetMap = (Map<String, Object>)stateValues[1];
-        if (facetMap != null && getFacetCount() > 0)
-        {
-            // Call the processRestoreState() method of all facets and children of this UIComponent in the order 
-            // determined by a call to getFacetsAndChildren().
-            
-            // To improve speed and robustness, the facets and children processing is splited to maintain the
-            // facet --> state coherence based on the facet's name
-            for (Map.Entry<String, UIComponent> entry : getFacets().entrySet())
-            {
-                Object facetState = facetMap.get(entry.getKey());
-                if (facetState != null)
-                {
-                    entry.getValue().processRestoreState(context, facetState);
-                    
-                    // After returning from the processRestoreState() method on a child or facet, call 
-                    // UIComponent.popComponentFromEL(javax.faces.context.FacesContext)
-                    popComponentFromEL(context);
-                }
-                else
-                {
-                    context.getExternalContext().log("No state found to restore facet " + entry.getKey());
-                }
-            }
-        }
 
-        List<Object> childrenList = (List<Object>)stateValues[2];
-        if (childrenList != null && getChildCount() > 0)
+        try
         {
-            // Call the processRestoreState() method of all facets and children of this UIComponent in the order 
-            // determined by a call to getFacetsAndChildren().
-            
-            // To improve speed and robustness, the facets and children processing is splited to maintain the
-            // facet --> state coherence based on the facet's name
-            int idx = 0;
-            for (UIComponent child : getChildren())
+            Map<String, Object> facetMap = (Map<String, Object>) stateValues[1];
+            if (facetMap != null && getFacetCount() > 0)
             {
-                if (!child.isTransient())
+                // Call the processRestoreState() method of all facets and children of this UIComponent in the order
+                // determined by a call to getFacetsAndChildren().
+
+                // To improve speed and robustness, the facets and children processing is splited to maintain the
+                // facet --> state coherence based on the facet's name
+                for (Map.Entry<String, UIComponent> entry : getFacets().entrySet())
                 {
-                    Object childState = childrenList.get(idx++);
-                    if (childState != null)
+                    Object facetState = facetMap.get(entry.getKey());
+                    if (facetState != null)
                     {
-                        child.processRestoreState(context, childState);
-                        
-                        // After returning from the processRestoreState() method on a child or facet, call 
+                        entry.getValue().processRestoreState(context, facetState);
+
+                        // After returning from the processRestoreState() method on a child or facet, call
                         // UIComponent.popComponentFromEL(javax.faces.context.FacesContext)
-                        popComponentFromEL(context);
+                        //popComponentFromEL(context);
                     }
                     else
                     {
-                        context.getExternalContext().log("No state found to restore child of component " + getId());
+                        context.getExternalContext().log(
+                                "No state found to restore facet "
+                                        + entry.getKey());
                     }
                 }
             }
+            List<Object> childrenList = (List<Object>) stateValues[2];
+            if (childrenList != null && getChildCount() > 0)
+            {
+                // Call the processRestoreState() method of all facets and children of this UIComponent in the order
+                // determined by a call to getFacetsAndChildren().
+
+                // To improve speed and robustness, the facets and children processing is splited to maintain the
+                // facet --> state coherence based on the facet's name
+                int idx = 0;
+                for (UIComponent child : getChildren())
+                {
+                    if (!child.isTransient())
+                    {
+                        Object childState = childrenList.get(idx++);
+                        if (childState != null)
+                        {
+                            child.processRestoreState(context, childState);
+
+                            // After returning from the processRestoreState() method on a child or facet, call
+                            // UIComponent.popComponentFromEL(javax.faces.context.FacesContext)
+                            //popComponentFromEL(context);
+                        }
+                        else
+                        {
+                            context.getExternalContext().log(
+                                    "No state found to restore child of component "
+                                            + getId());
+                        }
+                    }
+                }
+            }
+        }
+        finally
+        {
+            popComponentFromEL(context);
         }
     }
 
@@ -1140,7 +1165,7 @@
             {
                 _AttachedStateWrapper wrapper = (_AttachedStateWrapper)stateObj;
                 Object wrappedState = wrapper.getWrappedStateObject();
-                
+
                 StateHolder holder = (StateHolder)restoredObject;
                 holder.restoreState(context, wrappedState);
             }
@@ -1174,7 +1199,7 @@
      * Invoked in the "restore view" phase, this initialises this object's members from the values saved previously into
      * the provided state object.
      * <p>
-     * 
+     *
      * @param state
      *            is an object previously returned by the saveState method of this class.
      */
@@ -1287,14 +1312,14 @@
             }
         }
     }
-    
+
     private boolean _isPhaseExecutable(FacesContext context)
     {
         if (context == null)
         {
             throw new NullPointerException("context");
         }
-        
+
         // If the rendered property of this UIComponent is false, skip further processing.
         return isRendered();
     }

Modified: myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIViewRoot.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIViewRoot.java?rev=751462&r1=751461&r2=751462&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIViewRoot.java (original)
+++ myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIViewRoot.java Sun Mar  8 16:31:07 2009
@@ -76,31 +76,31 @@
     private static final int ANY_PHASE_ORDINAL = PhaseId.ANY_PHASE.getOrdinal();
 
     private final Logger logger = Logger.getLogger(UIViewRoot.class.getName());
-    
+
     private static final PhaseProcessor APPLY_REQUEST_VALUES_PROCESSOR = new ApplyRequestValuesPhaseProcessor();
     private static final PhaseProcessor PROCESS_VALIDATORS_PROCESSOR = new ProcessValidatorPhaseProcessor();
     private static final PhaseProcessor UPDATE_MODEL_PROCESSOR = new UpdateModelPhaseProcessor();
-    
+
     private static final ContextCallback AJAX_ENCODE_ALL_CALLBACK = new AjaxEncodeAllCallback();
     private static final ContextCallback APPLY_REQUEST_VALUES_CALLBACK = new ApplyRequestValuesPhaseCallback();
     private static final ContextCallback PROCESS_VALIDATORS_CALLBACK = new ProcessValidatorPhaseCallback();
     private static final ContextCallback UPDATE_MODEL_CALLBACK = new UpdateModelPhaseCallback();
-    
-    
+
+
     private static final String AJAX_RESPONSE_COMPONENTS = "components";
     private static final String AJAX_RESPONSE_ROOT = "partial-response";
-    
+
     private static final String AJAX_RESPONSE_MARKUP = "markup";
     private static final String AJAX_RESPONSE_RENDER = "render";
     private static final String AJAX_RESPONSE_STATE = "state";
     private static final String AJAX_RESPONSE_CHARACTER_DATA_END = "]]>";
     private static final String AJAX_RESPONSE_CHARACTER_DATA_START = "<![CDATA[";
-    
+
     private static final String XML_CONTENT_TYPE = "text/xml";
-    
+
     // TODO: Add the encoding as well? If so a constant might not be perfect
     private static final String XML_DOCUMENT_HEADER = "<?xml version=\"1.0\" ?>";
-    
+
     /**
      * The counter which will ensure a unique component id for every component instance in the tree that doesn't have an
      * id attribute set.
@@ -176,7 +176,7 @@
 
         _phaseListeners.add(phaseListener);
     }
-    
+
     /**
      * @since 2.0
      */
@@ -186,7 +186,7 @@
         {
             return;
         }
-        
+
         // Gather the events and purge the event list to prevent concurrent modification during broadcasting
         List<FacesEvent> anyPhase = new ArrayList<FacesEvent>(_events.size());
         List<FacesEvent> onPhase = new ArrayList<FacesEvent>(_events.size());
@@ -204,7 +204,7 @@
                 iterator.remove();
             }
         }
-        
+
         // First broadcast events that have been queued for PhaseId.ANY_PHASE.
         if (_broadcastAll(context, anyPhase))
         {
@@ -252,8 +252,12 @@
                 super.encodeBegin(context);
             }
         }
+        else
+        {
+            pushComponentToEL(context, this);
+        }
     }
-    
+
     /**
      * @since 2.0
      */
@@ -261,17 +265,17 @@
     public void encodeChildren(FacesContext context) throws IOException
     {
         PartialViewContext pContext = context.getPartialViewContext();
-        
-        // If FacesContext.isAjaxRequest() returns true and FacesContext.isRenderAll() returns false. 
+
+        // If FacesContext.isAjaxRequest() returns true and FacesContext.isRenderAll() returns false.
         if (pContext.isAjaxRequest() && !pContext.isRenderAll())
         {
-            // Call FacesContext.getRenderPhaseClientIds(). This returns a list of client ids that must be processed during 
+            // Call FacesContext.getRenderPhaseClientIds(). This returns a list of client ids that must be processed during
             // the render portion of the request processing lifecycle.
             List<String> clientIds = pContext.getRenderPhaseClientIds();
             if (clientIds.isEmpty())
             {
-                /* 
-                 * If partial rendering was not performed, delegate to the parent 
+                /*
+                 * If partial rendering was not performed, delegate to the parent
                  * UIComponentBase.encodeChildren(javax.faces.context.FacesContext) method.
                  */
                 super.encodeChildren(context);
@@ -280,10 +284,10 @@
             {
                 try
                 {
-                    // For each client id in the list, 
+                    // For each client id in the list,
                     for (String clientId : clientIds)
                     {
-                        // using invokeOnComponent, all the encodeAll method on the component with that client id. 
+                        // using invokeOnComponent, all the encodeAll method on the component with that client id.
                         invokeOnComponent(context, clientId, AJAX_ENCODE_ALL_CALLBACK);
                     }
                 }
@@ -303,8 +307,8 @@
         }
         else
         {
-            /* 
-             * If FacesContext.isAjaxRequest() returns false, or FacesContext.isRenderAll(), delegate to the parent 
+            /*
+             * If FacesContext.isAjaxRequest() returns false, or FacesContext.isRenderAll(), delegate to the parent
              * UIComponentBase.encodeChildren(javax.faces.context.FacesContext) method.
              */
             super.encodeChildren(context);
@@ -323,11 +327,11 @@
         }
         else
         {
-            // If FacesContext.isAjaxRequest() returns flase, invoke the default 
+            // If FacesContext.isAjaxRequest() returns flase, invoke the default
             // UIComponentBase.encodeEnd(javax.faces.context.FacesContext) behavior.
             super.encodeEnd(context);
         }
-        
+
         try
         {
             notifyListeners(context, PhaseId.RENDER_RESPONSE, getAfterPhaseListener(), false);
@@ -342,7 +346,7 @@
     /**
      * MethodBinding pointing to a method that takes a javax.faces.event.PhaseEvent and returns void, called after every
      * phase except for restore view.
-     * 
+     *
      * @return the new afterPhaseListener value
      */
     @JSFProperty(stateHolder = true, returnSignature = "void", methodSignature = "javax.faces.event.PhaseEvent", jspName = "afterPhase")
@@ -363,7 +367,7 @@
     /**
      * MethodBinding pointing to a method that takes a javax.faces.event.PhaseEvent and returns void, called before
      * every phase except for restore view.
-     * 
+     *
      * @return the new beforePhaseListener value
      */
     @JSFProperty(stateHolder = true, returnSignature = "void", methodSignature = "javax.faces.event.PhaseEvent", jspName = "beforePhase")
@@ -409,7 +413,7 @@
     public List<UIComponent> getComponentResources(FacesContext context, String target, boolean create)
     {
         // No doc so assuming the algorithm from the previous 2 argument method
-        
+
         // Locate the facet for the component by calling getFacet() using target as the argument
         UIComponent facet = getFacet(target);
 
@@ -418,11 +422,11 @@
         {
             if (!create)
             {
-                // Should it retun null or an empty list? who knows? null seems better for now since an empty 
+                // Should it retun null or an empty list? who knows? null seems better for now since an empty
                 // list could be used in an attempt to add en element, null is more explicit of the meaning.
                 return null;
             }
-            
+
             facet = context.getApplication().createComponent("javax.faces.Panel");
             facet.setId(target);
 
@@ -492,7 +496,7 @@
 
         return listeners;
     }
-    
+
     /**
      * Defines what renderkit should be used to render this view.
      */
@@ -503,13 +507,13 @@
         {
             return _renderKitId;
         }
-        
+
         ValueExpression expression = getValueExpression("renderKitId");
         if (expression != null)
         {
             return (String)expression.getValue(getFacesContext().getELContext());
         }
-        
+
         return null;
     }
 
@@ -519,7 +523,7 @@
     @Override
     public boolean getRendersChildren()
     {
-        // If FacesContext.isAjaxRequest() returns true and it is a partial render request 
+        // If FacesContext.isAjaxRequest() returns true and it is a partial render request
         // (FacesContext.isRenderAll() returns false), return true.
         PartialViewContext context = FacesContext.getCurrentInstance().getPartialViewContext();
 
@@ -564,21 +568,21 @@
         checkNull(context, "context");
         _process(context, PhaseId.INVOKE_APPLICATION, null);
     }
-    
+
     @Override
     public void processDecodes(FacesContext context)
     {
         checkNull(context, "context");
         _process(context, PhaseId.APPLY_REQUEST_VALUES, APPLY_REQUEST_VALUES_PROCESSOR);
     }
-    
+
     /**
      * @since 2.0
      */
     @Override
     public void processRestoreState(FacesContext context, Object state)
     {
-        // The default implementation must call UIComponentBase.processRestoreState(javax.faces.context.FacesContext, 
+        // The default implementation must call UIComponentBase.processRestoreState(javax.faces.context.FacesContext,
         // java.lang.Object) from within a try block.
         try
         {
@@ -588,14 +592,14 @@
         {
             // The try block must have a finally block that ensures that no FacesEvents remain in the event queue
             broadcastEvents(context, PhaseId.RESTORE_VIEW);
-            
+
             // that any PhaseListeners in getPhaseListeners() are invoked as appropriate
             PhaseEvent event = createEvent(context, PhaseId.RESTORE_VIEW);
             for (PhaseListener listener: getPhaseListeners())
             {
                 listener.afterPhase(event);
             }
-            
+
             // and that the this.UIComponent.doTreeTraversal is called
             doTreeTraversal(context, new RestoreStateCallback());
         }
@@ -609,7 +613,7 @@
         {
             _events = new ArrayList<FacesEvent>();
         }
-        
+
         _events.add(event);
     }
 
@@ -649,27 +653,27 @@
     {
         /*
          * Initialize a state flag to false.
-         * 
-         * If getBeforePhaseListener() returns non-null, invoke the listener, passing in the correct corresponding 
+         *
+         * If getBeforePhaseListener() returns non-null, invoke the listener, passing in the correct corresponding
          * PhaseId for this phase.
-         * 
-         * Upon return from the listener, call FacesContext.getResponseComplete() and FacesContext.getRenderResponse(). 
+         *
+         * Upon return from the listener, call FacesContext.getResponseComplete() and FacesContext.getRenderResponse().
          * If either return true set the internal state flag to true.
-         * 
-         * If or one or more listeners have been added by a call to addPhaseListener(javax.faces.event.PhaseListener), 
-         * invoke the beforePhase method on each one whose PhaseListener.getPhaseId() matches the current phaseId, 
+         *
+         * If or one or more listeners have been added by a call to addPhaseListener(javax.faces.event.PhaseListener),
+         * invoke the beforePhase method on each one whose PhaseListener.getPhaseId() matches the current phaseId,
          * passing in the same PhaseId as in the previous step.
-         * 
+         *
          * Upon return from each listener, call FacesContext.getResponseComplete() and FacesContext.getRenderResponse().
          * If either return true set the internal state flag to true.
-         * 
+         *
          * Execute any processing for this phase if the internal state flag was not set.
-         * 
-         * If getAfterPhaseListener() returns non-null, invoke the listener, passing in the correct corresponding 
+         *
+         * If getAfterPhaseListener() returns non-null, invoke the listener, passing in the correct corresponding
          * PhaseId for this phase.
-         * 
-         * If or one or more listeners have been added by a call to addPhaseListener(javax.faces.event.PhaseListener), 
-         * invoke the afterPhase method on each one whose PhaseListener.getPhaseId() matches the current phaseId, 
+         *
+         * If or one or more listeners have been added by a call to addPhaseListener(javax.faces.event.PhaseListener),
+         * invoke the afterPhase method on each one whose PhaseListener.getPhaseId() matches the current phaseId,
          * passing in the same PhaseId as in the previous step.
          */
 
@@ -719,27 +723,27 @@
         }
         return new PhaseEvent(context, phaseId, _lifecycle);
     }
-    
+
     /**
-     * Broadcast all events in the specified collection, stopping the at any time an AbortProcessingException 
+     * Broadcast all events in the specified collection, stopping the at any time an AbortProcessingException
      * is thrown.
-     * 
+     *
      * @param context the current JSF context
      * @param events the events to broadcast
-     * 
+     *
      * @return <code>true</code> if the broadcast was completed without abortion, <code>false</code> otherwise
      */
     private boolean _broadcastAll(FacesContext context, Collection<? extends FacesEvent> events)
     {
         assert events != null;
-        
+
         for (FacesEvent event : events)
         {
             UIComponent source = event.getComponent();
-            
+
             // Push the source as the current component
             pushComponentToEL(context, source);
-            
+
             try
             {
                 // Actual event broadcasting
@@ -756,7 +760,7 @@
                 popComponentFromEL(context);
             }
         }
-        
+
         return true;
     }
 
@@ -884,7 +888,7 @@
      * This property should be disabled (ie throw an exception if invoked). However there are currently several places
      * that call this method (eg during restoreState) so it just does the normal thing for the moment. TODO: fix callers
      * then make this throw an exception.
-     * 
+     *
      * @JSFProperty tagExcluded="true"
      */
     @Override
@@ -946,7 +950,7 @@
 
     /**
      * Sets
-     * 
+     *
      * @param beforePhaseListener
      *            the new beforePhaseListener value
      */
@@ -957,7 +961,7 @@
 
     /**
      * Sets
-     * 
+     *
      * @param afterPhaseListener
      *            the new afterPhaseListener value
      */
@@ -996,36 +1000,36 @@
         _beforePhaseListener = (MethodExpression)restoreAttachedState(facesContext, values[6]);
         _afterPhaseListener = (MethodExpression)restoreAttachedState(facesContext, values[7]);
     }
-    
+
     private void _encodeBeginAjax(FacesContext context) throws IOException
     {
         PartialViewContext pContext = context.getPartialViewContext();
-        
+
         // replace the ResponseWriter in the FacesContext with the writer used to render partial responses.
         ResponseWriter writer = pContext.getPartialResponseWriter();
-        
+
         context.setResponseWriter(writer);
-        
+
         if (!pContext.isRenderNone())
         {
-            // If FacesContext.isRenderNone() returns false, set the response content-type and headers 
+            // If FacesContext.isRenderNone() returns false, set the response content-type and headers
             // appropriately for XML.
             context.getExternalContext().setResponseContentType(XML_CONTENT_TYPE);
-            
+
             writer.write(XML_DOCUMENT_HEADER);
-            
+
             // The  method must write the beginning elements for the partial response:
             // <partial-response>
             //   <components>
             writer.startElement(AJAX_RESPONSE_ROOT, null);
             writer.startElement(AJAX_RESPONSE_COMPONENTS, null);
-            
+
             // If FacesContext.isRenderAll() returns true write:
             if (pContext.isRenderAll())
             {
                 // <render id="javax.faces.ViewRoot"/>
                 //   <markup><![CDATA[
-                // to indicate the client JavaScript must use the entire response.  
+                // to indicate the client JavaScript must use the entire response.
                 writer.startElement(AJAX_RESPONSE_RENDER, this);
                 writer.writeAttribute("id", getFamily(), "clientId");
                 writer.startElement(AJAX_RESPONSE_MARKUP, this);
@@ -1033,26 +1037,26 @@
             }
         }
     }
-    
+
     private void _encodeEndAjax(FacesContext context) throws IOException
     {
         ResponseWriter writer = context.getResponseWriter();
-        
+
         PartialViewContext pContext = context.getPartialViewContext();
-        
+
         if (pContext.isRenderAll())
         {
             // If FacesContext.isRenderAll() returns true write:
-            
+
             // ]]>
             writer.write(AJAX_RESPONSE_CHARACTER_DATA_END);
-            
+
             // </markup>
             writer.endElement(AJAX_RESPONSE_MARKUP);
-            
+
             // </render>
             writer.endElement(AJAX_RESPONSE_RENDER);
-            
+
             if (!pContext.isRenderNone())
             {
                 // component markup was rendered (FacesContext.isRenderNone() returns false), write:
@@ -1060,53 +1064,53 @@
                 writer.endElement(AJAX_RESPONSE_COMPONENTS);
             }
         }
-        
+
         // <state>
         writer.startElement(AJAX_RESPONSE_STATE, null);
-        
+
         // <![CDATA[
         writer.write(AJAX_RESPONSE_CHARACTER_DATA_START);
-        
+
         // state information for this view
         writer.write(context.getApplication().getStateManager().getViewState(context));
-        
+
         // ]]>
         writer.write(AJAX_RESPONSE_CHARACTER_DATA_END);
-        
+
         // </state>
         writer.endElement(AJAX_RESPONSE_STATE);
-        
+
         // Write the ending partial-response element:
         // </partial-response>
         writer.endElement(AJAX_RESPONSE_ROOT);
     }
-    
+
     private List<String> _getAjaxClientIds(FacesContext context)
     {
         PartialViewContext pContext = context.getPartialViewContext();
-        
+
         // Call FacesContext.getExecutePhaseClientIds()
         List<String> clientIds = pContext.getExecutePhaseClientIds();
         if (clientIds == null || clientIds.isEmpty())
         {
-            // If there were no client ids specified, refer to the List of client ids by calling 
+            // If there were no client ids specified, refer to the List of client ids by calling
             // FacesContext.getRenderPhaseClientIds()
             clientIds = pContext.getRenderPhaseClientIds();
         }
-        
+
         return clientIds;
     }
 
     /**
-     * Process the specified phase by calling PhaseListener.beforePhase for every phase listeners defined on this 
-     * view root, then calling the process method of the processor, broadcasting relevant events and finally 
+     * Process the specified phase by calling PhaseListener.beforePhase for every phase listeners defined on this
+     * view root, then calling the process method of the processor, broadcasting relevant events and finally
      * notifying the afterPhase method of every phase listeners registered on this view root.
-     * 
+     *
      * @param context
      * @param phaseId
      * @param processor
      * @param broadcast
-     * 
+     *
      * @return
      */
     private boolean _process(FacesContext context, PhaseId phaseId, PhaseProcessor processor)
@@ -1120,21 +1124,21 @@
 
             broadcastEvents(context, phaseId);
         }
-        
+
         if (context.getRenderResponse() || context.getResponseComplete())
         {
             clearEvents();
         }
-        
+
         return notifyListeners(context, phaseId, getAfterPhaseListener(), false);
     }
-    
+
     private void _processDecodesAjax(FacesContext context)
     {
         List<String> clientIds = _getAjaxClientIds(context);
         if (clientIds == null || clientIds.isEmpty())
         {
-            // If partial processing was not perfomed on any components, perform processDecodes on all components 
+            // If partial processing was not perfomed on any components, perform processDecodes on all components
             // in the view.
             _processDecodesDefault(context);
         }
@@ -1142,33 +1146,33 @@
         {
             for (String clientId : clientIds)
             {
-                // For each client id in the list, using invokeOnComponent, call the respective processDecodes method 
+                // For each client id in the list, using invokeOnComponent, call the respective processDecodes method
                 // on the component with that client id.
                 invokeOnComponent(context, clientId, APPLY_REQUEST_VALUES_CALLBACK);
             }
-            
+
             /*
-             * Obtain an instance of a response writer that uses content type text/xml by calling 
-             * FacesContext.getPartialResponseWriter(). Install the writer by calling 
-             * FacesContext.setResponseWriter(javax.faces.context.ResponseWriter). 
+             * Obtain an instance of a response writer that uses content type text/xml by calling
+             * FacesContext.getPartialResponseWriter(). Install the writer by calling
+             * FacesContext.setResponseWriter(javax.faces.context.ResponseWriter).
              */
             context.setResponseWriter(context.getPartialViewContext().getPartialResponseWriter());
         }
     }
-    
+
     private void _processDecodesDefault(FacesContext context)
     {
-        // If FacesContext.isAjaxRequest() returned false, or partial processing was not perfomed on any components, 
+        // If FacesContext.isAjaxRequest() returned false, or partial processing was not perfomed on any components,
         // perform processDecodes on all components in the view.
         super.processDecodes(context);
     }
-    
+
     private void _processUpdatesAjax(FacesContext context)
     {
         List<String> clientIds = _getAjaxClientIds(context);
         if (clientIds == null || clientIds.isEmpty())
         {
-            // If partial processing was not perfomed on any components, perform processDecodes on all components 
+            // If partial processing was not perfomed on any components, perform processDecodes on all components
             // in the view.
             _processUpdatesDefault(context);
         }
@@ -1176,26 +1180,26 @@
         {
             for (String clientId : clientIds)
             {
-                // For each client id in the list, using invokeOnComponent, call the respective processUpdates method 
+                // For each client id in the list, using invokeOnComponent, call the respective processUpdates method
                 // on the component with that client id.
                 invokeOnComponent(context, clientId, UPDATE_MODEL_CALLBACK);
             }
         }
     }
-    
+
     private void _processUpdatesDefault(FacesContext context)
     {
-        // If FacesContext.isAjaxRequest() returned false, or partial processing was not perfomed on any components, 
+        // If FacesContext.isAjaxRequest() returned false, or partial processing was not perfomed on any components,
         // perform processUpdates on all components in the view.
         super.processUpdates(context);
     }
-    
+
     private void _processValidatorsAjax(FacesContext context)
     {
         List<String> clientIds = _getAjaxClientIds(context);
         if (clientIds == null || clientIds.isEmpty())
         {
-            // If partial processing was not perfomed on any components, perform processDecodes on all components 
+            // If partial processing was not perfomed on any components, perform processDecodes on all components
             // in the view.
             _processValidatorsDefault(context);
         }
@@ -1203,16 +1207,16 @@
         {
             for (String clientId : clientIds)
             {
-                // For each client id in the list, using invokeOnComponent, call the respective processValidators 
+                // For each client id in the list, using invokeOnComponent, call the respective processValidators
                 // method on the component with that client id.
                 invokeOnComponent(context, clientId, PROCESS_VALIDATORS_CALLBACK);
             }
         }
     }
-    
+
     private void _processValidatorsDefault(FacesContext context)
     {
-        // If FacesContext.isAjaxRequest()  returned false, or partial processing was not perfomed on any components, 
+        // If FacesContext.isAjaxRequest()  returned false, or partial processing was not perfomed on any components,
         // perform processValidators on all components in the view.
         super.processValidators(context);
     }
@@ -1236,7 +1240,7 @@
             }
         }
     }
-    
+
     private static class ProcessValidatorPhaseProcessor implements PhaseProcessor
     {
         public void process(FacesContext context, UIViewRoot root)
@@ -1251,7 +1255,7 @@
             }
         }
     }
-    
+
     private static class UpdateModelPhaseProcessor implements PhaseProcessor
     {
         public void process(FacesContext context, UIViewRoot root)
@@ -1266,35 +1270,35 @@
             }
         }
     }
-    
+
     private static class AjaxEncodeAllCallback implements ContextCallback
     {
         public void invokeContextCallback(FacesContext context, UIComponent target)
         {
             // Each component's rendered markup must be wrapped as follows:
             ResponseWriter writer = context.getResponseWriter();
-            
+
             try
             {
                 // <render id="form:table"/>
                 writer.startElement(AJAX_RESPONSE_RENDER, target);
                 writer.writeAttribute("id", target.getClientId(context), "clientId");
-                
+
                 // <markup>
                 writer.startElement(AJAX_RESPONSE_MARKUP, target);
-                
+
                 // <![CDATA[
                 writer.write(AJAX_RESPONSE_CHARACTER_DATA_START);
 
                 // component rendered markup **
                 target.encodeAll(context);
-                
+
                 // ]]>
                 writer.write(AJAX_RESPONSE_CHARACTER_DATA_END);
-                
+
                 // </markup>
                 writer.endElement(AJAX_RESPONSE_MARKUP);
-                
+
                 // </render>
                 writer.endElement(AJAX_RESPONSE_RENDER);
             }
@@ -1312,7 +1316,7 @@
             target.processDecodes(context);
         }
     }
-    
+
     private static class ProcessValidatorPhaseCallback implements ContextCallback
     {
         public void invokeContextCallback(FacesContext context, UIComponent target)
@@ -1320,11 +1324,11 @@
             target.processValidators(context);
         }
     }
-    
+
     private class RestoreStateCallback implements ContextCallback
     {
         private AfterRestoreStateEvent event;
-        
+
         public void invokeContextCallback(FacesContext context, UIComponent target)
         {
             if (event == null)
@@ -1335,14 +1339,14 @@
             {
                 event.setComponent(target);
             }
-            
-            // call the processEvent method of the current component. 
-            // The argument event must be an instance of AfterRestoreStateEvent whose component 
+
+            // call the processEvent method of the current component.
+            // The argument event must be an instance of AfterRestoreStateEvent whose component
             // property is the current component in the traversal.
             processEvent(event);
         }
     }
-    
+
     private static class UpdateModelPhaseCallback implements ContextCallback
     {
         public void invokeContextCallback(FacesContext context, UIComponent target)
@@ -1350,16 +1354,16 @@
             target.processUpdates(context);
         }
     }
-    
+
     private static class CallbackIOException extends RuntimeException
     {
         private IOException exception;
-        
+
         public CallbackIOException(IOException exception)
         {
             super(exception);
         }
-        
+
         public IOException getIOException()
         {
             return exception;