Coverage Report - javax.faces.component.UIComponentBase
 
Classes in this File Line Coverage Branch Coverage Complexity
UIComponentBase
54%
456/830
49%
253/514
5.047
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements.  See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership.  The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License.  You may obtain a copy of the License at
 9  
  *
 10  
  *   http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied.  See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package javax.faces.component;
 20  
 
 21  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
 22  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspProperty;
 23  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
 24  
 
 25  
 import javax.el.ValueExpression;
 26  
 import javax.faces.FacesException;
 27  
 import javax.faces.component.behavior.Behavior;
 28  
 import javax.faces.component.behavior.ClientBehavior;
 29  
 import javax.faces.component.visit.VisitCallback;
 30  
 import javax.faces.component.visit.VisitContext;
 31  
 import javax.faces.context.FacesContext;
 32  
 import javax.faces.el.ValueBinding;
 33  
 import javax.faces.event.AbortProcessingException;
 34  
 import javax.faces.event.BehaviorEvent;
 35  
 import javax.faces.event.FacesEvent;
 36  
 import javax.faces.event.FacesListener;
 37  
 import javax.faces.event.PostAddToViewEvent;
 38  
 import javax.faces.event.PostValidateEvent;
 39  
 import javax.faces.event.PreRemoveFromViewEvent;
 40  
 import javax.faces.event.PreRenderComponentEvent;
 41  
 import javax.faces.event.PreValidateEvent;
 42  
 import javax.faces.event.SystemEvent;
 43  
 import javax.faces.event.SystemEventListener;
 44  
 import javax.faces.render.RenderKit;
 45  
 import javax.faces.render.Renderer;
 46  
 import javax.faces.view.Location;
 47  
 import java.io.IOException;
 48  
 import java.io.Serializable;
 49  
 import java.lang.reflect.Array;
 50  
 import java.util.ArrayList;
 51  
 import java.util.Collection;
 52  
 import java.util.Collections;
 53  
 import java.util.HashMap;
 54  
 import java.util.Iterator;
 55  
 import java.util.List;
 56  
 import java.util.Map;
 57  
 import java.util.logging.Level;
 58  
 import java.util.logging.Logger;
 59  
 import javax.faces.event.PhaseId;
 60  
 
 61  
 
 62  
 /**
 63  
  * Standard implementation of the UIComponent base class; all standard JSF components extend this class.
 64  
  * <p>
 65  
  * <i>Disclaimer</i>: The official definition for the behaviour of this class is the JSF 1.1 specification but for legal
 66  
  * reasons the specification cannot be replicated here. Any javadoc here therefore describes the current implementation
 67  
  * rather than the spec, though this class has been verified as correctly implementing the spec.
 68  
  * 
 69  
  * see Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a> for
 70  
  * more.
 71  
  */
 72  
 @JSFComponent(type = "javax.faces.ComponentBase", family = "javax.faces.ComponentBase",
 73  
               desc = "base component when all components must inherit",
 74  
               tagClass = "javax.faces.webapp.UIComponentELTag", configExcluded = true)
 75  
 @JSFJspProperty(name = "binding", returnType = "javax.faces.component.UIComponent",
 76  
                 longDesc = "Identifies a backing bean property (of type UIComponent or appropriate subclass) to bind "
 77  
                            + "to this component instance. This value must be an EL expression.",
 78  
                 desc = "backing bean property to bind to this component instance")
 79  
 public abstract class UIComponentBase extends UIComponent
 80  
 {
 81  
     //private static Log log = LogFactory.getLog(UIComponentBase.class);
 82  2
     private static Logger log = Logger.getLogger(UIComponentBase.class.getName());
 83  
 
 84  2
     private static final Iterator<UIComponent> _EMPTY_UICOMPONENT_ITERATOR = new _EmptyIterator<UIComponent>();
 85  
 
 86  
     private static final String _STRING_BUILDER_KEY
 87  
             = "javax.faces.component.UIComponentBase.SHARED_STRING_BUILDER";
 88  
 
 89  
     static final int RESET_MODE_OFF = 0;
 90  
     static final int RESET_MODE_SOFT = 1;
 91  
     static final int RESET_MODE_HARD = 2;
 92  
 
 93  1554
     private _ComponentAttributesMap _attributesMap = null;
 94  1554
     private _PassThroughAttributesMap _passthroughAttributesMap = null;
 95  1554
     private List<UIComponent> _childrenList = null;
 96  1554
     private Map<String, UIComponent> _facetMap = null;
 97  1554
     private _DeltaList<FacesListener> _facesListeners = null;
 98  1554
     private String _clientId = null;
 99  1554
     private String _id = null;
 100  1554
     private UIComponent _parent = null;
 101  1554
     private boolean _transient = false;
 102  
     
 103  
     //private boolean _isRendererTypeSet = false;
 104  
     private String _rendererType;
 105  
     private String _markCreated;
 106  
     private String _facetName;
 107  
     //private boolean _addedByHandler = false;
 108  
     //private boolean _facetCreatedUIPanel = false;
 109  
     //private boolean _passthroughAttributesMapSet = false;
 110  
     
 111  1554
     private int _capabilities = 0;
 112  
     private final static int FLAG_IS_RENDERER_TYPE_SET = 1;
 113  
     private final static int FLAG_ADDED_BY_HANDLER = 2;
 114  
     private final static int FLAG_FACET_CREATED_UIPANEL = 4;
 115  
     private final static int FLAG_PASSTHROUGH_ATTRIBUTE_MAP_SET = 8;
 116  
 
 117  
     /**
 118  
      * This map holds ClientBehavior instances.
 119  
      * 
 120  
      *  Note that BehaviorBase implements PartialStateHolder, so this class 
 121  
      *  should deal with that fact on clearInitialState() and 
 122  
      *  markInitialState() methods.
 123  
      * 
 124  
      *  Also, the map used by this instance is not set from outside this class.
 125  
      *  
 126  
      *  Note it is possible (but maybe not expected/valid) to manipulate 
 127  
      *  the values of the map(the list) but not put instances on the map 
 128  
      *  directly, because ClientBehaviorHolder.getClientBehaviors says that 
 129  
      *  this method should return a non null unmodificable map.
 130  
      *  
 131  
      */
 132  1554
     private Map<String, List<ClientBehavior>> _behaviorsMap = null;
 133  1554
     private transient Map<String, List<ClientBehavior>> _unmodifiableBehaviorsMap = null;
 134  
     
 135  
     private transient FacesContext _facesContext;
 136  
     private transient Boolean _cachedIsRendered;
 137  
     private transient Renderer _cachedRenderer;
 138  
     
 139  
     public UIComponentBase()
 140  1554
     {
 141  1554
     }
 142  
 
 143  
     /**
 144  
      * Put the provided value-binding into a map of value-bindings associated with this component.
 145  
      * 
 146  
      * @deprecated Replaced by setValueExpression
 147  
      */
 148  
     @Override
 149  
     public void setValueBinding(String name, ValueBinding binding)
 150  
     {
 151  8
         setValueExpression(name, binding == null ? null : new _ValueBindingToValueExpression(binding));
 152  8
     }
 153  
 
 154  
     /**
 155  
      * Set an identifier for this component which is unique within the scope of the nearest ancestor NamingContainer
 156  
      * component. The id is not necessarily unique across all components in the current view.
 157  
      * <p>
 158  
      * The id must start with an underscore if it is generated by the JSF framework, and must <i>not</i> start with an
 159  
      * underscore if it has been specified by the user (eg in a JSP tag).
 160  
      * <p>
 161  
      * The first character of the id must be an underscore or letter. Following characters may be letters, digits,
 162  
      * underscores or dashes.
 163  
      * <p>
 164  
      * Null is allowed as a parameter, and will reset the id to null.
 165  
      * <p>
 166  
      * The clientId of this component is reset by this method; see getClientId for more info.
 167  
      * 
 168  
      * @throws IllegalArgumentException
 169  
      *             if the id is not valid.
 170  
      */
 171  
     @Override
 172  
     public void setId(String id)
 173  
     {
 174  1008
         isIdValid(id);
 175  1008
         _id = id;
 176  1008
         _clientId = null;
 177  1008
     }
 178  
 
 179  
     /**
 180  
      * <p>Set the parent <code>UIComponent</code> of this
 181  
      * <code>UIComponent</code>.</p>
 182  
      * 
 183  
      * @param parent The new parent, or <code>null</code> for the root node
 184  
      *  of a component tree
 185  
      */
 186  
     @Override
 187  
     public void setParent(UIComponent parent)
 188  
     {
 189  
         // removing kids OR this is UIViewRoot
 190  402
         if (parent == null)
 191  
         {
 192  
             // not UIViewRoot...
 193  40
             if (_parent != null && _parent.isInView())
 194  
             {
 195  
                 // trigger the "remove event" lifecycle
 196  
                 // and call setInView(false) for all children/facets
 197  
                 // doing this => recursive
 198  12
                 FacesContext facesContext = getFacesContext();
 199  12
                 if (facesContext.isProcessingEvents())
 200  
                 {
 201  12
                     _publishPreRemoveFromViewEvent(facesContext, this);
 202  
                 }
 203  
                 else
 204  
                 {
 205  0
                     _updateInView(this, false);
 206  
                 }
 207  
             }
 208  40
             _parent = null;
 209  
         }
 210  
         else
 211  
         {
 212  362
             _parent = parent;
 213  362
             if (parent.isInView())
 214  
             {
 215  
                 // trigger the ADD_EVENT and call setInView(true)
 216  
                 // recursive for all kids/facets...
 217  
                 // Application.publishEvent(java.lang.Class, java.lang.Object)  must be called, passing 
 218  
                 // PostAddToViewEvent.class as the first argument and the newly added component as the second 
 219  
                 // argument.
 220  122
                 FacesContext facesContext = parent.isCachedFacesContext() ?
 221  
                     parent.getFacesContext() : getFacesContext();
 222  122
                 if (facesContext.isProcessingEvents())
 223  
                 {
 224  122
                     _publishPostAddToViewEvent(facesContext, this);
 225  
                 }
 226  
                 else
 227  
                 {
 228  0
                     _updateInView(this, true);
 229  
                 }
 230  
             }
 231  
         }
 232  402
     }
 233  
 
 234  
     
 235  
     /**
 236  
      * Publish PostAddToViewEvent to the component and all facets and children.
 237  
      * 
 238  
      * @param context
 239  
      * @param component
 240  
      */
 241  
     private static void _publishPostAddToViewEvent(FacesContext context, UIComponent component)
 242  
     {
 243  140
         component.setInView(true);
 244  140
         context.getApplication().publishEvent(context, PostAddToViewEvent.class, component.getClass(), component);
 245  
         
 246  140
         if (component.getChildCount() > 0)
 247  
         {
 248  
             // PostAddToViewEvent could cause component relocation
 249  
             // (h:outputScript, h:outputStylesheet, composite:insertChildren, composite:insertFacet)
 250  
             // so we need to check if the component was relocated or not
 251  
           
 252  10
             List<UIComponent> children = component.getChildren();
 253  22
             for (int i = 0; i < children.size(); i++)
 254  
             {
 255  
                 // spin on same index while component removed/replaced
 256  
                 // to prevent skipping components:
 257  
                 while (true)
 258  
                 {
 259  12
                     UIComponent child = children.get(i);
 260  12
                     child.pushComponentToEL(context, child);
 261  
                     try
 262  
                     {
 263  12
                         _publishPostAddToViewEvent(context, child);
 264  
                     }
 265  
                     finally
 266  
                     {
 267  12
                         child.popComponentFromEL(context);
 268  12
                     }
 269  12
                     if (i < children.size() && children.get(i) != child)
 270  
                     {
 271  0
                         continue;
 272  
                     }
 273  
                     break;
 274  
                 }
 275  
             }
 276  
         }
 277  140
         if (component.getFacetCount() > 0)
 278  
         {
 279  6
             for (UIComponent child : component.getFacets().values())
 280  
             {
 281  6
                 child.pushComponentToEL(context, child);
 282  
                 try
 283  
                 {
 284  6
                     _publishPostAddToViewEvent(context, child);
 285  
                 }
 286  
                 finally
 287  
                 {
 288  6
                     child.popComponentFromEL(context);
 289  6
                 }
 290  6
             }
 291  
         }        
 292  140
     }
 293  
     
 294  
     /**
 295  
      * Publish PreRemoveFromViewEvent to the component and all facets and children.
 296  
      * 
 297  
      * @param context
 298  
      * @param component
 299  
      */
 300  
     private static void _publishPreRemoveFromViewEvent(FacesContext context, UIComponent component)
 301  
     {
 302  12
         component.setInView(false);
 303  12
         context.getApplication().publishEvent(context, PreRemoveFromViewEvent.class, component.getClass(), component);
 304  
         
 305  12
         if (component.getChildCount() > 0)
 306  
         {
 307  0
             for (int i = 0, childCount = component.getChildCount(); i < childCount; i++)
 308  
             {
 309  0
                 UIComponent child = component.getChildren().get(i);
 310  0
                 _publishPreRemoveFromViewEvent(context, child);
 311  
             }
 312  
         }
 313  12
         if (component.getFacetCount() > 0)
 314  
         {
 315  0
             for (UIComponent child : component.getFacets().values())
 316  
             {
 317  0
                 _publishPreRemoveFromViewEvent(context, child);
 318  0
             }
 319  
         }        
 320  12
     }    
 321  
     
 322  
     private static void _updateInView(UIComponent component, boolean isInView)
 323  
     {
 324  0
         component.setInView(isInView);
 325  
         
 326  0
         if (component.getChildCount() > 0)
 327  
         {
 328  0
             for (int i = 0, childCount = component.getChildCount(); i < childCount; i++)
 329  
             {
 330  0
                 UIComponent child = component.getChildren().get(i);
 331  0
                 _updateInView(child, isInView);
 332  
             }
 333  
         }
 334  0
         if (component.getFacetCount() > 0)
 335  
         {
 336  0
             for (UIComponent child : component.getFacets().values())
 337  
             {
 338  0
                 _updateInView(child, isInView);
 339  0
             }
 340  
         }        
 341  0
     }  
 342  
     
 343  
     /**
 344  
      * 
 345  
      * @param eventName
 346  
      * @param behavior
 347  
      * 
 348  
      * @since 2.0
 349  
      */
 350  
     public void addClientBehavior(String eventName, ClientBehavior behavior)
 351  
     {
 352  0
         Collection<String> eventNames = getEventNames();
 353  
         
 354  0
         if(eventNames == null)
 355  
         {
 356  
             //component didn't implement getEventNames properly
 357  
             //log an error and return
 358  0
             if(log.isLoggable(Level.SEVERE))
 359  
             {
 360  0
                 log.severe("attempted to add a behavior to a component which did not properly "
 361  
                            + "implement getEventNames.  getEventNames must not return null");
 362  0
                 return;
 363  
             }
 364  
         }
 365  
         
 366  0
         if(eventNames.contains(eventName))
 367  
         {
 368  0
             if(_behaviorsMap == null)
 369  
             {
 370  0
                 _behaviorsMap = new HashMap<String,List<ClientBehavior>>();
 371  
             }
 372  
             
 373  0
             List<ClientBehavior> behaviorsForEvent = _behaviorsMap.get(eventName);
 374  0
             if(behaviorsForEvent == null)
 375  
             {
 376  
                 // Normally have client only 1 client behaviour per event name,
 377  
                 // so size 2 must be sufficient: 
 378  0
                 behaviorsForEvent = new _DeltaList<ClientBehavior>(new ArrayList<ClientBehavior>(2));
 379  0
                 _behaviorsMap.put(eventName, behaviorsForEvent);
 380  
             }
 381  
             
 382  0
             behaviorsForEvent.add(behavior);
 383  0
             _unmodifiableBehaviorsMap = null;
 384  
         }
 385  0
     }
 386  
 
 387  
     /**
 388  
      * Invoke any listeners attached to this object which are listening for an event whose type matches the specified
 389  
      * event's runtime type.
 390  
      * <p>
 391  
      * This method does not propagate the event up to parent components, ie listeners attached to parent components
 392  
      * don't automatically get called.
 393  
      * <p>
 394  
      * If any of the listeners throws AbortProcessingException then that exception will prevent any further listener
 395  
      * callbacks from occurring, and the exception propagates out of this method without alteration.
 396  
      * <p>
 397  
      * ActionEvent events are typically queued by the renderer associated with this component in its decode method;
 398  
      * ValueChangeEvent events by the component's validate method. In either case the event's source property references
 399  
      * a component. At some later time the UIViewRoot component iterates over its queued events and invokes the
 400  
      * broadcast method on each event's source object.
 401  
      * 
 402  
      * @param event
 403  
      *            must not be null.
 404  
      */
 405  
     @Override
 406  
     public void broadcast(FacesEvent event) throws AbortProcessingException
 407  
     {
 408  64
         if (event == null)
 409  
         {
 410  2
             throw new NullPointerException("event");
 411  
         }
 412  
         
 413  62
         if (event instanceof BehaviorEvent && event.getComponent() == this)
 414  
         {
 415  0
             Behavior behavior = ((BehaviorEvent) event).getBehavior();
 416  0
             behavior.broadcast((BehaviorEvent) event);
 417  
         }
 418  
 
 419  62
         if (_facesListeners == null)
 420  
         {
 421  2
             return;
 422  
         }
 423  
         // perf: _facesListeners is RandomAccess instance (javax.faces.component._DeltaList)
 424  122
         for (int i = 0, size = _facesListeners.size(); i < size; i++)
 425  
         {
 426  62
             FacesListener facesListener = _facesListeners.get(i);
 427  62
             if (event.isAppropriateListener(facesListener))
 428  
             {
 429  60
                 event.processListener(facesListener);
 430  
             }
 431  
         }
 432  60
     }
 433  
     
 434  
     public void clearInitialState()
 435  
     {
 436  86
         super.clearInitialState();
 437  86
         if (_facesListeners != null)
 438  
         {
 439  4
             _facesListeners.clearInitialState();
 440  
         }
 441  86
         if (_behaviorsMap != null)
 442  
         {
 443  0
             for (Map.Entry<String, List<ClientBehavior> > entry : _behaviorsMap.entrySet())
 444  
             {
 445  0
                 ((PartialStateHolder) entry.getValue()).clearInitialState();
 446  0
             }
 447  
         }
 448  86
         if (_systemEventListenerClassMap != null)
 449  
         {
 450  
             for (Map.Entry<Class<? extends SystemEvent>, List<SystemEventListener>> entry : 
 451  0
                 _systemEventListenerClassMap.entrySet())
 452  
             {
 453  0
                 ((PartialStateHolder) entry.getValue()).clearInitialState();
 454  0
             }
 455  
         }
 456  
         //_isRendererTypeSet = false;
 457  86
         _capabilities &= ~(FLAG_IS_RENDERER_TYPE_SET);
 458  86
     }
 459  
 
 460  
     /**
 461  
      * Check the submitted form parameters for data associated with this component. This default implementation
 462  
      * delegates to this component's renderer if there is one, and otherwise ignores the call.
 463  
      */
 464  
     @Override
 465  
     public void decode(FacesContext context)
 466  
     {
 467  32
         if (context == null)
 468  
         {
 469  2
             throw new NullPointerException("context");
 470  
         }
 471  
         
 472  30
         setCachedRenderer(null);
 473  30
         Renderer renderer = getRenderer(context);
 474  30
         if (renderer != null)
 475  
         {
 476  26
             setCachedRenderer(renderer);
 477  
             try
 478  
             {
 479  26
                 renderer.decode(context, this);
 480  
             }
 481  
             finally
 482  
             {
 483  26
                 setCachedRenderer(null);
 484  26
             }
 485  
         }
 486  
 
 487  30
     }
 488  
 
 489  
     public void encodeAll(FacesContext context) throws IOException
 490  
     {
 491  0
         if (context == null)
 492  
         {
 493  0
             throw new NullPointerException();
 494  
         }
 495  
 
 496  0
         pushComponentToEL(context, this);
 497  
         try
 498  
         {
 499  0
             setCachedIsRendered(null);
 500  
             boolean rendered;
 501  
             try
 502  
             {
 503  0
                 setCachedFacesContext(context);
 504  0
                 rendered = isRendered();
 505  
             }
 506  
             finally
 507  
             {
 508  0
                 setCachedFacesContext(null);
 509  0
             } 
 510  0
             setCachedIsRendered(rendered);
 511  0
             if (!rendered)
 512  
             {
 513  0
                 setCachedIsRendered(null);
 514  
                 return;
 515  
             }
 516  0
             setCachedRenderer(null);
 517  0
             setCachedRenderer(getRenderer(context));
 518  
         }
 519  
         finally
 520  
         {
 521  0
             popComponentFromEL(context);
 522  0
         }
 523  
 
 524  
         try
 525  
         {
 526  
             //if (isRendered()) {
 527  0
             this.encodeBegin(context);
 528  
 
 529  
             // rendering children
 530  
             boolean rendersChildren;
 531  
             try
 532  
             {
 533  0
                 setCachedFacesContext(context);
 534  0
                 rendersChildren = this.getRendersChildren();
 535  
             }
 536  
             finally
 537  
             {
 538  0
                 setCachedFacesContext(null);
 539  0
             }
 540  0
             if (rendersChildren)
 541  
             {
 542  0
                 this.encodeChildren(context);
 543  
             } // let children render itself
 544  
             else
 545  
             {
 546  0
                 if (this.getChildCount() > 0)
 547  
                 {
 548  0
                     for (int i = 0; i < this.getChildCount(); i++)
 549  
                     {
 550  0
                         UIComponent comp = this.getChildren().get(i);
 551  0
                         comp.encodeAll(context);
 552  
                     }
 553  
                 }
 554  
             }
 555  0
             this.encodeEnd(context);
 556  
             //}
 557  
         }
 558  
         finally
 559  
         {
 560  0
             setCachedIsRendered(null);
 561  0
             setCachedRenderer(null);
 562  0
         }
 563  0
     }
 564  
 
 565  
     @Override
 566  
     public void encodeBegin(FacesContext context) throws IOException
 567  
     {
 568  4
         if (context == null)
 569  
         {
 570  2
             throw new NullPointerException("context");
 571  
         }
 572  
 
 573  
         try
 574  
         {
 575  2
             setCachedFacesContext(context);
 576  
             // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
 577  2
             pushComponentToEL(context, this);
 578  
     
 579  2
             if (isRendered())
 580  
             {
 581  
                 // If our rendered property is true, render the beginning of the current state of this
 582  
                 // UIComponent to the response contained in the specified FacesContext.
 583  
     
 584  
                 // Call Application.publishEvent(java.lang.Class, java.lang.Object), passing BeforeRenderEvent.class as
 585  
                 // the first argument and the component instance to be rendered as the second argument.
 586  
     
 587  
                 // The main issue we have here is that the listeners are normally just registered
 588  
                 // to UIComponent, how do we deal with inherited ones?
 589  
                 // We have to ask the EG
 590  2
                 context.getApplication().publishEvent(context,  PreRenderComponentEvent.class, UIComponent.class, this);
 591  
     
 592  2
                 Renderer renderer = getRenderer(context);
 593  2
                 if (renderer != null)
 594  
                 {
 595  
                     // If a Renderer is associated with this UIComponent, the actual encoding will be delegated to
 596  
                     // Renderer.encodeBegin(FacesContext, UIComponent).
 597  0
                     renderer.encodeBegin(context, this);
 598  
                 }
 599  
             }
 600  
         }
 601  
         finally
 602  
         {
 603  2
             setCachedFacesContext(null);
 604  2
         }
 605  2
     }
 606  
 
 607  
     @Override
 608  
     public void encodeChildren(FacesContext context) throws IOException
 609  
     {
 610  6
         if (context == null)
 611  
         {
 612  2
             throw new NullPointerException("context");
 613  
         }
 614  
 
 615  4
         boolean isCachedFacesContext = isCachedFacesContext();
 616  
         try
 617  
         {
 618  4
             if (!isCachedFacesContext)
 619  
             {
 620  4
                 setCachedFacesContext(context);
 621  
             }
 622  4
             if (isRendered())
 623  
             {
 624  
                 // If our rendered property is true, render the child UIComponents of this UIComponent.
 625  
     
 626  2
                 Renderer renderer = getRenderer(context);
 627  2
                 if (renderer == null)
 628  
                 {
 629  
                     // If no Renderer is associated with this UIComponent, iterate over each of the children of this
 630  
                     // component and call UIComponent.encodeAll(javax.faces.context.FacesContext).
 631  0
                     if (getChildCount() > 0)
 632  
                     {
 633  0
                         for (int i = 0, childCount = getChildCount(); i < childCount; i++)
 634  
                         {
 635  0
                             UIComponent child = getChildren().get(i);
 636  0
                             child.encodeAll(context);
 637  
                         }
 638  
                     }
 639  
                 }
 640  
                 else
 641  
                 {
 642  
                     // If a Renderer is associated with this UIComponent, the actual encoding will be delegated to
 643  
                     // Renderer.encodeChildren(FacesContext, UIComponent).
 644  2
                     renderer.encodeChildren(context, this);
 645  
                 }
 646  
             }
 647  
         }
 648  
         finally
 649  
         {
 650  4
             if (!isCachedFacesContext)
 651  
             {
 652  4
                 setCachedFacesContext(null);
 653  
             }
 654  
         }
 655  4
     }
 656  
 
 657  
     @Override
 658  
     public void encodeEnd(FacesContext context) throws IOException
 659  
     {
 660  2
         if (context == null)
 661  
         {
 662  2
             throw new NullPointerException("context");
 663  
         }
 664  
         try
 665  
         {
 666  0
             setCachedFacesContext(context);
 667  0
             if (isRendered())
 668  
             {
 669  
                 // If our rendered property is true, render the ending of the current state of this UIComponent.
 670  0
                 Renderer renderer = getRenderer(context);
 671  0
                 if (renderer != null)
 672  
                 {
 673  
                     // If a Renderer is associated with this UIComponent, the actual encoding will be delegated to
 674  
                     // Renderer.encodeEnd(FacesContext, UIComponent).
 675  0
                     renderer.encodeEnd(context, this);
 676  
                 }
 677  
             }
 678  
         }
 679  
         finally
 680  
         {
 681  
             // Call UIComponent.popComponentFromEL(javax.faces.context.FacesContext). before returning regardless
 682  
             // of the value of the rendered property.
 683  0
             popComponentFromEL(context);
 684  0
             setCachedFacesContext(null);
 685  0
         }
 686  0
     }
 687  
     
 688  
     /**
 689  
      * Standard method for finding other components by id, inherited by most UIComponent objects.
 690  
      * <p>
 691  
      * The lookup is performed in a manner similar to finding a file in a filesystem; there is a "base" at which to
 692  
      * start, and the id can be for something in the "local directory", or can include a relative path. Here,
 693  
      * NamingContainer components fill the role of directories, and ":" is the "path separator". Note, however, that
 694  
      * although components have a strict parent/child hierarchy, component ids are only prefixed ("namespaced") with the
 695  
      * id of their parent when the parent is a NamingContainer.
 696  
      * <p>
 697  
      * The base node at which the search starts is determined as follows:
 698  
      * <ul>
 699  
      * <li>When expr starts with ':', the search starts with the root component of the tree that this component is in
 700  
      * (ie the ancestor whose parent is null).
 701  
      * <li>Otherwise, if this component is a NamingContainer then the search starts with this component.
 702  
      * <li>Otherwise, the search starts from the nearest ancestor NamingContainer (or the root component if there is no
 703  
      * NamingContainer ancestor).
 704  
      * </ul>
 705  
      * 
 706  
      * @param expr
 707  
      *            is of form "id1:id2:id3".
 708  
      * @return UIComponent or null if no component with the specified id is found.
 709  
      */
 710  
 
 711  
     @Override
 712  
     public UIComponent findComponent(String expr)
 713  
     {
 714  46
         if (expr == null)
 715  
         {
 716  2
             throw new NullPointerException("expr");
 717  
         }
 718  44
         if (expr.length() == 0)
 719  
         {
 720  2
             return null;
 721  
         }
 722  
 
 723  42
         char separatorChar = getFacesContext().getNamingContainerSeparatorChar();
 724  
         UIComponent findBase;
 725  42
         if (expr.charAt(0) == separatorChar)
 726  
         {
 727  20
             findBase = _ComponentUtils.getRootComponent(this);
 728  20
             expr = expr.substring(1);
 729  
         }
 730  
         else
 731  
         {
 732  22
             if (this instanceof NamingContainer)
 733  
             {
 734  18
                 findBase = this;
 735  
             }
 736  
             else
 737  
             {
 738  4
                 findBase = _ComponentUtils.findParentNamingContainer(this, true /* root if not found */);
 739  
             }
 740  
         }
 741  
 
 742  42
         int separator = expr.indexOf(separatorChar);
 743  42
         if (separator == -1)
 744  
         {
 745  28
             return _ComponentUtils.findComponent(findBase, expr, separatorChar);
 746  
         }
 747  
 
 748  14
         String id = expr.substring(0, separator);
 749  14
         findBase = _ComponentUtils.findComponent(findBase, id, separatorChar);
 750  14
         if (findBase == null)
 751  
         {
 752  0
             return null;
 753  
         }
 754  
 
 755  14
         if (!(findBase instanceof NamingContainer))
 756  
         {
 757  0
             throw new IllegalArgumentException("Intermediate identifier " + id + " in search expression " + expr
 758  
                     + " identifies a UIComponent that is not a NamingContainer");
 759  
         }
 760  
 
 761  14
         return findBase.findComponent(expr.substring(separator + 1));
 762  
 
 763  
     }
 764  
 
 765  
     /**
 766  
      * Get a map through which all the UIComponent's properties, value-bindings and non-property attributes can be read
 767  
      * and written.
 768  
      * <p>
 769  
      * When writing to the returned map:
 770  
      * <ul>
 771  
      * <li>If this component has an explicit property for the specified key then the setter method is called. An
 772  
      * IllegalArgumentException is thrown if the property is read-only. If the property is readable then the old value
 773  
      * is returned, otherwise null is returned.
 774  
      * <li>Otherwise the key/value pair is stored in a map associated with the component.
 775  
      * </ul>
 776  
      * Note that value-bindings are <i>not</i> written by put calls to this map. Writing to the attributes map using a
 777  
      * key for which a value-binding exists will just store the value in the attributes map rather than evaluating the
 778  
      * binding, effectively "hiding" the value-binding from later attributes.get calls. Setter methods on components
 779  
      * commonly do <i>not</i> evaluate a binding of the same name; they just store the provided value directly on the
 780  
      * component.
 781  
      * <p>
 782  
      * When reading from the returned map:
 783  
      * <ul>
 784  
      * <li>If this component has an explicit property for the specified key then the getter method is called. If the
 785  
      * property exists, but is read-only (ie only a setter method is defined) then an IllegalArgumentException is
 786  
      * thrown.
 787  
      * <li>If the attribute map associated with the component has an entry with the specified key, then that is
 788  
      * returned.
 789  
      * <li>If this component has a value-binding for the specified key, then the value-binding is evaluated to fetch the
 790  
      * value.
 791  
      * <li>Otherwise, null is returned.
 792  
      * </ul>
 793  
      * Note that components commonly define getter methods such that they evaluate a value-binding of the same name if
 794  
      * there isn't yet a local property.
 795  
      * <p>
 796  
      * Assigning values to the map which are not explicit properties on the underlying component can be used to "tunnel"
 797  
      * attributes from the JSP tag (or view-specific equivalent) to the associated renderer without modifying the
 798  
      * component itself.
 799  
      * <p>
 800  
      * Any value-bindings and non-property attributes stored in this map are automatically serialized along with the
 801  
      * component when the view is serialized.
 802  
      */
 803  
     @Override
 804  
     public Map<String, Object> getAttributes()
 805  
     {
 806  980
         if (_attributesMap == null)
 807  
         {
 808  276
             _attributesMap = new _ComponentAttributesMap(this);
 809  
         }
 810  
 
 811  980
         return _attributesMap;
 812  
     }
 813  
 
 814  
     @Override
 815  
     public Map<String, Object> getPassThroughAttributes(boolean create)
 816  
     {
 817  
         // Take into account the param "create" in MyFaces case does not have
 818  
         // sense at all
 819  0
         if (_passthroughAttributesMap == null)
 820  
         {
 821  0
             if (!create)
 822  
             {
 823  0
                 if ((_capabilities & FLAG_PASSTHROUGH_ATTRIBUTE_MAP_SET) != 0)
 824  
                 {
 825  
                     // Was already created, return wrapper
 826  0
                     _passthroughAttributesMap = new _PassThroughAttributesMap(this);
 827  
                 }
 828  
             }
 829  
             else
 830  
             {
 831  0
                 _passthroughAttributesMap = new _PassThroughAttributesMap(this);
 832  0
                 _capabilities |= FLAG_PASSTHROUGH_ATTRIBUTE_MAP_SET;
 833  
             }
 834  
         }
 835  0
         return _passthroughAttributesMap;
 836  
     }
 837  
 
 838  
     /**
 839  
      * Return the number of direct child components this component has.
 840  
      * <p>
 841  
      * Identical to getChildren().size() except that when this component has no children this method will not force an
 842  
      * empty list to be created.
 843  
      */
 844  
     @Override
 845  
     public int getChildCount()
 846  
     {
 847  3196
         return _childrenList == null ? 0 : _childrenList.size();
 848  
     }
 849  
 
 850  
     /**
 851  
      * Return a list of the UIComponent objects which are direct children of this component.
 852  
      * <p>
 853  
      * The list object returned has some non-standard behaviour:
 854  
      * <ul>
 855  
      * <li>The list is type-checked; only UIComponent objects can be added.
 856  
      * <li>If a component is added to the list with an id which is the same as some other component in the list then an
 857  
      * exception is thrown. However multiple components with a null id may be added.
 858  
      * <li>The component's parent property is set to this component. If the component already had a parent, then the
 859  
      * component is first removed from its original parent's child list.
 860  
      * </ul>
 861  
      */
 862  
     @Override
 863  
     public List<UIComponent> getChildren()
 864  
     {
 865  1590
         if (_childrenList == null)
 866  
         {
 867  252
             _childrenList = new _ComponentChildrenList(this);
 868  
         }
 869  1590
         return _childrenList;
 870  
     }
 871  
     
 872  
     /**
 873  
      * 
 874  
      * @return
 875  
      * 
 876  
      * @since 2.0
 877  
      */
 878  
     public Map<String,List<ClientBehavior>> getClientBehaviors()
 879  
     {
 880  0
         if(_behaviorsMap == null)
 881  
         {
 882  0
             return Collections.emptyMap();
 883  
         }
 884  
 
 885  0
         return wrapBehaviorsMap();
 886  
     }
 887  
 
 888  
     /**
 889  
      * Get a string which can be output to the response which uniquely identifies this UIComponent within the current
 890  
      * view.
 891  
      * <p>
 892  
      * The component should have an id attribute already assigned to it; however if the id property is currently null
 893  
      * then a unique id is generated and set for this component. This only happens when components are programmatically
 894  
      * created without ids, as components created by a ViewHandler should be assigned ids when they are created.
 895  
      * <p>
 896  
      * If this component is a descendant of a NamingContainer then the client id is of form
 897  
      * "{namingContainerId}:{componentId}". Note that the naming container's id may itself be of compound form if it has
 898  
      * an ancestor naming container. Note also that this only applies to naming containers; other UIComponent types in
 899  
      * the component's ancestry do not affect the clientId.
 900  
      * <p>
 901  
      * Finally the renderer associated with this component is asked to convert the id into a suitable form. This allows
 902  
      * escaping of any characters in the clientId which are significant for the markup language generated by that
 903  
      * renderer.
 904  
      */
 905  
     @Override
 906  
     public String getClientId(FacesContext context)
 907  
     {
 908  1262
         if (context == null)
 909  
         {
 910  2
             throw new NullPointerException("context");
 911  
         }
 912  
 
 913  1260
         if (_clientId != null)
 914  
         {
 915  946
             return _clientId;
 916  
         }
 917  
 
 918  
         //boolean idWasNull = false;
 919  314
         String id = getId();
 920  314
         if (id == null)
 921  
         {
 922  
             // Although this is an error prone side effect, we automatically create a new id
 923  
             // just to be compatible to the RI
 924  
             
 925  
             // The documentation of UniqueIdVendor says that this interface should be implemented by
 926  
             // components that also implements NamingContainer. The only component that does not implement
 927  
             // NamingContainer but UniqueIdVendor is UIViewRoot. Anyway we just can't be 100% sure about this
 928  
             // fact, so it is better to scan for the closest UniqueIdVendor. If it is not found use 
 929  
             // viewRoot.createUniqueId, otherwise use UniqueIdVendor.createUniqueId(context,seed).
 930  46
             UniqueIdVendor parentUniqueIdVendor = _ComponentUtils.findParentUniqueIdVendor(this);
 931  46
             if (parentUniqueIdVendor == null)
 932  
             {
 933  42
                 UIViewRoot viewRoot = context.getViewRoot();
 934  42
                 if (viewRoot != null)
 935  
                 {
 936  40
                     id = viewRoot.createUniqueId();
 937  
                 }
 938  
                 else
 939  
                 {
 940  
                     // The RI throws a NPE
 941  2
                     String location = getComponentLocation(this);
 942  2
                     throw new FacesException("Cannot create clientId. No id is assigned for component"
 943  
                             + " to create an id and UIViewRoot is not defined: "
 944  
                             + getPathToComponent(this)
 945  
                             + (location != null ? " created from: " + location : ""));
 946  
                 }
 947  40
             }
 948  
             else
 949  
             {
 950  4
                 id = parentUniqueIdVendor.createUniqueId(context, null);
 951  
             }
 952  44
             setId(id);
 953  
             // We remember that the id was null and log a warning down below
 954  
             // idWasNull = true;
 955  
         }
 956  
 
 957  312
         UIComponent namingContainer = _ComponentUtils.findParentNamingContainer(this, false);
 958  312
         if (namingContainer != null)
 959  
         {
 960  172
             String containerClientId = namingContainer.getContainerClientId(context);
 961  172
             if (containerClientId != null)
 962  
             {
 963  172
                 StringBuilder bld = _getSharedStringBuilder(context);
 964  172
                 _clientId = bld.append(containerClientId).append(
 965  
                                       context.getNamingContainerSeparatorChar()).append(id).toString();
 966  172
             }
 967  
             else
 968  
             {
 969  0
                 _clientId = id;
 970  
             }
 971  172
         }
 972  
         else
 973  
         {
 974  140
             _clientId = id;
 975  
         }
 976  
 
 977  312
         Renderer renderer = getRenderer(context);
 978  312
         if (renderer != null)
 979  
         {
 980  84
             _clientId = renderer.convertClientId(context, _clientId);
 981  
         }
 982  
 
 983  
         // -=Leonardo Uribe=- In jsf 1.1 and 1.2 this warning has sense, but in jsf 2.0 it is common to have
 984  
         // components without any explicit id (UIViewParameter components and UIOuput resource components) instances.
 985  
         // So, this warning is becoming obsolete in this new context and should be removed.
 986  
         //if (idWasNull && log.isLoggable(Level.WARNING))
 987  
         //{
 988  
         //    log.warning("WARNING: Component " + _clientId
 989  
         //            + " just got an automatic id, because there was no id assigned yet. "
 990  
         //            + "If this component was created dynamically (i.e. not by a JSP tag) you should assign it an "
 991  
         //            + "explicit static id or assign it the id you get from "
 992  
         //            + "the createUniqueId from the current UIViewRoot "
 993  
         //            + "component right after creation! Path to Component: " + getPathToComponent(this));
 994  
         //}
 995  
 
 996  312
         return _clientId;
 997  
     }
 998  
     
 999  
     /**
 1000  
      * 
 1001  
      * @return
 1002  
      * 
 1003  
      * @since 2.0
 1004  
      */
 1005  
     public String getDefaultEventName()
 1006  
     {
 1007  
         // if a default event exists for a component, this method is overriden thus assume null
 1008  0
         return null;
 1009  
     }
 1010  
     
 1011  
     /**
 1012  
      * 
 1013  
      * @return
 1014  
      * 
 1015  
      * @since 2.0
 1016  
      */
 1017  
     public Collection<String> getEventNames()
 1018  
     {
 1019  
         // must be specified by the implementing component.
 1020  
         // Returning null will force an error message in addClientBehavior.
 1021  0
         return null;
 1022  
     }
 1023  
 
 1024  
     @Override
 1025  
     public UIComponent getFacet(String name)
 1026  
     {
 1027  0
         return _facetMap == null ? null : _facetMap.get(name);
 1028  
     }
 1029  
 
 1030  
     /**
 1031  
      * @since 1.2
 1032  
      */
 1033  
     @Override
 1034  
     public int getFacetCount()
 1035  
     {
 1036  1012
         return _facetMap == null ? 0 : _facetMap.size();
 1037  
     }
 1038  
 
 1039  
     @Override
 1040  
     public Map<String, UIComponent> getFacets()
 1041  
     {
 1042  66
         if (_facetMap == null)
 1043  
         {
 1044  18
             _facetMap = new _ComponentFacetMap<UIComponent>(this);
 1045  
         }
 1046  66
         return _facetMap;
 1047  
     }
 1048  
 
 1049  
     @Override
 1050  
     public Iterator<UIComponent> getFacetsAndChildren()
 1051  
     {
 1052  
         // we can't use _facetMap and _childrenList here directly,
 1053  
         // because some component implementation could keep their 
 1054  
         // own properties for facets and children and just override
 1055  
         // getFacets() and getChildren() (e.g. seen in PrimeFaces).
 1056  
         // See MYFACES-2611 for details.
 1057  144
         if (getFacetCount() == 0)
 1058  
         {
 1059  144
             if (getChildCount() == 0)
 1060  
             {
 1061  144
                 return _EMPTY_UICOMPONENT_ITERATOR;
 1062  
             }
 1063  
 
 1064  0
             return getChildren().iterator();
 1065  
         }
 1066  
         else
 1067  
         {
 1068  0
             if (getChildCount() == 0)
 1069  
             {
 1070  0
                 return getFacets().values().iterator();
 1071  
             }
 1072  
 
 1073  0
             return new _FacetsAndChildrenIterator(getFacets(), getChildren());
 1074  
         }
 1075  
     }
 1076  
 
 1077  
     /**
 1078  
      * Get a string which uniquely identifies this UIComponent within the scope of the nearest ancestor NamingContainer
 1079  
      * component. The id is not necessarily unique across all components in the current view.
 1080  
      */
 1081  
     @JSFProperty(rtexprvalue = true)
 1082  
     public String getId()
 1083  
     {
 1084  1666
         return _id;
 1085  
     }
 1086  
 
 1087  
     @Override
 1088  
     public UIComponent getParent()
 1089  
     {
 1090  1992
         return _parent;
 1091  
     }
 1092  
 
 1093  
     @Override
 1094  
     public String getRendererType()
 1095  
     {
 1096  
         // rendererType is literal-only, no ValueExpression - MYFACES-3136:
 1097  
         // Even if this is true, according to JSF spec section 8 Rendering Model,
 1098  
         // this part is essential to implement "delegated implementation" pattern,
 1099  
         // so we can't do this optimization here. Instead, JSF developers could prevent
 1100  
         // this evaluation overriding this method directly.
 1101  394
         if (_rendererType != null)
 1102  
         {
 1103  292
             return _rendererType;
 1104  
         }
 1105  102
         ValueExpression expression = getValueExpression("rendererType");
 1106  102
         if (expression != null)
 1107  
         {
 1108  0
             return (String) expression.getValue(getFacesContext().getELContext());
 1109  
         }
 1110  102
         return null;
 1111  
     }
 1112  
 
 1113  
     /**
 1114  
      * Indicates whether this component or its renderer manages the invocation of the rendering methods of its child
 1115  
      * components. When this is true:
 1116  
      * <ul>
 1117  
      * <li>This component's encodeBegin method will only be called after all the child components have been created and
 1118  
      * added to this component. <li>This component's encodeChildren method will be called after its encodeBegin method.
 1119  
      * Components for which this method returns false do not get this method invoked at all. <li>No rendering methods
 1120  
      * will be called automatically on child components; this component is required to invoke the
 1121  
      * encodeBegin/encodeEnd/etc on them itself.
 1122  
      * </ul>
 1123  
      */
 1124  
     @Override
 1125  
     public boolean getRendersChildren()
 1126  
     {
 1127  6
         Renderer renderer = getRenderer(getFacesContext());
 1128  6
         return renderer != null ? renderer.getRendersChildren() : false;
 1129  
     }
 1130  
 
 1131  
     /**
 1132  
      * Get the named value-binding associated with this component.
 1133  
      * <p>
 1134  
      * Value-bindings are stored in a map associated with the component, though there is commonly a property
 1135  
      * (setter/getter methods) of the same name defined on the component itself which evaluates the value-binding when
 1136  
      * called.
 1137  
      * 
 1138  
      * @deprecated Replaced by getValueExpression
 1139  
      */
 1140  
     @Override
 1141  
     public ValueBinding getValueBinding(String name)
 1142  
     {
 1143  10
         ValueExpression expression = getValueExpression(name);
 1144  10
         if (expression != null)
 1145  
         {
 1146  8
             if (expression instanceof _ValueBindingToValueExpression)
 1147  
             {
 1148  6
                 return ((_ValueBindingToValueExpression) expression).getValueBinding();
 1149  
             }
 1150  2
             return new _ValueExpressionToValueBinding(expression);
 1151  
         }
 1152  2
         return null;
 1153  
     }
 1154  
     
 1155  
     /**
 1156  
      * <code>invokeOnComponent</code> must be implemented in <code>UIComponentBase</code> too...
 1157  
      */
 1158  
     @Override
 1159  
     public boolean invokeOnComponent(FacesContext context, String clientId, ContextCallback callback)
 1160  
             throws FacesException
 1161  
     {
 1162  18
         if (isCachedFacesContext())
 1163  
         {
 1164  0
             return super.invokeOnComponent(context, clientId, callback);
 1165  
         }
 1166  
         else
 1167  
         {
 1168  
             try
 1169  
             {
 1170  18
                 setCachedFacesContext(context);
 1171  18
                 return super.invokeOnComponent(context, clientId, callback);
 1172  
             }
 1173  
             finally
 1174  
             {
 1175  16
                 setCachedFacesContext(null);
 1176  
             }
 1177  
         }
 1178  
     }
 1179  
 
 1180  
     @Override
 1181  
     public boolean visitTree(VisitContext context, VisitCallback callback)
 1182  
     {
 1183  62
         if (isCachedFacesContext())
 1184  
         {
 1185  0
             return super.visitTree(context, callback);
 1186  
         }
 1187  
         else
 1188  
         {
 1189  
             try
 1190  
             {
 1191  62
                 setCachedFacesContext(context.getFacesContext());
 1192  62
                 return super.visitTree(context, callback);
 1193  
             }
 1194  
             finally
 1195  
             {
 1196  62
                 setCachedFacesContext(null);
 1197  
             }
 1198  
         }
 1199  
     }
 1200  
 
 1201  
     /**
 1202  
      * A boolean value that indicates whether this component should be rendered. Default value: true.
 1203  
      **/
 1204  
     @Override
 1205  
     @JSFProperty
 1206  
     public boolean isRendered()
 1207  
     {
 1208  104
         if (_cachedIsRendered != null)
 1209  
         {
 1210  0
             return Boolean.TRUE.equals(_cachedIsRendered);
 1211  
         }
 1212  104
         return (Boolean) getStateHelper().eval(PropertyKeys.rendered, DEFAULT_RENDERED);
 1213  
     }
 1214  
 
 1215  
     @JSFProperty(literalOnly = true, istransient = true, tagExcluded = true)
 1216  
     public boolean isTransient()
 1217  
     {
 1218  1004
         return _transient;
 1219  
     }
 1220  
     
 1221  
     public void markInitialState()
 1222  
     {
 1223  328
         super.markInitialState();
 1224  
         
 1225  
         // Enable copyFullInitialState behavior when delta is written into this component.
 1226  328
         ((_DeltaStateHelper)getStateHelper()).setCopyFullInitialState(true);
 1227  
         
 1228  328
         if (_facesListeners != null)
 1229  
         {
 1230  40
             _facesListeners.markInitialState();
 1231  
         }
 1232  328
         if (_behaviorsMap != null)
 1233  
         {
 1234  0
             for (Map.Entry<String, List<ClientBehavior> > entry : _behaviorsMap.entrySet())
 1235  
             {
 1236  0
                 ((PartialStateHolder) entry.getValue()).markInitialState();
 1237  0
             }
 1238  
         }
 1239  328
         if (_systemEventListenerClassMap != null)
 1240  
         {
 1241  
             for (Map.Entry<Class<? extends SystemEvent>, List<SystemEventListener>> entry : 
 1242  0
                 _systemEventListenerClassMap.entrySet())
 1243  
             {
 1244  0
                 ((PartialStateHolder) entry.getValue()).markInitialState();
 1245  0
             }
 1246  
         }
 1247  328
     }
 1248  
 
 1249  
     @Override
 1250  
     protected void addFacesListener(FacesListener listener)
 1251  
     {
 1252  84
         if (listener == null)
 1253  
         {
 1254  0
             throw new NullPointerException("listener");
 1255  
         }
 1256  84
         if (_facesListeners == null)
 1257  
         {
 1258  
             // How many facesListeners have single component normally? 
 1259  62
             _facesListeners = new _DeltaList<FacesListener>(new ArrayList<FacesListener>(5));
 1260  
         }
 1261  84
         _facesListeners.add(listener);
 1262  84
     }
 1263  
 
 1264  
     @Override
 1265  
     protected FacesContext getFacesContext()
 1266  
     {
 1267  21748
         if (_facesContext == null)
 1268  
         {
 1269  21490
             return FacesContext.getCurrentInstance();
 1270  
         }
 1271  
         else
 1272  
         {
 1273  258
             return _facesContext;
 1274  
         }
 1275  
     }
 1276  
 
 1277  
     // FIXME: Notify EG for generic usage
 1278  
     @Override
 1279  
     protected FacesListener[] getFacesListeners(Class clazz)
 1280  
     {
 1281  158
         if (clazz == null)
 1282  
         {
 1283  2
             throw new NullPointerException("Class is null");
 1284  
         }
 1285  156
         if (!FacesListener.class.isAssignableFrom(clazz))
 1286  
         {
 1287  2
             throw new IllegalArgumentException("Class " + clazz.getName() + " must implement " + FacesListener.class);
 1288  
         }
 1289  
 
 1290  154
         if (_facesListeners == null)
 1291  
         {
 1292  2
             return (FacesListener[]) Array.newInstance(clazz, 0);
 1293  
         }
 1294  152
         List<FacesListener> lst = null;
 1295  
         // perf: _facesListeners is RandomAccess instance (javax.faces.component._DeltaList)
 1296  302
         for (int i = 0, size = _facesListeners.size(); i < size; i++)
 1297  
         {
 1298  150
             FacesListener facesListener = _facesListeners.get(i);
 1299  150
             if (facesListener != null && clazz.isAssignableFrom(facesListener.getClass()))
 1300  
             {
 1301  148
                 if (lst == null)
 1302  
                 {
 1303  88
                     lst = new ArrayList<FacesListener>();
 1304  
                 }
 1305  148
                 lst.add(facesListener);
 1306  
             }
 1307  
         }
 1308  152
         if (lst == null)
 1309  
         {
 1310  64
             return (FacesListener[]) Array.newInstance(clazz, 0);
 1311  
         }
 1312  
 
 1313  88
         return lst.toArray((FacesListener[]) Array.newInstance(clazz, lst.size()));
 1314  
     }
 1315  
 
 1316  
     @Override
 1317  
     protected Renderer getRenderer(FacesContext context)
 1318  
     {
 1319  368
         if (context == null)
 1320  
         {
 1321  0
             throw new NullPointerException("context");
 1322  
         }
 1323  368
         Renderer renderer = getCachedRenderer();
 1324  368
         if (renderer != null)
 1325  
         {
 1326  0
             return renderer;
 1327  
         }
 1328  368
         String rendererType = getRendererType();
 1329  368
         if (rendererType == null)
 1330  
         {
 1331  102
             return null;
 1332  
         }
 1333  
         
 1334  266
         RenderKit renderKit = context.getRenderKit();
 1335  266
         renderer = renderKit.getRenderer(getFamily(), rendererType);
 1336  266
         if (renderer == null)
 1337  
         {
 1338  152
             String location = getComponentLocation(this);
 1339  152
             String logStr = "No Renderer found for component " + getPathToComponent(this)
 1340  
                     + " (component-family=" + getFamily()
 1341  
                     + ", renderer-type=" + rendererType + ")"
 1342  
                     + (location != null ? " created from: " + location : "");
 1343  
             
 1344  152
             getFacesContext().getExternalContext().log(logStr);
 1345  152
             log.warning(logStr);
 1346  
         }
 1347  266
         return renderer;
 1348  
     }
 1349  
 
 1350  
     @Override
 1351  
     protected void removeFacesListener(FacesListener listener)
 1352  
     {
 1353  54
         if (listener == null)
 1354  
         {
 1355  2
             throw new NullPointerException("listener is null");
 1356  
         }
 1357  
 
 1358  52
         if (_facesListeners != null)
 1359  
         {
 1360  52
             _facesListeners.remove(listener);
 1361  
         }
 1362  52
     }
 1363  
 
 1364  
     @Override
 1365  
     public void queueEvent(FacesEvent event)
 1366  
     {
 1367  70
         if (event == null)
 1368  
         {
 1369  2
             throw new NullPointerException("event");
 1370  
         }
 1371  68
         UIComponent parent = getParent();
 1372  68
         if (parent == null)
 1373  
         {
 1374  2
             throw new IllegalStateException("component is not a descendant of a UIViewRoot");
 1375  
         }
 1376  66
         parent.queueEvent(event);
 1377  66
     }
 1378  
 
 1379  
     @Override
 1380  
     public void processDecodes(FacesContext context)
 1381  
     {
 1382  
         try
 1383  
         {
 1384  24
             setCachedFacesContext(context);
 1385  
             // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
 1386  24
             pushComponentToEL(context, this);
 1387  22
             if (_isPhaseExecutable(context))
 1388  
             {
 1389  
                 // Call the processDecodes() method of all facets and children of this UIComponent, in the order
 1390  
                 // determined by a call to getFacetsAndChildren().
 1391  22
                 int facetCount = getFacetCount();
 1392  22
                 if (facetCount > 0)
 1393  
                 {
 1394  0
                     for (UIComponent facet : getFacets().values())
 1395  
                     {
 1396  0
                         facet.processDecodes(context);
 1397  0
                     }
 1398  
                 }
 1399  22
                 for (int i = 0, childCount = getChildCount(); i < childCount; i++)
 1400  
                 {
 1401  0
                     UIComponent child = getChildren().get(i);
 1402  0
                     child.processDecodes(context);
 1403  
                 }
 1404  
 
 1405  
                 try
 1406  
                 {
 1407  
                     // Call the decode() method of this component.
 1408  22
                     decode(context);
 1409  
                 }
 1410  0
                 catch (RuntimeException e)
 1411  
                 {
 1412  
                     // If a RuntimeException is thrown during decode processing, call FacesContext.renderResponse()
 1413  
                     // and re-throw the exception.
 1414  0
                     context.renderResponse();
 1415  0
                     throw e;
 1416  22
                 }
 1417  
             }
 1418  
         }
 1419  
         finally
 1420  
         {
 1421  
             // Call UIComponent.popComponentFromEL(javax.faces.context.FacesContext) from inside of a finally
 1422  
             // block, just before returning.
 1423  
 
 1424  24
             popComponentFromEL(context);
 1425  22
             setCachedFacesContext(null);
 1426  22
         }
 1427  22
     }
 1428  
 
 1429  
     @Override
 1430  
     public void processValidators(FacesContext context)
 1431  
     {
 1432  
         try
 1433  
         {
 1434  2
             setCachedFacesContext(context);
 1435  
             // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
 1436  2
             pushComponentToEL(context, this);
 1437  0
             if (_isPhaseExecutable(context))
 1438  
             {
 1439  
                 //Pre validation event dispatch for component
 1440  0
                 context.getApplication().publishEvent(context,  PreValidateEvent.class, getClass(), this);
 1441  
                 
 1442  
                 try
 1443  
                 {
 1444  
                     // Call the processValidators() method of all facets and children of this UIComponent, in the order
 1445  
                     // determined by a call to getFacetsAndChildren().
 1446  0
                     int facetCount = getFacetCount();
 1447  0
                     if (facetCount > 0)
 1448  
                     {
 1449  0
                         for (UIComponent facet : getFacets().values())
 1450  
                         {
 1451  0
                             facet.processValidators(context);
 1452  0
                         }
 1453  
                     }
 1454  
     
 1455  0
                     for (int i = 0, childCount = getChildCount(); i < childCount; i++)
 1456  
                     {
 1457  0
                         UIComponent child = getChildren().get(i);
 1458  0
                         child.processValidators(context);
 1459  
                     }
 1460  
                 }
 1461  
                 finally
 1462  
                 {
 1463  0
                     context.getApplication().publishEvent(context,  PostValidateEvent.class, getClass(), this);
 1464  0
                 }
 1465  
             }
 1466  
         }
 1467  
         finally
 1468  
         {
 1469  2
             popComponentFromEL(context);
 1470  0
             setCachedFacesContext(null);
 1471  0
         }
 1472  0
     }
 1473  
 
 1474  
     /**
 1475  
      * This isn't an input component, so just pass on the processUpdates call to child components and facets that might
 1476  
      * be input components.
 1477  
      * <p>
 1478  
      * Components that were never rendered can't possibly be receiving update data (no corresponding fields were ever
 1479  
      * put into the response) so if this component is not rendered then this method does not invoke processUpdates on
 1480  
      * its children.
 1481  
      */
 1482  
     @Override
 1483  
     public void processUpdates(FacesContext context)
 1484  
     {
 1485  
         try
 1486  
         {
 1487  4
             setCachedFacesContext(context);
 1488  
             // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
 1489  4
             pushComponentToEL(context, this);
 1490  2
             if (_isPhaseExecutable(context))
 1491  
             {
 1492  
                 // Call the processUpdates() method of all facets and children of this UIComponent, in the order
 1493  
                 // determined by a call to getFacetsAndChildren().
 1494  2
                 int facetCount = getFacetCount();
 1495  2
                 if (facetCount > 0)
 1496  
                 {
 1497  0
                     for (UIComponent facet : getFacets().values())
 1498  
                     {
 1499  0
                         facet.processUpdates(context);
 1500  0
                     }
 1501  
                 }
 1502  
 
 1503  2
                 for (int i = 0, childCount = getChildCount(); i < childCount; i++)
 1504  
                 {
 1505  0
                     UIComponent child = getChildren().get(i);
 1506  0
                     child.processUpdates(context);
 1507  
                 }
 1508  
             }
 1509  
         }
 1510  
         finally
 1511  
         {
 1512  
             // After returning from the processUpdates() method on a child or facet, call
 1513  
             // UIComponent.popComponentFromEL(javax.faces.context.FacesContext)
 1514  4
             popComponentFromEL(context);
 1515  
             
 1516  2
             setCachedFacesContext(null);
 1517  2
         }
 1518  2
     }
 1519  
 
 1520  
     @Override
 1521  
     public Object processSaveState(FacesContext context)
 1522  
     {
 1523  2
         if (context == null)
 1524  
         {
 1525  2
             throw new NullPointerException("context");
 1526  
         }
 1527  
 
 1528  0
         if (isTransient())
 1529  
         {
 1530  
             // consult the transient property of this component. If true, just return null.
 1531  0
             return null;
 1532  
         }
 1533  
 
 1534  
         // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
 1535  0
         pushComponentToEL(context, this);
 1536  
 
 1537  
         Map<String, Object> facetMap;
 1538  
 
 1539  
         List<Object> childrenList;
 1540  
         
 1541  
         Object savedState;
 1542  
         try
 1543  
         {
 1544  0
             facetMap = null;
 1545  0
             int facetCount = getFacetCount();
 1546  0
             if (facetCount > 0)
 1547  
             {
 1548  
                 // Call the processSaveState() method of all facets and children of this UIComponent in the order
 1549  
                 // determined by a call to getFacetsAndChildren(), skipping children and facets that are transient.
 1550  
 
 1551  
                 // To improve speed and robustness, the facets and children processing is splited to maintain the
 1552  
                 // facet --> state coherence based on the facet's name
 1553  0
                 for (Map.Entry<String, UIComponent> entry : getFacets().entrySet())
 1554  
                 {
 1555  0
                     UIComponent component = entry.getValue();
 1556  0
                     if (!component.isTransient())
 1557  
                     {
 1558  0
                         if (facetMap == null)
 1559  
                         {
 1560  0
                             facetMap = new HashMap<String, Object>(facetCount, 1);
 1561  
                         }
 1562  
 
 1563  0
                         facetMap.put(entry.getKey(), component.processSaveState(context));
 1564  
 
 1565  
                         // Ensure that UIComponent.popComponentFromEL(javax.faces.context.FacesContext) is called
 1566  
                         // correctly after each child or facet.
 1567  
                         // popComponentFromEL(context);
 1568  
                     }
 1569  0
                 }
 1570  
             }
 1571  0
             childrenList = null;
 1572  0
             int childCount = getChildCount();
 1573  0
             if (childCount > 0)
 1574  
             {
 1575  
                 // Call the processSaveState() method of all facets and children of this UIComponent in the order
 1576  
                 // determined by a call to getFacetsAndChildren(), skipping children and facets that are transient.
 1577  
 
 1578  
                 // To improve speed and robustness, the facets and children processing is splited to maintain the
 1579  
                 // facet --> state coherence based on the facet's name
 1580  0
                 for (int i = 0; i < childCount; i++)
 1581  
                 {
 1582  0
                     UIComponent child = getChildren().get(i);
 1583  0
                     if (!child.isTransient())
 1584  
                     {
 1585  0
                         if (childrenList == null)
 1586  
                         {
 1587  0
                             childrenList = new ArrayList<Object>(childCount);
 1588  
                         }
 1589  
 
 1590  0
                         Object childState = child.processSaveState(context);
 1591  0
                         if (childState != null)
 1592  
                         { // FIXME: Isn't that check dangerous for restoration since the child isn't marked transient?
 1593  0
                             childrenList.add(childState);
 1594  
                         }
 1595  
 
 1596  
                         // Ensure that UIComponent.popComponentFromEL(javax.faces.context.FacesContext) is called
 1597  
                         // correctly after each child or facet.
 1598  
                     }
 1599  
                 }
 1600  
             }
 1601  
             
 1602  
             // Call the saveState() method of this component.
 1603  0
             savedState = saveState(context);
 1604  
         }
 1605  
         finally
 1606  
         {
 1607  0
             popComponentFromEL(context);
 1608  0
         }
 1609  
 
 1610  
         // Encapsulate the child state and your state into a Serializable Object and return it.
 1611  0
         return new Object[] { savedState, facetMap, childrenList };
 1612  
     }
 1613  
 
 1614  
     @SuppressWarnings("unchecked")
 1615  
     @Override
 1616  
     public void processRestoreState(FacesContext context, Object state)
 1617  
     {
 1618  2
         if (context == null)
 1619  
         {
 1620  2
             throw new NullPointerException("context");
 1621  
         }
 1622  
 
 1623  0
         Object[] stateValues = (Object[]) state;
 1624  
 
 1625  
         try
 1626  
         {
 1627  
             // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
 1628  0
             pushComponentToEL(context, this);
 1629  
 
 1630  
             // Call the restoreState() method of this component.
 1631  0
             restoreState(context, stateValues[0]);
 1632  
             
 1633  0
             Map<String, Object> facetMap = (Map<String, Object>) stateValues[1];
 1634  0
             if (facetMap != null && getFacetCount() > 0)
 1635  
             {
 1636  
                 // Call the processRestoreState() method of all facets and children of this UIComponent in the order
 1637  
                 // determined by a call to getFacetsAndChildren().
 1638  
 
 1639  
                 // To improve speed and robustness, the facets and children processing is splited to maintain the
 1640  
                 // facet --> state coherence based on the facet's name
 1641  0
                 for (Map.Entry<String, UIComponent> entry : getFacets().entrySet())
 1642  
                 {
 1643  0
                     Object facetState = facetMap.get(entry.getKey());
 1644  0
                     if (facetState != null)
 1645  
                     {
 1646  0
                         entry.getValue().processRestoreState(context, facetState);
 1647  
 
 1648  
                         // After returning from the processRestoreState() method on a child or facet, call
 1649  
                         // UIComponent.popComponentFromEL(javax.faces.context.FacesContext)
 1650  
                         // popComponentFromEL(context);
 1651  
                     }
 1652  
                     else
 1653  
                     {
 1654  0
                         context.getExternalContext().log("No state found to restore facet " + entry.getKey());
 1655  
                     }
 1656  0
                 }
 1657  
             }
 1658  0
             List<Object> childrenList = (List<Object>) stateValues[2];
 1659  0
             if (childrenList != null && getChildCount() > 0)
 1660  
             {
 1661  
                 // Call the processRestoreState() method of all facets and children of this UIComponent in the order
 1662  
                 // determined by a call to getFacetsAndChildren().
 1663  
 
 1664  
                 // To improve speed and robustness, the facets and children processing is splited to maintain the
 1665  
                 // facet --> state coherence based on the facet's name
 1666  0
                 int idx = 0;
 1667  0
                 for (int i = 0, childCount = getChildCount(); i < childCount; i++)
 1668  
                 {
 1669  0
                     UIComponent child = getChildren().get(i);
 1670  0
                     if (!child.isTransient())
 1671  
                     {
 1672  0
                         Object childState = childrenList.get(idx++);
 1673  0
                         if (childState != null)
 1674  
                         {
 1675  0
                             child.processRestoreState(context, childState);
 1676  
 
 1677  
                             // After returning from the processRestoreState() method on a child or facet, call
 1678  
                             // UIComponent.popComponentFromEL(javax.faces.context.FacesContext)
 1679  
                             // popComponentFromEL(context);
 1680  
                         }
 1681  
                         else
 1682  
                         {
 1683  0
                             context.getExternalContext().log("No state found to restore child of component " + getId());
 1684  
                         }
 1685  
                     }
 1686  
                 }
 1687  
             }
 1688  
         }
 1689  
         finally
 1690  
         {
 1691  0
             popComponentFromEL(context);
 1692  0
         }
 1693  0
     }
 1694  
     
 1695  
     /**
 1696  
      * Gets the Location of the given UIComponent from its attribute map.
 1697  
      * @param component
 1698  
      * @return
 1699  
      */
 1700  
     private String getComponentLocation(UIComponent component)
 1701  
     {
 1702  154
         Location location = (Location) component.getAttributes()
 1703  
                 .get(UIComponent.VIEW_LOCATION_KEY);
 1704  154
         if (location != null)
 1705  
         {
 1706  0
             return location.toString();
 1707  
         }
 1708  154
         return null;
 1709  
     }
 1710  
 
 1711  
     private String getPathToComponent(UIComponent component)
 1712  
     {
 1713  154
         StringBuffer buf = new StringBuffer();
 1714  
 
 1715  154
         if (component == null)
 1716  
         {
 1717  0
             buf.append("{Component-Path : ");
 1718  0
             buf.append("[null]}");
 1719  0
             return buf.toString();
 1720  
         }
 1721  
 
 1722  154
         getPathToComponent(component, buf);
 1723  
 
 1724  154
         buf.insert(0, "{Component-Path : ");
 1725  154
         buf.append("}");
 1726  
 
 1727  154
         return buf.toString();
 1728  
     }
 1729  
 
 1730  
     private void getPathToComponent(UIComponent component, StringBuffer buf)
 1731  
     {
 1732  536
         if (component == null)
 1733  
         {
 1734  154
             return;
 1735  
         }
 1736  
 
 1737  382
         StringBuffer intBuf = new StringBuffer();
 1738  
 
 1739  382
         intBuf.append("[Class: ");
 1740  382
         intBuf.append(component.getClass().getName());
 1741  382
         if (component instanceof UIViewRoot)
 1742  
         {
 1743  70
             intBuf.append(",ViewId: ");
 1744  70
             intBuf.append(((UIViewRoot) component).getViewId());
 1745  
         }
 1746  
         else
 1747  
         {
 1748  312
             intBuf.append(",Id: ");
 1749  312
             intBuf.append(component.getId());
 1750  
         }
 1751  382
         intBuf.append("]");
 1752  
 
 1753  382
         buf.insert(0, intBuf.toString());
 1754  
 
 1755  382
         getPathToComponent(component.getParent(), buf);
 1756  382
     }
 1757  
 
 1758  
     public void setTransient(boolean transientFlag)
 1759  
     {
 1760  0
         _transient = transientFlag;
 1761  0
     }
 1762  
 
 1763  
     /**
 1764  
      * Serializes objects which are "attached" to this component but which are not UIComponent children of it. Examples
 1765  
      * are validator and listener objects. To be precise, it returns an object which implements java.io.Serializable,
 1766  
      * and which when serialized will persist the state of the provided object.
 1767  
      * <p>
 1768  
      * If the attachedObject is a List then every object in the list is saved via a call to this method, and the
 1769  
      * returned wrapper object contains a List object.
 1770  
      * <p>
 1771  
      * If the object implements StateHolder then the object's saveState is called immediately, and a wrapper is returned
 1772  
      * which contains both this saved state and the original class name. However in the case where the
 1773  
      * StateHolder.isTransient method returns true, null is returned instead.
 1774  
      * <p>
 1775  
      * If the object implements java.io.Serializable then the object is simply returned immediately; standard java
 1776  
      * serialization will later be used to store this object.
 1777  
      * <p>
 1778  
      * In all other cases, a wrapper is returned which simply stores the type of the provided object. When deserialized,
 1779  
      * a default instance of that type will be recreated.
 1780  
      */
 1781  
     public static Object saveAttachedState(FacesContext context, Object attachedObject)
 1782  
     {
 1783  524
         if (context == null)
 1784  
         {
 1785  0
             throw new NullPointerException ("context");
 1786  
         }
 1787  
         
 1788  524
         if (attachedObject == null)
 1789  
         {
 1790  262
             return null;
 1791  
         }
 1792  
         // StateHolder interface should take precedence over
 1793  
         // List children
 1794  262
         if (attachedObject instanceof StateHolder)
 1795  
         {
 1796  202
             StateHolder holder = (StateHolder) attachedObject;
 1797  202
             if (holder.isTransient())
 1798  
             {
 1799  24
                 return null;
 1800  
             }
 1801  
 
 1802  178
             return new _AttachedStateWrapper(attachedObject.getClass(), holder.saveState(context));
 1803  
         }
 1804  60
         else if (attachedObject instanceof Collection)
 1805  
         {
 1806  0
             if (ArrayList.class.equals(attachedObject.getClass()))
 1807  
             {
 1808  0
                 ArrayList<?> list = (ArrayList<?>) attachedObject;
 1809  0
                 int size = list.size();
 1810  0
                 List<Object> lst = new ArrayList<Object>(size);
 1811  0
                 for (int i = 0; i < size; i++)
 1812  
                 {
 1813  0
                     Object item = list.get(i);
 1814  0
                     if (item != null)
 1815  
                     {
 1816  0
                         lst.add(saveAttachedState(context, item));
 1817  
                     }
 1818  
                 }
 1819  0
                 return new _AttachedListStateWrapper(lst);
 1820  
             }
 1821  
             else
 1822  
             {
 1823  0
                 List<Object> lst = new ArrayList<Object>(((Collection<?>) attachedObject).size());
 1824  0
                 for (Object item : (Collection<?>) attachedObject)
 1825  
                 {
 1826  0
                     if (item != null)
 1827  
                     {
 1828  0
                         lst.add(saveAttachedState(context, item));
 1829  
                     }
 1830  0
                 }
 1831  0
                 return new _AttachedCollectionStateWrapper(attachedObject.getClass(), lst);
 1832  
             }
 1833  
         }
 1834  60
         else if (attachedObject instanceof Serializable)
 1835  
         {
 1836  18
             return attachedObject;
 1837  
         }
 1838  
         else
 1839  
         {
 1840  42
             return new _AttachedStateWrapper(attachedObject.getClass(), null);
 1841  
         }
 1842  
     }
 1843  
 
 1844  
     public static Object restoreAttachedState(FacesContext context, Object stateObj) throws IllegalStateException
 1845  
     {
 1846  604
         if (context == null)
 1847  
         {
 1848  0
             throw new NullPointerException("context");
 1849  
         }
 1850  604
         if (stateObj == null)
 1851  
         {
 1852  192
             return null;
 1853  
         }
 1854  412
         if (stateObj instanceof _AttachedListStateWrapper)
 1855  
         {
 1856  
             // perf: getWrappedStateList in _AttachedListStateWrapper is always ArrayList: see saveAttachedState
 1857  0
             ArrayList<Object> lst = (ArrayList<Object>) ((_AttachedListStateWrapper) stateObj).getWrappedStateList();
 1858  0
             List<Object> restoredList = new ArrayList<Object>(lst.size());
 1859  0
             for (int i = 0, size = lst.size(); i < size; i++)
 1860  
             {
 1861  0
                 Object item = lst.get(i);
 1862  0
                 restoredList.add(restoreAttachedState(context, item));
 1863  
             }
 1864  0
             return restoredList;
 1865  
         }
 1866  412
         else if (stateObj instanceof _AttachedCollectionStateWrapper)
 1867  
         {
 1868  0
             _AttachedCollectionStateWrapper wrappedState = (_AttachedCollectionStateWrapper) stateObj; 
 1869  0
             Class<?> clazz = wrappedState.getClazz();
 1870  0
             List<Object> lst = wrappedState.getWrappedStateList();
 1871  
             Collection restoredList;
 1872  
             try
 1873  
             {
 1874  0
                 restoredList = (Collection) clazz.newInstance();
 1875  
             }
 1876  0
             catch (InstantiationException e)
 1877  
             {
 1878  0
                 throw new RuntimeException("Could not restore StateHolder of type " + clazz.getName()
 1879  
                         + " (missing no-args constructor?)", e);
 1880  
             }
 1881  0
             catch (IllegalAccessException e)
 1882  
             {
 1883  0
                 throw new RuntimeException(e);
 1884  0
             }
 1885  
 
 1886  0
             for (Object item : lst)
 1887  
             {
 1888  0
                 restoredList.add(restoreAttachedState(context, item));
 1889  0
             }
 1890  0
             return restoredList;
 1891  
 
 1892  
         }
 1893  412
         else if (stateObj instanceof _AttachedStateWrapper)
 1894  
         {
 1895  236
             Class<?> clazz = ((_AttachedStateWrapper) stateObj).getClazz();
 1896  
             Object restoredObject;
 1897  
             try
 1898  
             {
 1899  236
                 restoredObject = clazz.newInstance();
 1900  
             }
 1901  0
             catch (InstantiationException e)
 1902  
             {
 1903  0
                 throw new RuntimeException("Could not restore StateHolder of type " + clazz.getName()
 1904  
                         + " (missing no-args constructor?)", e);
 1905  
             }
 1906  0
             catch (IllegalAccessException e)
 1907  
             {
 1908  0
                 throw new RuntimeException(e);
 1909  236
             }
 1910  236
             if (restoredObject instanceof StateHolder)
 1911  
             {
 1912  198
                 _AttachedStateWrapper wrapper = (_AttachedStateWrapper) stateObj;
 1913  198
                 Object wrappedState = wrapper.getWrappedStateObject();
 1914  
 
 1915  198
                 StateHolder holder = (StateHolder) restoredObject;
 1916  198
                 holder.restoreState(context, wrappedState);
 1917  
             }
 1918  236
             return restoredObject;
 1919  
         }
 1920  
         else
 1921  
         {
 1922  176
             return stateObj;
 1923  
         }
 1924  
     }
 1925  
     
 1926  
     private static final int FULL_STATE_ARRAY_SIZE = 10;
 1927  
 
 1928  
     /**
 1929  
      * Invoked after the render phase has completed, this method returns an object which can be passed to the
 1930  
      * restoreState of some other instance of UIComponentBase to reset that object's state to the same values as this
 1931  
      * object currently has.
 1932  
      */
 1933  
     public Object saveState(FacesContext context)
 1934  
     {
 1935  228
         if (context == null)
 1936  
         {
 1937  0
             throw new NullPointerException ("context");
 1938  
         }
 1939  
         
 1940  228
         if (context.getViewRoot() != null)
 1941  
         {
 1942  228
             if (context.getViewRoot().getResetSaveStateMode() == RESET_MODE_SOFT)
 1943  
             {
 1944  
                 // Force FacesContext cleanup to prevent leak it.
 1945  0
                 setCachedFacesContext(null);
 1946  
                 // Reset state to recalculate state first.
 1947  0
                 StateHelper stateHelper = getStateHelper(false);
 1948  0
                 if (stateHelper != null)
 1949  
                 {
 1950  0
                     ((_DeltaStateHelper)stateHelper).resetSoftState(context);
 1951  
                 }
 1952  
             }
 1953  228
             if (context.getViewRoot().getResetSaveStateMode() == RESET_MODE_HARD)
 1954  
             {
 1955  
                 // Force FacesContext cleanup to prevent leak it.
 1956  0
                 setCachedFacesContext(null);
 1957  
                 // Reset state to recalculate state first.
 1958  0
                 StateHelper stateHelper = getStateHelper(false);
 1959  0
                 if (stateHelper != null)
 1960  
                 {
 1961  0
                     ((_DeltaStateHelper)stateHelper).resetHardState(context);
 1962  
                 }
 1963  
             }
 1964  
         }
 1965  228
         if (initialStateMarked())
 1966  
         {
 1967  
             //Delta
 1968  
             //_id and _clientId was already restored from template
 1969  
             //and never changes during component life.
 1970  188
             Object facesListenersSaved = saveFacesListenersList(context);
 1971  188
             Object behaviorsMapSaved = saveBehaviorsMap(context);
 1972  188
             Object systemEventListenerClassMapSaved = saveSystemEventListenerClassMap(context);
 1973  188
             Object stateHelperSaved = null;
 1974  188
             StateHelper stateHelper = getStateHelper(false);
 1975  188
             if (stateHelper != null)
 1976  
             {
 1977  188
                 stateHelperSaved = stateHelper.saveState(context);
 1978  
             }
 1979  
             
 1980  188
             if (facesListenersSaved == null && stateHelperSaved == null && 
 1981  
                 behaviorsMapSaved == null && systemEventListenerClassMapSaved == null &&
 1982  
                !((_capabilities & FLAG_IS_RENDERER_TYPE_SET) != 0))
 1983  
             {
 1984  98
                 return null;
 1985  
             }
 1986  
             
 1987  90
             Object transientState = null;
 1988  90
             if (context.getCurrentPhaseId() != null && 
 1989  
                 !PhaseId.RENDER_RESPONSE.equals(context.getCurrentPhaseId()))
 1990  
             {
 1991  84
                 transientState = saveTransientState(context);
 1992  
             }
 1993  
             
 1994  90
             if (transientState != null)
 1995  
             {
 1996  8
                 if ((_capabilities & FLAG_IS_RENDERER_TYPE_SET) != 0)
 1997  
                 {
 1998  0
                     return new Object[] {facesListenersSaved, stateHelperSaved, behaviorsMapSaved,
 1999  
                                         systemEventListenerClassMapSaved, transientState,
 2000  
                                         _rendererType};
 2001  
                 }
 2002  
                 else
 2003  
                 {
 2004  8
                     return new Object[] {facesListenersSaved, stateHelperSaved, behaviorsMapSaved,
 2005  
                         systemEventListenerClassMapSaved, transientState};
 2006  
                 }
 2007  
             }
 2008  
             else
 2009  
             {
 2010  82
                 if ((_capabilities & FLAG_IS_RENDERER_TYPE_SET) != 0)
 2011  
                 {
 2012  0
                     return new Object[] {facesListenersSaved, stateHelperSaved, behaviorsMapSaved,
 2013  
                                         systemEventListenerClassMapSaved, null,
 2014  
                                         _rendererType};
 2015  
                 }
 2016  
                 else
 2017  
                 {
 2018  82
                     return new Object[] {facesListenersSaved, stateHelperSaved, behaviorsMapSaved,
 2019  
                         systemEventListenerClassMapSaved};
 2020  
                 }
 2021  
             }
 2022  
         }
 2023  
         else
 2024  
         {
 2025  
             //Full
 2026  40
             Object values[] = new Object[FULL_STATE_ARRAY_SIZE];
 2027  40
             values[0] = saveFacesListenersList(context);
 2028  40
             StateHelper stateHelper = getStateHelper(false);
 2029  40
             if (stateHelper != null)
 2030  
             {
 2031  24
                 values[1] = stateHelper.saveState(context);
 2032  
             }
 2033  40
             values[2] = saveBehaviorsMap(context);
 2034  40
             values[3] = saveSystemEventListenerClassMap(context);
 2035  40
             values[4] = _id;
 2036  40
             values[5] = _clientId;
 2037  40
             values[6] = _markCreated;
 2038  40
             values[7] = _rendererType;
 2039  40
             values[8] = _capabilities;
 2040  40
             if (context.getCurrentPhaseId() != null && 
 2041  
                 !PhaseId.RENDER_RESPONSE.equals(context.getCurrentPhaseId()))
 2042  
             {
 2043  36
                 values[9] = saveTransientState(context);
 2044  
             }
 2045  
             //values[8] = _isRendererTypeSet;
 2046  
             //values[9] = _addedByHandler;
 2047  
             //values[10] = _facetCreatedUIPanel;
 2048  
 
 2049  40
             return values;
 2050  
         }
 2051  
     }
 2052  
 
 2053  
     /**
 2054  
      * Invoked in the "restore view" phase, this initialises this object's members from the values saved previously into
 2055  
      * the provided state object.
 2056  
      * <p>
 2057  
      * 
 2058  
      * @param state
 2059  
      *            is an object previously returned by the saveState method of this class.
 2060  
      */
 2061  
     @SuppressWarnings("unchecked")
 2062  
     public void restoreState(FacesContext context, Object state)
 2063  
     {
 2064  228
         if (context == null)
 2065  
         {
 2066  0
             throw new NullPointerException ("context");
 2067  
         }
 2068  
         
 2069  228
         if (state == null)
 2070  
         {
 2071  
             //Only happens if initialStateMarked return true
 2072  
             
 2073  56
             if (initialStateMarked())
 2074  
             {
 2075  56
                 return;
 2076  
             }
 2077  
             
 2078  0
             throw new NullPointerException ("state");
 2079  
         }
 2080  
         
 2081  172
         Object values[] = (Object[]) state;
 2082  
         
 2083  172
         if ( values.length == FULL_STATE_ARRAY_SIZE && initialStateMarked())
 2084  
         {
 2085  
             //Delta mode is active, but we are restoring a full state.
 2086  
             //we need to clear the initial state, to restore state without
 2087  
             //take into account delta.
 2088  0
             clearInitialState();
 2089  
         }
 2090  
         
 2091  172
         if (values[0] instanceof _AttachedDeltaWrapper)
 2092  
         {
 2093  
             //Delta: check for null is not necessary since _facesListener field
 2094  
             //is only set once and never reset
 2095  
             //if (_facesListeners != null)
 2096  
             //{
 2097  6
                 ((StateHolder)_facesListeners).restoreState(context,
 2098  
                         ((_AttachedDeltaWrapper) values[0]).getWrappedStateObject());
 2099  
             //}
 2100  
         }
 2101  166
         else if (values[0] != null || (values.length == FULL_STATE_ARRAY_SIZE))
 2102  
         {
 2103  
             //Full
 2104  110
             _facesListeners = (_DeltaList<FacesListener>)
 2105  
                 restoreAttachedState(context,values[0]);
 2106  
         }
 2107  
         // Note that if values[0] == null && initialStateMarked(),
 2108  
         // means delta is null, not that _facesListeners == null. 
 2109  
         // We can do this here because _facesListeners instance once
 2110  
         // is created is never replaced or set to null.
 2111  
         
 2112  172
         getStateHelper().restoreState(context, values[1]);
 2113  
         
 2114  172
         if (values.length == FULL_STATE_ARRAY_SIZE)
 2115  
         {
 2116  96
             _id = (String) values[4];
 2117  96
             _clientId = (String) values[5];
 2118  96
             _markCreated = (String) values[6];
 2119  96
             _rendererType = (String) values[7];
 2120  96
             _capabilities = (Integer) values[8];
 2121  
             //_isRendererTypeSet = (Boolean) values[8];
 2122  
             //_addedByHandler = (Boolean) values[9];
 2123  
             //_facetCreatedUIPanel = (Boolean) values[10];
 2124  
         }
 2125  76
         else if (values.length == 6)
 2126  
         {
 2127  0
             restoreTransientState(context, values[4]);
 2128  0
             _rendererType = (String) values[5];
 2129  
             //_isRendererTypeSet = true;
 2130  0
             _capabilities |= FLAG_IS_RENDERER_TYPE_SET;
 2131  
         }
 2132  76
         else if (values.length == 5)
 2133  
         {
 2134  8
             restoreTransientState(context, values[4]);
 2135  
         }
 2136  
         
 2137  
         
 2138  
         // rendererType needs to be restored before SystemEventListener,
 2139  
         // otherwise UIComponent.getCurrentComponent(context).getRenderer(context)
 2140  
         // will not work correctly
 2141  172
         if (values.length == FULL_STATE_ARRAY_SIZE)
 2142  
         {
 2143  
             //Full restore
 2144  96
             restoreFullBehaviorsMap(context, values[2]);
 2145  96
             restoreFullSystemEventListenerClassMap(context, values[3]);
 2146  96
             restoreTransientState(context, values[9]);
 2147  
         }
 2148  
         else
 2149  
         {
 2150  
             //Delta restore
 2151  76
             restoreDeltaBehaviorsMap(context, values[2]);
 2152  76
             restoreDeltaSystemEventListenerClassMap(context, values[3]);
 2153  
         }
 2154  172
     }
 2155  
     
 2156  
     private Object saveFacesListenersList(FacesContext facesContext)
 2157  
     {
 2158  228
         PartialStateHolder holder = (PartialStateHolder) _facesListeners;
 2159  228
         if (initialStateMarked() && _facesListeners != null && holder.initialStateMarked())
 2160  
         {                
 2161  10
             Object attachedState = holder.saveState(facesContext);
 2162  10
             if (attachedState != null)
 2163  
             {
 2164  6
                 return new _AttachedDeltaWrapper(_facesListeners.getClass(),
 2165  
                         attachedState);
 2166  
             }
 2167  
             //_facesListeners instances once is created never changes, we can return null
 2168  4
             return null;
 2169  
         }
 2170  
         else
 2171  
         {
 2172  218
             return saveAttachedState(facesContext,_facesListeners);
 2173  
         }            
 2174  
     }
 2175  
 
 2176  
     @SuppressWarnings("unchecked")
 2177  
     private void restoreFullBehaviorsMap(FacesContext facesContext, Object stateObj)
 2178  
     {
 2179  96
         if (stateObj != null)
 2180  
         {
 2181  0
             Map<String, Object> stateMap = (Map<String, Object>) stateObj;
 2182  0
             int initCapacity = (stateMap.size() * 4 + 3) / 3;
 2183  0
             _behaviorsMap = new HashMap<String,  List<ClientBehavior> >(initCapacity);
 2184  0
             _unmodifiableBehaviorsMap = null;
 2185  0
             for (Map.Entry<String, Object> entry : stateMap.entrySet())
 2186  
             {
 2187  0
                 _behaviorsMap.put(entry.getKey(),
 2188  
                                   (List<ClientBehavior>) restoreAttachedState(facesContext, entry.getValue()));
 2189  0
             }
 2190  0
         }
 2191  
         else
 2192  
         {
 2193  96
             _behaviorsMap = null;
 2194  96
             _unmodifiableBehaviorsMap = null;
 2195  
         }        
 2196  96
     }
 2197  
     
 2198  
     @SuppressWarnings("unchecked")
 2199  
     private void restoreDeltaBehaviorsMap(FacesContext facesContext, Object stateObj)
 2200  
     {
 2201  76
         if (stateObj != null)
 2202  
         {
 2203  0
             _unmodifiableBehaviorsMap = null;
 2204  0
             Map<String, Object> stateMap = (Map<String, Object>) stateObj;
 2205  0
             int initCapacity = (stateMap.size() * 4 + 3) / 3;
 2206  0
             if (_behaviorsMap == null)
 2207  
             {
 2208  0
                 _behaviorsMap = new HashMap<String,  List<ClientBehavior> >(initCapacity);
 2209  
             }
 2210  0
             for (Map.Entry<String, Object> entry : stateMap.entrySet())
 2211  
             {
 2212  0
                 Object savedObject = entry.getValue(); 
 2213  0
                 if (savedObject instanceof _AttachedDeltaWrapper)
 2214  
                 {
 2215  0
                     StateHolder holderList = (StateHolder) _behaviorsMap.get(entry.getKey());
 2216  0
                     holderList.restoreState(facesContext,
 2217  
                                             ((_AttachedDeltaWrapper) savedObject).getWrappedStateObject());
 2218  0
                 }
 2219  
                 else
 2220  
                 {
 2221  0
                     _behaviorsMap.put(entry.getKey(),
 2222  
                                       (List<ClientBehavior>) restoreAttachedState(facesContext, savedObject));
 2223  
                 }
 2224  0
             }
 2225  
         }
 2226  76
     }
 2227  
     
 2228  
     private Object saveBehaviorsMap(FacesContext facesContext)
 2229  
     {
 2230  228
         if (_behaviorsMap != null)
 2231  
         {
 2232  0
             if (initialStateMarked())
 2233  
             {
 2234  0
                 HashMap<String, Object> stateMap = new HashMap<String, Object>(_behaviorsMap.size(), 1);
 2235  0
                 boolean nullDelta = true;
 2236  0
                 for (Map.Entry<String, List<ClientBehavior> > entry : _behaviorsMap.entrySet())
 2237  
                 {
 2238  
                     // The list is always an instance of _DeltaList so we can cast to
 2239  
                     // PartialStateHolder 
 2240  0
                     PartialStateHolder holder = (PartialStateHolder) entry.getValue();
 2241  0
                     if (holder.initialStateMarked())
 2242  
                     {
 2243  0
                         Object attachedState = holder.saveState(facesContext);
 2244  0
                         if (attachedState != null)
 2245  
                         {
 2246  0
                             stateMap.put(entry.getKey(), new _AttachedDeltaWrapper(_behaviorsMap.getClass(),
 2247  
                                     attachedState));
 2248  0
                             nullDelta = false;
 2249  
                         }
 2250  0
                     }
 2251  
                     else
 2252  
                     {
 2253  0
                         stateMap.put(entry.getKey(), saveAttachedState(facesContext, holder));
 2254  0
                         nullDelta = false;
 2255  
                     }
 2256  0
                 }
 2257  0
                 if (nullDelta)
 2258  
                 {
 2259  0
                     return null;
 2260  
                 }
 2261  0
                 return stateMap;
 2262  
             }
 2263  
             else
 2264  
             {
 2265  
                 //Save it in the traditional way
 2266  0
                 HashMap<String, Object> stateMap = 
 2267  
                     new HashMap<String, Object>(_behaviorsMap.size(), 1);
 2268  0
                 for (Map.Entry<String, List<ClientBehavior> > entry : _behaviorsMap.entrySet())
 2269  
                 {
 2270  0
                     stateMap.put(entry.getKey(), saveAttachedState(facesContext, entry.getValue()));
 2271  0
                 }
 2272  0
                 return stateMap;
 2273  
             }
 2274  
         }
 2275  
         else
 2276  
         {
 2277  228
             return null;
 2278  
         }
 2279  
     }
 2280  
     
 2281  
     @SuppressWarnings("unchecked")
 2282  
     private void restoreFullSystemEventListenerClassMap(FacesContext facesContext, Object stateObj)
 2283  
     {
 2284  96
         if (stateObj != null)
 2285  
         {
 2286  0
             Map<Class<? extends SystemEvent>, Object> stateMap = (Map<Class<? extends SystemEvent>, Object>) stateObj;
 2287  0
             int initCapacity = (stateMap.size() * 4 + 3) / 3;
 2288  0
             _systemEventListenerClassMap
 2289  
                     = new HashMap<Class<? extends SystemEvent>, List<SystemEventListener>>(initCapacity);
 2290  0
             for (Map.Entry<Class<? extends SystemEvent>, Object> entry : stateMap.entrySet())
 2291  
             {
 2292  0
                 _systemEventListenerClassMap.put(entry.getKey(),
 2293  
                         (List<SystemEventListener>) restoreAttachedState(facesContext, entry.getValue()));
 2294  0
             }
 2295  0
         }
 2296  
         else
 2297  
         {
 2298  96
             _systemEventListenerClassMap = null;
 2299  
         }        
 2300  96
     }
 2301  
     
 2302  
     @SuppressWarnings("unchecked")
 2303  
     private void restoreDeltaSystemEventListenerClassMap(FacesContext facesContext, Object stateObj)
 2304  
     {
 2305  76
         if (stateObj != null)
 2306  
         {
 2307  0
             Map<Class<? extends SystemEvent>, Object> stateMap = (Map<Class<? extends SystemEvent>, Object>) stateObj;
 2308  0
             int initCapacity = (stateMap.size() * 4 + 3) / 3;
 2309  0
             if (_systemEventListenerClassMap == null)
 2310  
             {
 2311  0
                 _systemEventListenerClassMap
 2312  
                         = new HashMap<Class<? extends SystemEvent>, List<SystemEventListener>>(initCapacity);
 2313  
             }
 2314  0
             for (Map.Entry<Class<? extends SystemEvent>, Object> entry : stateMap.entrySet())
 2315  
             {
 2316  0
                 Object savedObject = entry.getValue(); 
 2317  0
                 if (savedObject instanceof _AttachedDeltaWrapper)
 2318  
                 {
 2319  0
                     StateHolder holderList = (StateHolder) _systemEventListenerClassMap.get(entry.getKey());
 2320  0
                     holderList.restoreState(facesContext,
 2321  
                                             ((_AttachedDeltaWrapper) savedObject).getWrappedStateObject());
 2322  0
                 }
 2323  
                 else
 2324  
                 {
 2325  0
                     _systemEventListenerClassMap.put(entry.getKey(),
 2326  
                             (List<SystemEventListener>) restoreAttachedState(facesContext, savedObject));
 2327  
                 }
 2328  0
             }
 2329  
         }
 2330  76
     }
 2331  
     
 2332  
     private Object saveSystemEventListenerClassMap(FacesContext facesContext)
 2333  
     {
 2334  228
         if (_systemEventListenerClassMap != null)
 2335  
         {
 2336  0
             if (initialStateMarked())
 2337  
             {
 2338  0
                 HashMap<Class<? extends SystemEvent>, Object> stateMap
 2339  
                         = new HashMap<Class<? extends SystemEvent>, Object>(_systemEventListenerClassMap.size(), 1);
 2340  0
                 boolean nullDelta = true;
 2341  
                 for (Map.Entry<Class<? extends SystemEvent>, List<SystemEventListener> > entry
 2342  0
                         : _systemEventListenerClassMap.entrySet())
 2343  
                 {
 2344  
                     // The list is always an instance of _DeltaList so we can cast to
 2345  
                     // PartialStateHolder 
 2346  0
                     PartialStateHolder holder = (PartialStateHolder) entry.getValue();
 2347  0
                     if (holder.initialStateMarked())
 2348  
                     {
 2349  0
                         Object attachedState = holder.saveState(facesContext);
 2350  0
                         if (attachedState != null)
 2351  
                         {
 2352  0
                             stateMap.put(entry.getKey(),
 2353  
                                     new _AttachedDeltaWrapper(_systemEventListenerClassMap.getClass(), attachedState));
 2354  0
                             nullDelta = false;
 2355  
                         }
 2356  0
                     }
 2357  
                     else
 2358  
                     {
 2359  0
                         stateMap.put(entry.getKey(), saveAttachedState(facesContext, holder));
 2360  0
                         nullDelta = false;
 2361  
                     }
 2362  0
                 }
 2363  0
                 if (nullDelta)
 2364  
                 {
 2365  0
                     return null;
 2366  
                 }
 2367  0
                 return stateMap;
 2368  
             }
 2369  
             else
 2370  
             {
 2371  
                 //Save it in the traditional way
 2372  0
                 HashMap<Class<? extends SystemEvent>, Object> stateMap = 
 2373  
                     new HashMap<Class<? extends SystemEvent>, Object>(_systemEventListenerClassMap.size(), 1);
 2374  
                 for (Map.Entry<Class<? extends SystemEvent>, List<SystemEventListener> > entry
 2375  0
                         : _systemEventListenerClassMap.entrySet())
 2376  
                 {
 2377  0
                     stateMap.put(entry.getKey(), saveAttachedState(facesContext, entry.getValue()));
 2378  0
                 }
 2379  0
                 return stateMap;
 2380  
             }
 2381  
         }
 2382  
         else
 2383  
         {
 2384  228
             return null;
 2385  
         }
 2386  
     }
 2387  
     
 2388  
     /*
 2389  
     private Object saveBindings(FacesContext context)
 2390  
     {
 2391  
         if (bindings != null)
 2392  
         {
 2393  
             HashMap<String, Object> stateMap = new HashMap<String, Object>(bindings.size(), 1);
 2394  
             for (Iterator<Entry<String, ValueExpression>> it = bindings.entrySet().iterator(); it.hasNext();)
 2395  
             {
 2396  
                 Entry<String, ValueExpression> entry = it.next();
 2397  
                 stateMap.put(entry.getKey(), saveAttachedState(context, entry.getValue()));
 2398  
             }
 2399  
             return stateMap;
 2400  
         }
 2401  
 
 2402  
         return null;
 2403  
     }
 2404  
 
 2405  
     @SuppressWarnings("unchecked")
 2406  
     private void restoreValueExpressionMap(FacesContext context, Object stateObj)
 2407  
     {
 2408  
         if (stateObj != null)
 2409  
         {
 2410  
             Map<String, Object> stateMap = (Map<String, Object>) stateObj;
 2411  
             int initCapacity = (stateMap.size() * 4 + 3) / 3;
 2412  
             bindings = new HashMap<String, ValueExpression>(initCapacity);
 2413  
             for (Map.Entry<String, Object> entry : stateMap.entrySet())
 2414  
             {
 2415  
                 bindings.put(entry.getKey(), (ValueExpression) restoreAttachedState(context, entry.getValue()));
 2416  
             }
 2417  
         }
 2418  
         else
 2419  
         {
 2420  
             bindings = null;
 2421  
         }
 2422  
     }*/
 2423  
 
 2424  
     /**
 2425  
      * @param string
 2426  
      *            the component id, that should be a vaild one.
 2427  
      */
 2428  
     private void isIdValid(String string)
 2429  
     {
 2430  
 
 2431  
         // is there any component identifier ?
 2432  1008
         if (string == null)
 2433  
         {
 2434  160
             return;
 2435  
         }
 2436  
 
 2437  
         // Component identifiers must obey the following syntax restrictions:
 2438  
         // 1. Must not be a zero-length String.
 2439  848
         if (string.length() == 0)
 2440  
         {
 2441  0
             throw new IllegalArgumentException("component identifier must not be a zero-length String");
 2442  
         }
 2443  
 
 2444  
         // If new id is the same as old it must be valid
 2445  848
         if (string.equals(_id))
 2446  
         {
 2447  434
             return;
 2448  
         }
 2449  
 
 2450  
         // 2. First character must be a letter or an underscore ('_').
 2451  414
         if (!Character.isLetter(string.charAt(0)) && string.charAt(0) != '_')
 2452  
         {
 2453  0
             throw new IllegalArgumentException("component identifier's first character must be a letter "
 2454  
                                                + "or an underscore ('_')! But it is \""
 2455  
                                                + string.charAt(0) + "\"");
 2456  
         }
 2457  3256
         for (int i = 1; i < string.length(); i++)
 2458  
         {
 2459  2842
             char c = string.charAt(i);
 2460  
             // 3. Subsequent characters must be a letter, a digit, an underscore ('_'), or a dash ('-').
 2461  2842
             if (!Character.isLetterOrDigit(c) && c != '-' && c != '_')
 2462  
             {
 2463  0
                 throw new IllegalArgumentException("Subsequent characters of component identifier must be a letter, "
 2464  
                                                    + "a digit, an underscore ('_'), or a dash ('-')! "
 2465  
                                                    + "But component identifier contains \""
 2466  
                                                    + c + "\"");
 2467  
             }
 2468  
         }
 2469  414
     }
 2470  
 
 2471  
     private boolean _isPhaseExecutable(FacesContext context)
 2472  
     {
 2473  24
         if (context == null)
 2474  
         {
 2475  0
             throw new NullPointerException("context");
 2476  
         }
 2477  
 
 2478  
         // If the rendered property of this UIComponent is false, skip further processing.
 2479  24
         return isRendered();
 2480  
     }
 2481  
 
 2482  
     boolean isCachedFacesContext()
 2483  
     {
 2484  292
         return _facesContext != null;
 2485  
     }
 2486  
     
 2487  
     void setCachedFacesContext(FacesContext facesContext)
 2488  
     {
 2489  474
         _facesContext = facesContext;
 2490  474
     }
 2491  
     
 2492  
     Renderer getCachedRenderer()
 2493  
     {
 2494  368
         return _cachedRenderer;
 2495  
     }
 2496  
     
 2497  
     void setCachedRenderer(Renderer renderer)
 2498  
     {
 2499  1766
         _cachedRenderer = renderer;
 2500  1766
     }
 2501  
 
 2502  
     Boolean isCachedIsRendered()
 2503  
     {
 2504  0
         return _cachedIsRendered;
 2505  
     }
 2506  
     
 2507  
     void setCachedIsRendered(Boolean rendered)
 2508  
     {
 2509  6
        _cachedIsRendered = rendered;
 2510  6
     }
 2511  
     
 2512  
     <T> T getExpressionValue(String attribute, T explizitValue, T defaultValueIfExpressionNull)
 2513  
     {
 2514  0
         return _ComponentUtils.getExpressionValue(this, attribute, explizitValue, defaultValueIfExpressionNull);
 2515  
     }
 2516  
 
 2517  
     void setOamVfMarkCreated(String markCreated)
 2518  
     {
 2519  0
         _markCreated = markCreated;
 2520  0
     }
 2521  
     
 2522  
     String getOamVfMarkCreated()
 2523  
     {
 2524  0
         return _markCreated;
 2525  
     }
 2526  
     
 2527  
     String getOamVfFacetName()
 2528  
     {
 2529  0
         return _facetName;
 2530  
     }
 2531  
     
 2532  
     void setOamVfFacetName(String facetName)
 2533  
     {
 2534  0
         _facetName = facetName;
 2535  0
     }
 2536  
     
 2537  
     boolean isOamVfAddedByHandler()
 2538  
     {
 2539  0
         return (_capabilities & FLAG_ADDED_BY_HANDLER) != 0;
 2540  
     }
 2541  
     
 2542  
     void setOamVfAddedByHandler(boolean addedByHandler)
 2543  
     {
 2544  0
         if (addedByHandler)
 2545  
         {
 2546  0
             _capabilities |= FLAG_ADDED_BY_HANDLER;
 2547  
         }
 2548  
         else
 2549  
         {
 2550  0
             _capabilities &= ~(FLAG_ADDED_BY_HANDLER);
 2551  
         }
 2552  
         //_addedByHandler = addedByHandler;
 2553  0
     }
 2554  
     
 2555  
     boolean isOamVfFacetCreatedUIPanel()
 2556  
     {
 2557  0
         return (_capabilities & FLAG_FACET_CREATED_UIPANEL) != 0;
 2558  
     }
 2559  
     
 2560  
     void setOamVfFacetCreatedUIPanel(boolean facetCreatedUIPanel)
 2561  
     {
 2562  
         //_facetCreatedUIPanel = facetCreatedUIPanel;
 2563  0
         if (facetCreatedUIPanel)
 2564  
         {
 2565  0
             _capabilities |= FLAG_FACET_CREATED_UIPANEL;
 2566  
         }
 2567  
         else
 2568  
         {
 2569  0
             _capabilities &= ~(FLAG_FACET_CREATED_UIPANEL);
 2570  
         }
 2571  0
     }
 2572  
 
 2573  
 /**
 2574  
      * <p>
 2575  
      * This gets a single FacesContext-local shared stringbuilder instance, each time you call
 2576  
      * _getSharedStringBuilder it sets the length of the stringBuilder instance to 0.
 2577  
      * </p><p>
 2578  
      * This allows you to use the same StringBuilder instance over and over.
 2579  
      * You must call toString on the instance before calling _getSharedStringBuilder again.
 2580  
      * </p>
 2581  
      * Example that works
 2582  
      * <pre><code>
 2583  
      * StringBuilder sb1 = _getSharedStringBuilder();
 2584  
      * sb1.append(a).append(b);
 2585  
      * String c = sb1.toString();
 2586  
      *
 2587  
      * StringBuilder sb2 = _getSharedStringBuilder();
 2588  
      * sb2.append(b).append(a);
 2589  
      * String d = sb2.toString();
 2590  
      * </code></pre>
 2591  
      * <br><br>
 2592  
      * Example that doesn't work, you must call toString on sb1 before
 2593  
      * calling _getSharedStringBuilder again.
 2594  
      * <pre><code>
 2595  
      * StringBuilder sb1 = _getSharedStringBuilder();
 2596  
      * StringBuilder sb2 = _getSharedStringBuilder();
 2597  
      *
 2598  
      * sb1.append(a).append(b);
 2599  
      * String c = sb1.toString();
 2600  
      *
 2601  
      * sb2.append(b).append(a);
 2602  
      * String d = sb2.toString();
 2603  
      * </code></pre>
 2604  
      *
 2605  
      */
 2606  
     static StringBuilder _getSharedStringBuilder()
 2607  
     {
 2608  0
         return _getSharedStringBuilder(FacesContext.getCurrentInstance());
 2609  
     }
 2610  
 
 2611  
     // TODO checkstyle complains; does this have to lead with __ ?
 2612  
     static StringBuilder _getSharedStringBuilder(FacesContext facesContext)
 2613  
     {
 2614  20574
         Map<Object, Object> attributes = facesContext.getAttributes();
 2615  
 
 2616  20574
         StringBuilder sb = (StringBuilder) attributes.get(_STRING_BUILDER_KEY);
 2617  
 
 2618  20574
         if (sb == null)
 2619  
         {
 2620  32
             sb = new StringBuilder();
 2621  32
             attributes.put(_STRING_BUILDER_KEY, sb);
 2622  
         }
 2623  
         else
 2624  
         {
 2625  
 
 2626  
             // clear out the stringBuilder by setting the length to 0
 2627  20542
             sb.setLength(0);
 2628  
         }
 2629  
 
 2630  20574
         return sb;
 2631  
     }
 2632  
 
 2633  
     // ------------------ GENERATED CODE BEGIN (do not modify!) --------------------
 2634  
 
 2635  2
     private static final Boolean DEFAULT_RENDERED = Boolean.TRUE;
 2636  
 
 2637  
     @Override
 2638  
     public void setRendered(boolean rendered)
 2639  
     {
 2640  6
         getStateHelper().put(PropertyKeys.rendered, rendered );
 2641  6
         setCachedIsRendered(null);
 2642  6
     }
 2643  
 
 2644  
     @Override
 2645  
     public void setRendererType(String rendererType)
 2646  
     {
 2647  1684
         this._rendererType = rendererType;
 2648  1684
         if (initialStateMarked())
 2649  
         {
 2650  
             //This flag just indicates the rendererType 
 2651  
             //should be included on the delta
 2652  
             //this._isRendererTypeSet = true;
 2653  0
             _capabilities |= FLAG_IS_RENDERER_TYPE_SET;
 2654  
         }
 2655  1684
         setCachedRenderer(null);
 2656  1684
     }
 2657  
 
 2658  
     // ------------------ GENERATED CODE END ---------------------------------------
 2659  
 
 2660  
     private Map<String, List<ClientBehavior>> wrapBehaviorsMap()
 2661  
     {
 2662  0
         if (_unmodifiableBehaviorsMap == null)
 2663  
         {
 2664  0
             _unmodifiableBehaviorsMap = Collections.unmodifiableMap(_behaviorsMap); 
 2665  
         }
 2666  0
         return _unmodifiableBehaviorsMap; 
 2667  
     }
 2668  
 }