Coverage Report - javax.faces.component.UIComponentBase
 
Classes in this File Line Coverage Branch Coverage Complexity
UIComponentBase
0%
0/427
0%
0/256
0
 
 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.commons.logging.Log;
 22  
 import org.apache.commons.logging.LogFactory;
 23  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
 24  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspProperty;
 25  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
 26  
 
 27  
 import javax.el.ValueExpression;
 28  
 import javax.faces.FacesException;
 29  
 import javax.faces.FactoryFinder;
 30  
 import javax.faces.context.FacesContext;
 31  
 import javax.faces.el.ValueBinding;
 32  
 import javax.faces.event.AbortProcessingException;
 33  
 import javax.faces.event.FacesEvent;
 34  
 import javax.faces.event.FacesListener;
 35  
 import javax.faces.render.RenderKit;
 36  
 import javax.faces.render.RenderKitFactory;
 37  
 import javax.faces.render.Renderer;
 38  
 import java.io.IOException;
 39  
 import java.io.Serializable;
 40  
 import java.lang.reflect.Array;
 41  
 import java.util.ArrayList;
 42  
 import java.util.HashMap;
 43  
 import java.util.Iterator;
 44  
 import java.util.List;
 45  
 import java.util.Map;
 46  
 import java.util.Map.Entry;
 47  
 
 48  
 /**
 49  
  * Standard implementation of the UIComponent base class; all standard JSF
 50  
  * components extend this class.
 51  
  * <p>
 52  
  * <i>Disclaimer</i>: The official definition for the behaviour of
 53  
  * this class is the JSF 1.1 specification but for legal reasons the
 54  
  * specification cannot be replicated here. Any javadoc here therefore
 55  
  * describes the current implementation rather than the spec, though
 56  
  * this class has been verified as correctly implementing the spec.
 57  
  *
 58  
  * see Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a> for more.
 59  
  * 
 60  
  * @author Manfred Geiler (latest modification by $Author: lu4242 $)
 61  
  * @version $Revision: 949071 $ $Date: 2010-05-27 21:22:17 -0500 (Thu, 27 May 2010) $
 62  
  */
 63  
 @JSFComponent(type = "javax.faces.ComponentBase",
 64  
               family = "javax.faces.ComponentBase",
 65  
               desc = "base component when all components must inherit",
 66  
               tagClass = "javax.faces.webapp.UIComponentELTag",
 67  
               configExcluded = true)
 68  
 @JSFJspProperty(name = "binding" ,
 69  
                 returnType = "javax.faces.component.UIComponent",
 70  
                 longDesc = "Identifies a backing bean property (of type UIComponent or appropriate subclass) to bind to this component instance. This value must be an EL expression.",
 71  
                 desc="backing bean property to bind to this component instance")
 72  
 public abstract class UIComponentBase
 73  
         extends UIComponent
 74  
 {
 75  0
     private static Log log = LogFactory.getLog(UIComponentBase.class);
 76  
     
 77  0
     private static final ThreadLocal<StringBuilder> _STRING_BUILDER =
 78  
         new ThreadLocal<StringBuilder>();
 79  
 
 80  0
     private static final Iterator<UIComponent> _EMPTY_UICOMPONENT_ITERATOR = 
 81  
         new _EmptyIterator<UIComponent>();
 82  
     
 83  0
     private _ComponentAttributesMap _attributesMap = null;
 84  0
     private List<UIComponent> _childrenList = null;
 85  0
     private Map<String,UIComponent> _facetMap = null;
 86  0
     private List<FacesListener> _facesListeners = null;
 87  0
     private String _clientId = null;
 88  0
     private String _id = null;
 89  0
     private UIComponent _parent = null;
 90  0
     private boolean _transient = false;
 91  
 
 92  
     private transient FacesContext _facesContext;
 93  
     
 94  
     public UIComponentBase()
 95  0
     {
 96  0
     }
 97  
     
 98  
     /**
 99  
      * Get a map through which all the UIComponent's properties, value-bindings
 100  
      * and non-property attributes can be read and written.
 101  
      * <p>
 102  
      * When writing to the returned map:
 103  
      * <ul>
 104  
      * <li>If this component has an explicit property for the specified key
 105  
      *  then the setter method is called. An IllegalArgumentException is
 106  
      *  thrown if the property is read-only. If the property is readable
 107  
      *  then the old value is returned, otherwise null is returned.
 108  
      * <li>Otherwise the key/value pair is stored in a map associated with
 109  
      * the component.
 110  
      * </ul>
 111  
      * Note that value-bindings are <i>not</i> written by put calls to this map.
 112  
      * Writing to the attributes map using a key for which a value-binding 
 113  
      * exists will just store the value in the attributes map rather than
 114  
      * evaluating the binding, effectively "hiding" the value-binding from
 115  
      * later attributes.get calls. Setter methods on components commonly do
 116  
      * <i>not</i> evaluate a binding of the same name; they just store the
 117  
      * provided value directly on the component.
 118  
      * <p>
 119  
      * When reading from the returned map:
 120  
      * <ul>
 121  
      * <li>If this component has an explicit property for the specified key
 122  
      *  then the getter method is called. If the property exists, but is
 123  
      *  read-only (ie only a setter method is defined) then an
 124  
      *  IllegalArgumentException is thrown.
 125  
      * <li>If the attribute map associated with the component has an entry
 126  
      *  with the specified key, then that is returned.
 127  
      * <li>If this component has a value-binding for the specified key, then
 128  
      * the value-binding is evaluated to fetch the value.
 129  
      * <li>Otherwise, null is returned.
 130  
      * </ul>
 131  
      * Note that components commonly define getter methods such that they
 132  
      * evaluate a value-binding of the same name if there isn't yet a
 133  
      * local property.
 134  
      * <p>
 135  
      * Assigning values to the map which are not explicit properties on
 136  
      * the underlying component can be used to "tunnel" attributes from
 137  
      * the JSP tag (or view-specific equivalent) to the associated renderer
 138  
      * without modifying the component itself.
 139  
      * <p>
 140  
      * Any value-bindings and non-property attributes stored in this map
 141  
      * are automatically serialized along with the component when the view
 142  
      * is serialized.
 143  
      */
 144  
     public Map<String, Object> getAttributes()
 145  
     {
 146  0
         if (_attributesMap == null)
 147  
         {
 148  0
             _attributesMap = new _ComponentAttributesMap(this);
 149  
         }
 150  0
         return _attributesMap;
 151  
     }
 152  
 
 153  
     /**
 154  
      * Get the named value-binding associated with this component.
 155  
      * <p>
 156  
      * Value-bindings are stored in a map associated with the component,
 157  
      * though there is commonly a property (setter/getter methods) 
 158  
      * of the same name defined on the component itself which
 159  
      * evaluates the value-binding when called.
 160  
      *
 161  
      * @deprecated Replaced by getValueExpression
 162  
      */
 163  
     public ValueBinding getValueBinding(String name)
 164  
     {
 165  0
         ValueExpression expression = getValueExpression(name);
 166  0
         if (expression != null)
 167  
         {
 168  0
             if (expression instanceof _ValueBindingToValueExpression)
 169  
             {
 170  0
                 return ((_ValueBindingToValueExpression) expression).getValueBinding();
 171  
             }
 172  0
             return new _ValueExpressionToValueBinding(expression);
 173  
         }
 174  0
         return null;
 175  
     }
 176  
 
 177  
     /**
 178  
      * Put the provided value-binding into a map of value-bindings
 179  
      * associated with this component.
 180  
      *
 181  
      * @deprecated Replaced by setValueExpression
 182  
      */
 183  
     public void setValueBinding(String name,
 184  
                                 ValueBinding binding)
 185  
     {
 186  0
         setValueExpression(name, binding == null ? null : new _ValueBindingToValueExpression(binding));
 187  0
     }
 188  
 
 189  
     /**
 190  
      * Get a string which can be output to the response which uniquely
 191  
      * identifies this UIComponent within the current view.
 192  
      * <p>
 193  
      * The component should have an id attribute already assigned to it;
 194  
      * however if the id property is currently null then a unique id
 195  
      * is generated and set for this component. This only happens when
 196  
      * components are programmatically created without ids, as components
 197  
      * created by a ViewHandler should be assigned ids when they are created.
 198  
      * <p>
 199  
      * If this component is a descendant of a NamingContainer then the
 200  
      * client id is of form "{namingContainerId}:{componentId}". Note that
 201  
      * the naming container's id may itself be of compound form if it has
 202  
      * an ancestor naming container. Note also that this only applies to
 203  
      * naming containers; other UIComponent types in the component's
 204  
      * ancestry do not affect the clientId.
 205  
      * <p>
 206  
      * Finally the renderer associated with this component is asked to
 207  
      * convert the id into a suitable form. This allows escaping of any
 208  
      * characters in the clientId which are significant for the markup
 209  
      * language generated by that renderer.
 210  
      */
 211  
     public String getClientId(FacesContext context)
 212  
     {
 213  0
         if (context == null) throw new NullPointerException("context");
 214  
 
 215  0
         if (_clientId != null) return _clientId;
 216  
 
 217  0
         boolean idWasNull = false;
 218  0
         String id = getId();
 219  0
         if (id == null)
 220  
         {
 221  
             //Although this is an error prone side effect, we automatically create a new id
 222  
             //just to be compatible to the RI
 223  0
             UIViewRoot viewRoot = context.getViewRoot();
 224  0
             if (viewRoot != null)
 225  
             {
 226  0
                 id = viewRoot.createUniqueId();
 227  
             }
 228  
             else
 229  
             {
 230  
                 // The RI throws a NPE
 231  0
                 throw new FacesException(
 232  
                         "Cannot create clientId. No id is assigned for component to create an id and UIViewRoot is not defined: "
 233  
                                 + getPathToComponent(this));
 234  
             }
 235  0
             setId(id);
 236  
             //We remember that the id was null and log a warning down below
 237  0
             idWasNull = true;
 238  
         }
 239  
 
 240  0
         UIComponent namingContainer = _ComponentUtils.findParentNamingContainer(this, false);
 241  0
         if (namingContainer != null)
 242  
         {
 243  0
             String containerClientId = namingContainer.getContainerClientId(context); 
 244  0
             if (containerClientId != null )
 245  
             {
 246  0
                 StringBuilder bld = __getSharedStringBuilder();
 247  0
                 _clientId = bld.append(containerClientId).append(NamingContainer.SEPARATOR_CHAR).append(id).toString();
 248  0
             }
 249  
             else
 250  
             {
 251  0
                 _clientId = id;
 252  
             }
 253  0
         }
 254  
         else
 255  
         {
 256  0
             _clientId = id;
 257  
         }
 258  
 
 259  0
         Renderer renderer = getRenderer(context);
 260  0
         if (renderer != null)
 261  
         {
 262  0
             _clientId = renderer.convertClientId(context, _clientId);
 263  
         }
 264  
 
 265  0
         if (idWasNull && log.isWarnEnabled())
 266  
         {            
 267  0
             log.warn("WARNING: Component " + _clientId
 268  
                     + " just got an automatic id, because there was no id assigned yet. "
 269  
                     + "If this component was created dynamically (i.e. not by a JSP tag) you should assign it an "
 270  
                     + "explicit static id or assign it the id you get from "
 271  
                     + "the createUniqueId from the current UIViewRoot "
 272  
                     + "component right after creation! Path to Component: " + getPathToComponent(this));
 273  
         }
 274  
 
 275  0
         return _clientId;
 276  
     }
 277  
 
 278  
     /**
 279  
      * Get a string which uniquely identifies this UIComponent within the scope of the nearest ancestor NamingContainer
 280  
      * component. The id is not necessarily unique across all components in the current view.
 281  
      */
 282  
     @JSFProperty
 283  
       (rtexprvalue = true)
 284  
     public String getId()
 285  
     {
 286  0
         return _id;
 287  
     }
 288  
     
 289  
     
 290  
     /**
 291  
      * <code>invokeOnComponent</code> must be implemented in <code>UIComponentBase</code> too...
 292  
      */
 293  
     public boolean invokeOnComponent(FacesContext context, String clientId, ContextCallback callback) throws FacesException{
 294  0
         if (isCachedFacesContext())
 295  
         {
 296  0
             return super.invokeOnComponent(context, clientId, callback);
 297  
         }
 298  
         else
 299  
         {
 300  
             try
 301  
             {
 302  0
                 setCachedFacesContext(context);
 303  0
                 return super.invokeOnComponent(context, clientId, callback);
 304  
             }
 305  
             finally
 306  
             {
 307  0
                 setCachedFacesContext(null);
 308  
             }
 309  
         }
 310  
     }
 311  
 
 312  
     /**
 313  
      * Set an identifier for this component which is unique within the
 314  
      * scope of the nearest ancestor NamingContainer component. The id is
 315  
      * not necessarily unique across all components in the current view.
 316  
      * <p>
 317  
      * The id must start with an underscore if it is generated by the JSF
 318  
      * framework, and must <i>not</i> start with an underscore if it has
 319  
      * been specified by the user (eg in a JSP tag).
 320  
      * <p>
 321  
      * The first character of the id must be an underscore or letter.
 322  
      * Following characters may be letters, digits, underscores or dashes.
 323  
      * <p>
 324  
      * Null is allowed as a parameter, and will reset the id to null.
 325  
      * <p>
 326  
      * The clientId of this component is reset by this method; see
 327  
      * getClientId for more info.
 328  
      *  
 329  
      * @throws IllegalArgumentException if the id is not valid.
 330  
      */
 331  
     public void setId(String id)
 332  
     {
 333  0
         isIdValid(id);
 334  0
         _id = id;
 335  0
         _clientId = null;
 336  0
     }
 337  
 
 338  
     public UIComponent getParent()
 339  
     {
 340  0
         return _parent;
 341  
     }
 342  
 
 343  
     public void setParent(UIComponent parent)
 344  
     {
 345  0
         _parent = parent;
 346  0
     }
 347  
 
 348  
     /**
 349  
      * Indicates whether this component or its renderer manages the
 350  
      * invocation of the rendering methods of its child components.
 351  
      * When this is true:
 352  
      * <ul>
 353  
      * <li>This component's encodeBegin method will only be called
 354  
      * after all the child components have been created and added
 355  
      * to this component.
 356  
      * <li>This component's encodeChildren method will be called
 357  
      * after its encodeBegin method. Components for which this
 358  
      * method returns false do not get this method invoked at all.
 359  
      * <li>No rendering methods will be called automatically on
 360  
      * child components; this component is required to invoke the
 361  
      * encodeBegin/encodeEnd/etc on them itself.
 362  
      * </ul>
 363  
      */
 364  
     public boolean getRendersChildren()
 365  
     {
 366  0
         Renderer renderer = getRenderer(getFacesContext());
 367  0
         return renderer != null ? renderer.getRendersChildren() : false;
 368  
     }
 369  
 
 370  
     /**
 371  
      * Return a list of the UIComponent objects which are direct children
 372  
      * of this component.
 373  
      * <p>
 374  
      * The list object returned has some non-standard behaviour:
 375  
      * <ul>
 376  
      * <li>The list is type-checked; only UIComponent objects can be added.
 377  
      * <li>If a component is added to the list with an id which is the same
 378  
      * as some other component in the list then an exception is thrown. However
 379  
      * multiple components with a null id may be added.
 380  
      * <li>The component's parent property is set to this component. If the
 381  
      * component already had a parent, then the component is first removed
 382  
      * from its original parent's child list.
 383  
      * </ul>
 384  
      */
 385  
     public List<UIComponent> getChildren()
 386  
     {
 387  0
         if (_childrenList == null)
 388  
         {
 389  0
             _childrenList = new _ComponentChildrenList(this);
 390  
         }
 391  0
         return _childrenList;
 392  
     }
 393  
 
 394  
     /**
 395  
      * Return the number of direct child components this component has.
 396  
      * <p>
 397  
      * Identical to getChildren().size() except that when this component
 398  
      * has no children this method will not force an empty list to be
 399  
      * created.
 400  
      */
 401  
     public int getChildCount()
 402  
     {
 403  0
         return _childrenList == null ? 0 : _childrenList.size();
 404  
     }
 405  
 
 406  
     /**
 407  
      * Standard method for finding other components by id, inherited by
 408  
      * most UIComponent objects.
 409  
      * <p>
 410  
      * The lookup is performed in a manner similar to finding a file
 411  
      * in a filesystem; there is a "base" at which to start, and the
 412  
      * id can be for something in the "local directory", or can include
 413  
      * a relative path. Here, NamingContainer components fill the role
 414  
      * of directories, and ":" is the "path separator". Note, however,
 415  
      * that although components have a strict parent/child hierarchy,
 416  
      * component ids are only prefixed ("namespaced") with the id of
 417  
      * their parent when the parent is a NamingContainer.
 418  
      * <p>
 419  
      * The base node at which the search starts is determined as
 420  
      * follows:
 421  
      * <ul>
 422  
      * <li>When expr starts with ':', the search starts with the root
 423  
      * component of the tree that this component is in (ie the ancestor
 424  
      * whose parent is null).
 425  
      * <li>Otherwise, if this component is a NamingContainer then the search
 426  
      * starts with this component.
 427  
      * <li>Otherwise, the search starts from the nearest ancestor 
 428  
      * NamingContainer (or the root component if there is no NamingContainer
 429  
      * ancestor).
 430  
      * </ul>
 431  
      * 
 432  
      * @param expr is of form "id1:id2:id3".
 433  
      * @return UIComponent or null if no component with the specified id is
 434  
      * found.
 435  
      */
 436  
 
 437  
     public UIComponent findComponent(String expr)
 438  
     {
 439  0
         if (expr == null) 
 440  0
             throw new NullPointerException("expr");
 441  0
         if (expr.length() == 0) 
 442  0
             return null;
 443  
 
 444  
         UIComponent findBase;
 445  0
         if (expr.charAt(0) == NamingContainer.SEPARATOR_CHAR)
 446  
         {
 447  0
             findBase = _ComponentUtils.getRootComponent(this);
 448  0
             expr = expr.substring(1);
 449  
         }
 450  
         else
 451  
         {
 452  0
             if (this instanceof NamingContainer)
 453  
             {
 454  0
                 findBase = this;
 455  
             }
 456  
             else
 457  
             {
 458  0
                 findBase = _ComponentUtils.findParentNamingContainer(this, true /* root if not found */);
 459  
             }
 460  
         }
 461  
 
 462  0
         int separator = expr.indexOf(NamingContainer.SEPARATOR_CHAR);
 463  0
         if (separator == -1)
 464  
         {
 465  0
             return _ComponentUtils.findComponent(findBase, expr);
 466  
         }
 467  
 
 468  0
         String id = expr.substring(0, separator);
 469  0
         findBase = _ComponentUtils.findComponent(findBase, id);
 470  0
         if (findBase == null)
 471  
         {
 472  0
             return null;
 473  
         }
 474  
         
 475  0
         if (!(findBase instanceof NamingContainer))
 476  0
                     throw new IllegalArgumentException("Intermediate identifier " + id + " in search expression " +
 477  
                         expr + " identifies a UIComponent that is not a NamingContainer");
 478  
         
 479  0
         return findBase.findComponent(expr.substring(separator + 1));
 480  
         
 481  
     }
 482  
 
 483  
 
 484  
     public Map<String, UIComponent> getFacets()
 485  
     {
 486  0
         if (_facetMap == null)
 487  
         {
 488  0
             _facetMap = new _ComponentFacetMap<UIComponent>(this);
 489  
         }
 490  0
         return _facetMap;
 491  
     }
 492  
 
 493  
     public UIComponent getFacet(String name)
 494  
     {
 495  0
         return _facetMap == null ? null : _facetMap.get(name);
 496  
     }
 497  
 
 498  
     public Iterator<UIComponent> getFacetsAndChildren()
 499  
     {
 500  
         // we can't use _facetMap and _childrenList here directly,
 501  
         // because some component implementation could keep their 
 502  
         // own properties for facets and children and just override
 503  
         // getFacets() and getChildren() (e.g. seen in PrimeFaces).
 504  
         // See MYFACES-2611 for details.
 505  0
         if (getFacetCount() == 0)
 506  
         {
 507  0
             if (getChildCount() == 0)
 508  0
                 return _EMPTY_UICOMPONENT_ITERATOR;
 509  
 
 510  0
             return getChildren().iterator();
 511  
         }
 512  
         else
 513  
         {
 514  0
             if (getChildCount() == 0)
 515  0
                 return getFacets().values().iterator();
 516  
 
 517  0
             return new _FacetsAndChildrenIterator(getFacets(), getChildren());
 518  
         }
 519  
     }
 520  
 
 521  
     /**
 522  
      * Invoke any listeners attached to this object which are listening
 523  
      * for an event whose type matches the specified event's runtime
 524  
      * type.
 525  
      * <p>
 526  
      * This method does not propagate the event up to parent components,
 527  
      * ie listeners attached to parent components don't automatically
 528  
      * get called.
 529  
      * <p>
 530  
      * If any of the listeners throws AbortProcessingException then
 531  
      * that exception will prevent any further listener callbacks
 532  
      * from occurring, and the exception propagates out of this
 533  
      * method without alteration.
 534  
      * <p>
 535  
      * ActionEvent events are typically queued by the renderer associated
 536  
      * with this component in its decode method; ValueChangeEvent events by
 537  
      * the component's validate method. In either case the event's source
 538  
      * property references a component. At some later time the UIViewRoot
 539  
      * component iterates over its queued events and invokes the broadcast
 540  
      * method on each event's source object.
 541  
      * 
 542  
      * @param event must not be null.
 543  
      */
 544  
     public void broadcast(FacesEvent event)
 545  
             throws AbortProcessingException
 546  
     {
 547  0
         if (event == null) throw new NullPointerException("event");
 548  
         try {
 549  
 
 550  0
             if (_facesListeners == null) return;
 551  0
             for (Iterator<FacesListener> it = _facesListeners.iterator(); it.hasNext(); )
 552  
             {
 553  0
                 FacesListener facesListener = it.next();
 554  0
                 if (event.isAppropriateListener(facesListener))
 555  
                 {
 556  0
                     event.processListener(facesListener);
 557  
                 }
 558  0
             }
 559  
         }
 560  0
         catch(Exception ex) {
 561  0
             if (ex instanceof AbortProcessingException) {
 562  0
                 throw (AbortProcessingException) ex;
 563  
             }
 564  0
             throw new FacesException("Exception while calling broadcast on component : "+getPathToComponent(this), ex);
 565  0
         }
 566  0
     }
 567  
 
 568  
     /**
 569  
      * Check the submitted form parameters for data associated with this
 570  
      * component. This default implementation delegates to this component's
 571  
      * renderer if there is one, and otherwise ignores the call.
 572  
      */
 573  
     public void decode(FacesContext context)
 574  
     {
 575  0
         if (context == null) throw new NullPointerException("context");
 576  
         try
 577  
         {
 578  0
             Renderer renderer = getRenderer(context);
 579  0
             if (renderer != null)
 580  
             {
 581  0
                 renderer.decode(context, this);
 582  
             }
 583  
         }
 584  0
         catch(Exception ex) {
 585  0
             throw new FacesException("Exception while decoding component : "+getPathToComponent(this), ex);
 586  0
         }
 587  0
     }
 588  
 
 589  
     public void encodeBegin(FacesContext context)
 590  
             throws IOException
 591  
     {
 592  0
         if (context == null) throw new NullPointerException("context");
 593  
         try {
 594  0
             setCachedFacesContext(context);
 595  
             
 596  0
             if (!isRendered()) return;
 597  0
             Renderer renderer = getRenderer(context);
 598  0
             if (renderer != null)
 599  
             {
 600  0
                 renderer.encodeBegin(context, this);
 601  
             }
 602  0
         } catch (Exception ex) {
 603  0
             throw new FacesException("Exception while calling encodeBegin on component : "+getPathToComponent(this), ex);
 604  
         }
 605  
         finally
 606  
         {
 607  0
             setCachedFacesContext(null);
 608  0
         }
 609  0
     }
 610  
 
 611  
     public void encodeChildren(FacesContext context)
 612  
             throws IOException
 613  
     {
 614  0
         if (context == null) throw new NullPointerException("context");
 615  
         
 616  0
         boolean isCachedFacesContext = isCachedFacesContext();
 617  
         try
 618  
         {
 619  0
             if (!isCachedFacesContext)
 620  
             {
 621  0
                 setCachedFacesContext(context);
 622  
             }
 623  0
             if (!isRendered()) return;
 624  0
             Renderer renderer = getRenderer(context);
 625  0
             if (renderer != null)
 626  
             {
 627  0
                 renderer.encodeChildren(context, this);
 628  
             }
 629  
         }
 630  
         finally
 631  
         {
 632  0
             if (!isCachedFacesContext)
 633  
             {
 634  0
                 setCachedFacesContext(null);
 635  
             }
 636  
         }
 637  0
     }
 638  
 
 639  
     public void encodeEnd(FacesContext context)
 640  
             throws IOException
 641  
     {
 642  0
         if (context == null) throw new NullPointerException("context");
 643  
         try {
 644  0
             setCachedFacesContext(context);
 645  0
             if (!isRendered()) return;
 646  0
             Renderer renderer = getRenderer(context);
 647  0
             if (renderer != null)
 648  
             {
 649  0
                 renderer.encodeEnd(context, this);
 650  
             }
 651  0
         } catch (Exception ex) {
 652  0
             throw new FacesException("Exception while calling encodeEnd on component : "+getPathToComponent(this), ex);
 653  
         }
 654  
         finally
 655  
         {
 656  0
             setCachedFacesContext(null);
 657  0
         }
 658  0
     }
 659  
 
 660  
     protected void addFacesListener(FacesListener listener)
 661  
     {
 662  0
         if (listener == null) throw new NullPointerException("listener");
 663  0
         if (_facesListeners == null)
 664  
         {
 665  0
             _facesListeners = new ArrayList<FacesListener>();
 666  
         }
 667  0
         _facesListeners.add(listener);
 668  0
     }
 669  
 
 670  
     protected FacesListener[] getFacesListeners(Class clazz)
 671  
     {
 672  0
         if(clazz == null)
 673  
         {
 674  0
             throw new NullPointerException("Class is null");
 675  
         }
 676  0
         if(!FacesListener.class.isAssignableFrom(clazz))
 677  
         {
 678  0
             throw new IllegalArgumentException("Class " + clazz.getName() + " must implement " + FacesListener.class);
 679  
         }
 680  
         
 681  0
         if (_facesListeners == null)
 682  
         {
 683  0
             return (FacesListener[])Array.newInstance(clazz, 0);
 684  
         }
 685  0
         List<FacesListener> lst = null;
 686  0
         for (Iterator<FacesListener> it = _facesListeners.iterator(); it.hasNext();)
 687  
         {
 688  0
             FacesListener facesListener = it.next();
 689  0
             if (clazz.isAssignableFrom(facesListener.getClass()))
 690  
             {
 691  0
                 if (lst == null)
 692  0
                     lst = new ArrayList<FacesListener>();
 693  0
                 lst.add(facesListener);
 694  
             }
 695  0
         }
 696  0
         if (lst == null)
 697  
         {
 698  0
             return (FacesListener[]) Array.newInstance(clazz, 0);
 699  
         }
 700  
         
 701  0
         return lst.toArray((FacesListener[])Array.newInstance(clazz, lst.size()));
 702  
     }
 703  
 
 704  
     protected void removeFacesListener(FacesListener listener)
 705  
     {
 706  0
         if(listener == null)
 707  
         {
 708  0
             throw new NullPointerException("listener is null");
 709  
         }
 710  
         
 711  0
         if (_facesListeners != null)
 712  
         {
 713  0
             _facesListeners.remove(listener);
 714  
         }
 715  0
     }
 716  
 
 717  
     public void queueEvent(FacesEvent event)
 718  
     {
 719  0
         if (event == null) throw new NullPointerException("event");
 720  0
         UIComponent parent = getParent();
 721  0
         if (parent == null)
 722  
         {
 723  0
             throw new IllegalStateException("component is not a descendant of a UIViewRoot");
 724  
         }
 725  0
         parent.queueEvent(event);
 726  0
     }
 727  
 
 728  
     public void processDecodes(FacesContext context)
 729  
     {
 730  0
         if (context == null)
 731  0
             throw new NullPointerException("context");
 732  
         
 733  
         try
 734  
         {
 735  0
             setCachedFacesContext(context);
 736  
             
 737  0
             if (!isRendered()) return;
 738  
             
 739  0
             for (Iterator<UIComponent> it = getFacetsAndChildren(); it.hasNext();)
 740  
             {
 741  0
                 it.next().processDecodes(context);
 742  
             }
 743  
             try
 744  
             {
 745  0
                 decode(context);
 746  
             }
 747  0
             catch (RuntimeException e)
 748  
             {
 749  0
                 context.renderResponse();
 750  0
                 throw e;
 751  0
             }
 752  
         }
 753  
         finally
 754  
         {
 755  0
             setCachedFacesContext(null);
 756  0
         }
 757  0
     }
 758  
 
 759  
 
 760  
     public void processValidators(FacesContext context)
 761  
     {
 762  0
         if (context == null) throw new NullPointerException("context");
 763  
         try
 764  
         {
 765  0
             setCachedFacesContext(context);
 766  0
             if (!isRendered()) return;
 767  
     
 768  0
             for (Iterator<UIComponent> it = getFacetsAndChildren(); it.hasNext(); )
 769  
             {
 770  0
                 it.next().processValidators(context);
 771  
             }
 772  
         }
 773  
         finally
 774  
         {
 775  0
             setCachedFacesContext(null);
 776  0
         }
 777  0
     }
 778  
 
 779  
     /**
 780  
      * This isn't an input component, so just pass on the processUpdates
 781  
      * call to child components and facets that might be input components.
 782  
      * <p>
 783  
      * Components that were never rendered can't possibly be receiving
 784  
      * update data (no corresponding fields were ever put into the response)
 785  
      * so if this component is not rendered then this method does not
 786  
      * invoke processUpdates on its children.
 787  
      */
 788  
     public void processUpdates(FacesContext context)
 789  
     {
 790  0
         if (context == null) throw new NullPointerException("context");
 791  
         
 792  
         try
 793  
         {
 794  0
             setCachedFacesContext(context);
 795  0
             if (!isRendered()) return;
 796  
     
 797  0
             for (Iterator<UIComponent> it = getFacetsAndChildren(); it.hasNext(); )
 798  
             {
 799  0
                 it.next().processUpdates(context);
 800  
             }
 801  
         }
 802  
         finally
 803  
         {
 804  0
             setCachedFacesContext(null);
 805  0
         }
 806  0
     }
 807  
 
 808  
     public Object processSaveState(FacesContext context)
 809  
     {
 810  0
         if (context == null)
 811  0
             throw new NullPointerException("context");
 812  0
         if (isTransient())
 813  0
             return null;
 814  0
         Map<String, Object> facetMap = null;
 815  0
         int facetCount = getFacetCount();
 816  0
         if (facetCount > 0)
 817  
         {
 818  0
             for (Iterator<Entry<String, UIComponent>> it = getFacets().entrySet().iterator(); it.hasNext();)
 819  
             {
 820  0
                 Entry<String, UIComponent> entry = it.next();
 821  0
                 UIComponent component = entry.getValue();
 822  0
                 if (!component.isTransient())
 823  
                 {
 824  0
                     if (facetMap == null)
 825  0
                         facetMap = new HashMap<String, Object>(facetCount, 1);
 826  0
                     facetMap.put(entry.getKey(), component.processSaveState(context));
 827  
                 }
 828  0
             }
 829  
         }
 830  0
         List<Object> childrenList = null;
 831  0
         int childCount = getChildCount();
 832  0
         if (childCount > 0)
 833  
         {
 834  0
             for (Iterator it = getChildren().iterator(); it.hasNext();)
 835  
             {
 836  0
                 UIComponent child = (UIComponent) it.next();
 837  0
                 if (!child.isTransient())
 838  
                 {
 839  0
                     if (childrenList == null)
 840  
                     {
 841  0
                         childrenList = new ArrayList<Object>(childCount);
 842  
                     }
 843  0
                     Object childState = child.processSaveState(context);
 844  0
                     if (childState != null)
 845  
                     {
 846  0
                         childrenList.add(childState);
 847  
                     }
 848  
                 }
 849  0
             }
 850  
         }
 851  
 
 852  
         Object savedState;
 853  
         try {
 854  0
             savedState = saveState(context);
 855  0
         } catch(Exception ex) {
 856  0
             throw new FacesException("Exception while saving state of component : "+getPathToComponent(this), ex);
 857  0
         }
 858  
 
 859  0
         return new Object[] { savedState, facetMap, childrenList };
 860  
     }
 861  
 
 862  
     public void processRestoreState(FacesContext context,
 863  
                                     Object state)
 864  
     {
 865  0
         if (context == null) throw new NullPointerException("context");
 866  0
         Object[] stateValues = (Object[]) state;
 867  0
         Object myState = stateValues[0];
 868  0
         Map<String, Object> facetMap = (Map<String, Object>)stateValues[1];
 869  0
         List<Object> childrenList = (List<Object>)stateValues[2];
 870  0
         if(facetMap != null && getFacetCount() > 0)
 871  
         {
 872  0
           for (Iterator<Entry<String, UIComponent>> it = getFacets().entrySet().iterator(); it.hasNext(); )
 873  
           {
 874  0
               Entry<String, UIComponent> entry = it.next();
 875  0
               Object facetState = facetMap.get(entry.getKey());
 876  0
               if (facetState != null)
 877  
               {
 878  0
                   entry.getValue().processRestoreState(context, facetState);
 879  
               }
 880  
               else
 881  
               {
 882  0
                   context.getExternalContext().log("No state found to restore facet " + entry.getKey());
 883  
               }
 884  0
           }
 885  
         }
 886  0
         if (childrenList != null && getChildCount() > 0)
 887  
         {
 888  0
             int idx = 0;
 889  0
             for (Iterator<UIComponent> it = getChildren().iterator(); it.hasNext(); )
 890  
             {
 891  0
                 UIComponent child = it.next();
 892  0
                 if(!child.isTransient())
 893  
                 {
 894  0
                   Object childState = childrenList.get(idx++);
 895  0
                   if (childState != null)
 896  
                   {
 897  0
                       child.processRestoreState(context, childState);
 898  
                   }
 899  
                   else
 900  
                   {
 901  0
                       context.getExternalContext().log("No state found to restore child of component " + getId());
 902  
                   }
 903  
                 }
 904  0
             }
 905  
         }
 906  
         try {
 907  0
             restoreState(context, myState);
 908  0
         } catch(Exception ex) {
 909  0
             throw new FacesException("Exception while restoring state of component : "+getPathToComponent(this), ex);
 910  0
         }
 911  0
     }
 912  
 
 913  
     protected FacesContext getFacesContext()
 914  
     {
 915  0
         if (_facesContext == null)
 916  
         {
 917  0
             return FacesContext.getCurrentInstance();
 918  
         }
 919  
         else
 920  
         {
 921  0
             return _facesContext;
 922  
         }
 923  
     }
 924  
 
 925  
     protected Renderer getRenderer(FacesContext context)
 926  
     {
 927  0
         if (context == null) throw new NullPointerException("context");
 928  0
         String rendererType = getRendererType();
 929  0
         if (rendererType == null) return null;
 930  
         
 931  0
         RenderKit renderKit = context.getRenderKit();
 932  0
         Renderer renderer = renderKit.getRenderer(getFamily(), rendererType);
 933  0
         if (renderer == null)
 934  
         {
 935  0
             getFacesContext().getExternalContext().log("No Renderer found for component " + getPathToComponent(this) + " (component-family=" + getFamily() + ", renderer-type=" + rendererType + ")");
 936  0
             log.warn("No Renderer found for component " + getPathToComponent(this) + " (component-family=" + getFamily() + ", renderer-type=" + rendererType + ")");
 937  
         }
 938  0
         return renderer;
 939  
     }
 940  
 
 941  
     private String getPathToComponent(UIComponent component)
 942  
     {
 943  0
         StringBuffer buf = new StringBuffer();
 944  
 
 945  0
         if(component == null)
 946  
         {
 947  0
             buf.append("{Component-Path : ");
 948  0
             buf.append("[null]}");
 949  0
             return buf.toString();
 950  
         }
 951  
 
 952  0
         getPathToComponent(component,buf);
 953  
 
 954  0
         buf.insert(0,"{Component-Path : ");
 955  0
         buf.append("}");
 956  
 
 957  0
         return buf.toString();
 958  
     }
 959  
 
 960  
     private void getPathToComponent(UIComponent component, StringBuffer buf)
 961  
     {
 962  0
         if(component == null)
 963  0
             return;
 964  
 
 965  0
         StringBuffer intBuf = new StringBuffer();
 966  
 
 967  0
         intBuf.append("[Class: ");
 968  0
         intBuf.append(component.getClass().getName());
 969  0
         if(component instanceof UIViewRoot)
 970  
         {
 971  0
             intBuf.append(",ViewId: ");
 972  0
             intBuf.append(((UIViewRoot) component).getViewId());
 973  
         }
 974  
         else
 975  
         {
 976  0
             intBuf.append(",Id: ");
 977  0
             intBuf.append(component.getId());
 978  
         }
 979  0
         intBuf.append("]");
 980  
 
 981  0
         buf.insert(0,intBuf.toString());
 982  
 
 983  0
         getPathToComponent(component.getParent(), buf);
 984  0
     }
 985  
 
 986  
     @JSFProperty(
 987  
        literalOnly = true,
 988  
        istransient = true,
 989  
        tagExcluded = true)
 990  
     public boolean isTransient()
 991  
     {
 992  0
         return _transient;
 993  
     }
 994  
 
 995  
     public void setTransient(boolean transientFlag)
 996  
     {
 997  0
         _transient = transientFlag;
 998  0
     }
 999  
 
 1000  
     /**
 1001  
      * Serializes objects which are "attached" to this component but which are
 1002  
      * not UIComponent children of it. Examples are validator and listener
 1003  
      * objects. To be precise, it returns an object which implements
 1004  
      * java.io.Serializable, and which when serialized will persist the
 1005  
      * state of the provided object.     
 1006  
      * <p>
 1007  
      * If the attachedObject is a List then every object in the list is saved
 1008  
      * via a call to this method, and the returned wrapper object contains
 1009  
      * a List object.
 1010  
      * <p>
 1011  
      * If the object implements StateHolder then the object's saveState is
 1012  
      * called immediately, and a wrapper is returned which contains both
 1013  
      * this saved state and the original class name. However in the case
 1014  
      * where the StateHolder.isTransient method returns true, null is
 1015  
      * returned instead.
 1016  
      * <p>
 1017  
      * If the object implements java.io.Serializable then the object is simply
 1018  
      * returned immediately; standard java serialization will later be used
 1019  
      * to store this object.
 1020  
      * <p>
 1021  
      * In all other cases, a wrapper is returned which simply stores the type
 1022  
      * of the provided object. When deserialized, a default instance of that
 1023  
      * type will be recreated.
 1024  
      */
 1025  
     public static Object saveAttachedState(FacesContext context,
 1026  
                                            Object attachedObject)
 1027  
     {
 1028  0
         if (attachedObject == null) return null;
 1029  0
         if (attachedObject instanceof List)
 1030  
         {
 1031  0
             List<Object> lst = new ArrayList<Object>(((List)attachedObject).size());
 1032  0
             for (Iterator it = ((List)attachedObject).iterator(); it.hasNext(); )
 1033  
             {
 1034  0
                 Object value = it.next();
 1035  0
                 if (value != null)
 1036  
                 {
 1037  0
                     lst.add(saveAttachedState(context, value));
 1038  
                 }
 1039  0
             }
 1040  0
             return new _AttachedListStateWrapper(lst);
 1041  
         }
 1042  0
         else if (attachedObject instanceof StateHolder)
 1043  
         {
 1044  0
             if (((StateHolder)attachedObject).isTransient())
 1045  
             {
 1046  0
                 return null;
 1047  
             }
 1048  
             
 1049  0
             return new _AttachedStateWrapper(attachedObject.getClass(),
 1050  
                                                  ((StateHolder)attachedObject).saveState(context));
 1051  
         }
 1052  0
         else if (attachedObject instanceof Serializable)
 1053  
         {
 1054  0
             return attachedObject;
 1055  
         }
 1056  
         else
 1057  
         {
 1058  0
             return new _AttachedStateWrapper(attachedObject.getClass(), null);
 1059  
         }
 1060  
     }
 1061  
 
 1062  
     public static Object restoreAttachedState(FacesContext context,
 1063  
                                               Object stateObj)
 1064  
             throws IllegalStateException
 1065  
     {
 1066  0
         if (context == null) throw new NullPointerException("context");
 1067  0
         if (stateObj == null) return null;
 1068  0
         if (stateObj instanceof _AttachedListStateWrapper)
 1069  
         {
 1070  0
             List<Object> lst = ((_AttachedListStateWrapper)stateObj).getWrappedStateList();
 1071  0
             List<Object> restoredList = new ArrayList<Object>(lst.size());
 1072  0
             for (Iterator<Object> it = lst.iterator(); it.hasNext(); )
 1073  
             {
 1074  0
                 restoredList.add(restoreAttachedState(context, it.next()));
 1075  
             }
 1076  0
             return restoredList;
 1077  
         }
 1078  0
         else if (stateObj instanceof _AttachedStateWrapper)
 1079  
         {
 1080  0
             Class clazz = ((_AttachedStateWrapper)stateObj).getClazz();
 1081  
             Object restoredObject;
 1082  
             try
 1083  
             {
 1084  0
                 restoredObject = clazz.newInstance();
 1085  
             }
 1086  0
             catch (InstantiationException e)
 1087  
             {
 1088  0
                 throw new RuntimeException("Could not restore StateHolder of type " + clazz.getName() + " (missing no-args constructor?)", e);
 1089  
             }
 1090  0
             catch (IllegalAccessException e)
 1091  
             {
 1092  0
                 throw new RuntimeException(e);
 1093  0
             }
 1094  0
             if (restoredObject instanceof StateHolder)
 1095  
             {
 1096  0
                 Object wrappedState = ((_AttachedStateWrapper)stateObj).getWrappedStateObject();
 1097  0
                 ((StateHolder)restoredObject).restoreState(context, wrappedState);
 1098  
             }
 1099  0
             return restoredObject;
 1100  
         }
 1101  
         else
 1102  
         {
 1103  0
             return stateObj;
 1104  
         }
 1105  
     }
 1106  
 
 1107  
 
 1108  
     /**
 1109  
      * Invoked after the render phase has completed, this method
 1110  
      * returns an object which can be passed to the restoreState
 1111  
      * of some other instance of UIComponentBase to reset that
 1112  
      * object's state to the same values as this object currently
 1113  
      * has.
 1114  
      */
 1115  
     public Object saveState(FacesContext context)
 1116  
     {
 1117  0
         Object values[] = new Object[7];
 1118  0
         values[0] = _id;
 1119  0
         values[1] = _rendered;
 1120  0
         values[2] = _rendererType;
 1121  0
         values[3] = _clientId;
 1122  0
         values[4] = saveAttributesMap();
 1123  0
         values[5] = saveAttachedState(context, _facesListeners);
 1124  0
         values[6] = saveBindings(context);
 1125  0
         return values;
 1126  
     }
 1127  
 
 1128  
     /**
 1129  
      * Invoked in the "restore view" phase, this initialises this
 1130  
      * object's members from the values saved previously into the
 1131  
      * provided state object.
 1132  
      * <p>
 1133  
      * @param state is an object previously returned by
 1134  
      * the saveState method of this class.
 1135  
      */
 1136  
     public void restoreState(FacesContext context, Object state)
 1137  
     {
 1138  0
         Object values[] = (Object[])state;
 1139  0
         _id = (String)values[0];
 1140  0
         _rendered = (Boolean)values[1];
 1141  0
         _rendererType = (String)values[2];
 1142  0
         _clientId = (String)values[3];
 1143  0
         restoreAttributesMap(values[4]);
 1144  0
         _facesListeners = (List<FacesListener>)restoreAttachedState(context, values[5]);
 1145  0
         restoreValueExpressionMap(context, values[6]);
 1146  0
     }
 1147  
 
 1148  
 
 1149  
     private Object saveAttributesMap()
 1150  
     {
 1151  0
         return _attributesMap != null ? _attributesMap.getUnderlyingMap() : null;
 1152  
     }
 1153  
 
 1154  
     private void restoreAttributesMap(Object stateObj)
 1155  
     {
 1156  0
         if (stateObj != null)
 1157  
         {
 1158  0
             _attributesMap = new _ComponentAttributesMap(this, (Map<Object, Object>)stateObj);
 1159  
         }
 1160  
         else
 1161  
         {
 1162  0
             _attributesMap = null;
 1163  
         }
 1164  0
     }
 1165  
 
 1166  
     private Object saveBindings(FacesContext context)
 1167  
     {
 1168  0
         if (bindings != null)
 1169  
         {
 1170  0
             HashMap<String, Object> stateMap = new HashMap<String, Object>(bindings.size(), 1);
 1171  0
             for (Iterator<Entry<String, ValueExpression>> it = bindings.entrySet().iterator(); it.hasNext(); )
 1172  
             {
 1173  0
                 Entry<String, ValueExpression> entry = it.next();
 1174  0
                 stateMap.put(entry.getKey(),
 1175  
                              saveAttachedState(context, entry.getValue()));
 1176  0
             }
 1177  0
             return stateMap;
 1178  
         }
 1179  
         
 1180  0
         return null;
 1181  
     }
 1182  
 
 1183  
     private void restoreValueExpressionMap(FacesContext context, Object stateObj)
 1184  
     {
 1185  0
         if (stateObj != null)
 1186  
         {
 1187  0
             Map stateMap = (Map)stateObj;
 1188  0
             int initCapacity = (stateMap.size() * 4 + 3) / 3;
 1189  0
             bindings = new HashMap<String, ValueExpression>(initCapacity);
 1190  0
             for (Iterator it = stateMap.entrySet().iterator(); it.hasNext(); )
 1191  
             {
 1192  0
                 Map.Entry entry = (Map.Entry)it.next();
 1193  0
                 bindings.put((String)entry.getKey(),
 1194  
                                      (ValueExpression)restoreAttachedState(context, entry.getValue()));
 1195  0
             }
 1196  0
         }
 1197  
         else
 1198  
         {
 1199  0
             bindings = null;
 1200  
         }
 1201  0
     }
 1202  
 
 1203  
 
 1204  
     /**
 1205  
      * @param string the component id, that should be a vaild one.
 1206  
      */
 1207  
     private void isIdValid(String string)
 1208  
     {
 1209  
 
 1210  
         //is there any component identifier ?
 1211  0
         if(string == null)
 1212  0
             return;
 1213  
 
 1214  
         //Component identifiers must obey the following syntax restrictions:
 1215  
         //1. Must not be a zero-length String.
 1216  0
         if(string.length()==0)
 1217  
         {
 1218  0
             throw new IllegalArgumentException("component identifier must not be a zero-length String");
 1219  
         }
 1220  
 
 1221  
         // If new id is the same as old it must be valid
 1222  0
         if (string.equals(_id)) {
 1223  0
             return;
 1224  
         }
 1225  
         
 1226  
         //2. First character must be a letter or an underscore ('_').
 1227  0
         if(!Character.isLetter(string.charAt(0)) &&  string.charAt(0) !='_')
 1228  
         {
 1229  0
             throw new IllegalArgumentException("component identifier's first character must be a letter or an underscore ('_')! But it is \""+string.charAt(0)+"\"");
 1230  
         }
 1231  0
         for (int i = 1; i < string.length(); i++)
 1232  
         {
 1233  0
             char c = string.charAt(i);
 1234  
             //3. Subsequent characters must be a letter, a digit, an underscore ('_'), or a dash ('-').
 1235  0
             if(!Character.isLetterOrDigit(c) && c !='-' && c !='_')
 1236  
             {
 1237  0
                 throw new IllegalArgumentException("Subsequent characters of component identifier must be a letter, a digit, an underscore ('_'), or a dash ('-')! But component identifier contains \""+c+"\"");
 1238  
             }
 1239  
         }
 1240  0
     }
 1241  
     
 1242  
     <T> T getExpressionValue(String attribute, T explizitValue, T defaultValueIfExpressionNull)
 1243  
     {
 1244  0
         return _ComponentUtils.getExpressionValue(this, attribute, explizitValue, defaultValueIfExpressionNull);
 1245  
     }
 1246  
     
 1247  
     /**
 1248  
      * <p>
 1249  
      * This gets a single threadlocal shared stringbuilder instance, each time you call
 1250  
      * __getSharedStringBuilder it sets the length of the stringBuilder instance to 0.
 1251  
      * </p><p>
 1252  
      * This allows you to use the same StringBuilder instance over and over.
 1253  
      * You must call toString on the instance before calling __getSharedStringBuilder again.
 1254  
      * </p>
 1255  
      * Example that works
 1256  
      * <pre><code>
 1257  
      * StringBuilder sb1 = __getSharedStringBuilder();
 1258  
      * sb1.append(a).append(b);
 1259  
      * String c = sb1.toString();
 1260  
      *
 1261  
      * StringBuilder sb2 = __getSharedStringBuilder();
 1262  
      * sb2.append(b).append(a);
 1263  
      * String d = sb2.toString();
 1264  
      * </code></pre>
 1265  
      * <br><br>
 1266  
      * Example that doesn't work, you must call toString on sb1 before
 1267  
      * calling __getSharedStringBuilder again.
 1268  
      * <pre><code>
 1269  
      * StringBuilder sb1 = __getSharedStringBuilder();
 1270  
      * StringBuilder sb2 = __getSharedStringBuilder();
 1271  
      *
 1272  
      * sb1.append(a).append(b);
 1273  
      * String c = sb1.toString();
 1274  
      *
 1275  
      * sb2.append(b).append(a);
 1276  
      * String d = sb2.toString();
 1277  
      * </code></pre>
 1278  
      *
 1279  
      */
 1280  
     static StringBuilder __getSharedStringBuilder()
 1281  
     {
 1282  0
       StringBuilder sb = _STRING_BUILDER.get();
 1283  
 
 1284  0
       if (sb == null)
 1285  
       {
 1286  0
         sb = new StringBuilder();
 1287  0
         _STRING_BUILDER.set(sb);
 1288  
       }
 1289  
 
 1290  
       // clear out the stringBuilder by setting the length to 0
 1291  0
       sb.setLength(0);
 1292  
 
 1293  0
       return sb;
 1294  
     }
 1295  
 
 1296  
     boolean isCachedFacesContext()
 1297  
     {
 1298  0
         return _facesContext != null;
 1299  
     }
 1300  
     
 1301  
     void setCachedFacesContext(FacesContext facesContext)
 1302  
     {
 1303  0
         _facesContext = facesContext;
 1304  0
     }
 1305  
 
 1306  
     //------------------ GENERATED CODE BEGIN (do not modify!) --------------------
 1307  
 
 1308  
     private static final boolean DEFAULT_RENDERED = true;
 1309  
 
 1310  0
     private Boolean _rendered = null;
 1311  0
     private String _rendererType = null;
 1312  
 
 1313  
 
 1314  
 
 1315  
     public void setRendered(boolean rendered)
 1316  
     {
 1317  0
         _rendered = Boolean.valueOf(rendered);
 1318  0
     }
 1319  
 
 1320  
     /**
 1321  
      * A boolean value that indicates whether this component should be rendered.
 1322  
      * Default value: true.
 1323  
      **/
 1324  
     @JSFProperty
 1325  
     public boolean isRendered()
 1326  
     {
 1327  0
         return getExpressionValue("rendered", _rendered, DEFAULT_RENDERED);
 1328  
     }
 1329  
 
 1330  
     public void setRendererType(String rendererType)
 1331  
     {
 1332  0
         _rendererType = rendererType;
 1333  0
     }
 1334  
 
 1335  
     public String getRendererType()
 1336  
     {
 1337  0
         return getExpressionValue("rendererType", _rendererType, null);
 1338  
     }
 1339  
 
 1340  
 
 1341  
     //------------------ GENERATED CODE END ---------------------------------------
 1342  
     
 1343  
     /**
 1344  
      * @since 1.2
 1345  
      */
 1346  
     
 1347  
     public int getFacetCount()
 1348  
     {
 1349  0
         return _facetMap == null ? 0 : _facetMap.size();
 1350  
     }
 1351  
 }