Coverage Report - javax.faces.component.UIComponent
 
Classes in this File Line Coverage Branch Coverage Complexity
UIComponent
50%
158/315
41%
95/231
3.028
UIComponent$1
100%
1/1
N/A
3.028
UIComponent$BundleMap
0%
0/34
0%
0/12
3.028
UIComponent$BundleMap$1
0%
0/4
N/A
3.028
UIComponent$EventListenerWrapper
75%
79/104
60%
51/84
3.028
UIComponent$PropertyKeys
100%
7/7
N/A
3.028
 
 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 java.io.IOException;
 22  
 import java.util.ArrayList;
 23  
 import java.util.Collection;
 24  
 import java.util.Collections;
 25  
 import java.util.Enumeration;
 26  
 import java.util.HashMap;
 27  
 import java.util.HashSet;
 28  
 import java.util.Iterator;
 29  
 import java.util.List;
 30  
 import java.util.Locale;
 31  
 import java.util.Map;
 32  
 import java.util.MissingResourceException;
 33  
 import java.util.PropertyResourceBundle;
 34  
 import java.util.ResourceBundle;
 35  
 import java.util.Set;
 36  
 
 37  
 import javax.el.ELException;
 38  
 import javax.el.ValueExpression;
 39  
 import javax.faces.FacesException;
 40  
 import javax.faces.application.Resource;
 41  
 import javax.faces.component.visit.VisitCallback;
 42  
 import javax.faces.component.visit.VisitContext;
 43  
 import javax.faces.component.visit.VisitHint;
 44  
 import javax.faces.component.visit.VisitResult;
 45  
 import javax.faces.context.FacesContext;
 46  
 import javax.faces.el.ValueBinding;
 47  
 import javax.faces.event.AbortProcessingException;
 48  
 import javax.faces.event.ComponentSystemEvent;
 49  
 import javax.faces.event.ComponentSystemEventListener;
 50  
 import javax.faces.event.FacesEvent;
 51  
 import javax.faces.event.FacesListener;
 52  
 import javax.faces.event.PostRestoreStateEvent;
 53  
 import javax.faces.event.SystemEvent;
 54  
 import javax.faces.event.SystemEventListener;
 55  
 import javax.faces.event.SystemEventListenerHolder;
 56  
 import javax.faces.render.Renderer;
 57  
 import javax.faces.render.RendererWrapper;
 58  
 
 59  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
 60  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
 61  
 
 62  
 /**
 63  
  *
 64  
  * see Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">J
 65  
  * SF Specification</a>
 66  
  */
 67  
 @JSFComponent(type = "javax.faces.Component", family = "javax.faces.Component",
 68  
               desc = "abstract base component", configExcluded = true)
 69  
 public abstract class UIComponent
 70  
         implements PartialStateHolder, TransientStateHolder, SystemEventListenerHolder, ComponentSystemEventListener
 71  
 {
 72  
     // TODO: Reorder methods, this class is a mess
 73  
     /**
 74  
      * Constant used in component attribute map to retrieve the BeanInfo of a composite
 75  
      * component.
 76  
      *
 77  
      * @see javax.faces.view.ViewDeclarationLanguage#getComponentMetadata(FacesContext, Resource)
 78  
      * @see javax.faces.view.ViewDeclarationLanguage#retargetAttachedObjects(FacesContext, UIComponent, List)
 79  
      * @see javax.faces.view.ViewDeclarationLanguage#retargetMethodExpressions(FacesContext, UIComponent)
 80  
      * @see javax.faces.application.Application#createComponent(FacesContext, Resource)
 81  
      */
 82  
     public static final String BEANINFO_KEY = "javax.faces.component.BEANINFO_KEY";
 83  
 
 84  
     /**
 85  
      * Constant used in BeanInfo descriptor as a key for retrieve an alternate component type
 86  
      * for create the composite base component. 
 87  
      *
 88  
      * @see javax.faces.application.Application#createComponent(FacesContext, Resource)
 89  
      */
 90  
     public static final String COMPOSITE_COMPONENT_TYPE_KEY = "javax.faces.component.COMPOSITE_COMPONENT_TYPE";
 91  
 
 92  
     /**
 93  
      * Constant used to define the facet inside this component that store the component hierarchy
 94  
      * generated by a composite component implementation, and then rendered. In other words, 
 95  
      * note that direct children of a component are not rendered, instead components inside 
 96  
      * this face are rendered.
 97  
      */
 98  
     public static final String COMPOSITE_FACET_NAME = "javax.faces.component.COMPOSITE_FACET_NAME";
 99  
 
 100  
     /**
 101  
      * Constant used to store the current component that is being processed.
 102  
      *
 103  
      * @see #pushComponentToEL(FacesContext, UIComponent)
 104  
      * @see #popComponentFromEL(FacesContext)
 105  
      */
 106  
     public static final String CURRENT_COMPONENT = "javax.faces.component.CURRENT_COMPONENT";
 107  
 
 108  
     /**
 109  
      * Constant used to store the current composite component that is being processed. 
 110  
      *
 111  
      * @see #pushComponentToEL(FacesContext, UIComponent)
 112  
      * @see #popComponentFromEL(FacesContext)
 113  
      */
 114  
     public static final String CURRENT_COMPOSITE_COMPONENT = "javax.faces.component.CURRENT_COMPOSITE_COMPONENT";
 115  
 
 116  
     /**
 117  
      * This constant has two usages. The first one is in component attribute map to identify the 
 118  
      * facet name under this component is child of its parent. The second one is on BeanInfo descriptor
 119  
      * as a key for a Map&lt;String, PropertyDescriptor&gt; that contains metadata information defined
 120  
      * by composite:facet tag and composite:implementation(because this one fills the facet referenced
 121  
      * by COMPOSITE_FACET_NAME constant). 
 122  
      */
 123  
     public static final String FACETS_KEY = "javax.faces.component.FACETS_KEY";
 124  
 
 125  
     /**
 126  
      * Constant used in component attribute map to store the {@link javax.faces.view.Location} object
 127  
      * where the definition of this component is.
 128  
      */
 129  
     public static final String VIEW_LOCATION_KEY = "javax.faces.component.VIEW_LOCATION_KEY";
 130  
 
 131  
     public static final String ATTRS_WITH_DECLARED_DEFAULT_VALUES
 132  
             = "javax.faces.component.ATTR_NAMES_WITH_DEFAULT_VALUES";
 133  
 
 134  
     /**
 135  
      * Indicate if the facesContext attribute values under the keys javax.faces.component.CURRENT_COMPONENT and
 136  
      * javax.faces.component.CURRENT_COMPOSITE_COMPONENT should be valid or not. By default, those keys are
 137  
      * deprecated since 2.1
 138  
      */
 139  
     @JSFWebConfigParam(since = "2.1.0", expectedValues = "true, false", defaultValue = "false")
 140  
     public static final String HONOR_CURRENT_COMPONENT_ATTRIBUTES_PARAM_NAME
 141  
             = "javax.faces.HONOR_CURRENT_COMPONENT_ATTRIBUTES";
 142  
 
 143  
     /**
 144  
      * The key under which the component stack is stored in the FacesContext.
 145  
      * ATTENTION: this constant is duplicate in CompositeComponentExpressionUtils.
 146  
      */
 147  2
     private static final String _COMPONENT_STACK = "componentStack:" + UIComponent.class.getName();
 148  
 
 149  2
     private static final String _CURRENT_COMPOSITE_COMPONENT_KEY = "compositeComponent:" + UIComponent.class.getName();
 150  
 
 151  
     Map<Class<? extends SystemEvent>, List<SystemEventListener>> _systemEventListenerClassMap;
 152  
 
 153  
     /**
 154  
      * @deprecated
 155  
      */
 156  
     @Deprecated
 157  
     protected Map<String, ValueExpression> bindings;
 158  
     /**
 159  
      * Used to cache the map created using getResourceBundleMap() method, since this method could be called several
 160  
      * times when rendering the composite component. This attribute may not be serialized, so transient is used (There
 161  
      * are some very few special cases when UIComponent instances are serializable like t:schedule, so it is better if
 162  
      * transient is used).
 163  
      */
 164  1554
     private transient Map<String, String> _resourceBundleMap = null;
 165  1554
     private boolean _inView = false;
 166  1554
     private _DeltaStateHelper _stateHelper = null;
 167  
 
 168  
     /**
 169  
      * In JSF 2.0 bindings map was deprecated, and replaced with a map
 170  
      * inside stateHelper. We need this one here because stateHelper needs
 171  
      * to be implemented from here and internally it depends from this property.
 172  
      */
 173  1554
     private boolean _initialStateMarked = false;
 174  
 
 175  
     /** Value of the {@link UIComponent#HONOR_CURRENT_COMPONENT_ATTRIBUTES_PARAM_NAME} parameter */
 176  
     private Boolean _honorCurrentComponentAttributes;
 177  
 
 178  
     public UIComponent()
 179  1554
     {
 180  1554
     }
 181  
 
 182  
     public abstract Map<String, Object> getAttributes();
 183  
     
 184  
     /**
 185  
      * @since 2.2
 186  
      * @return 
 187  
      */
 188  
     public final Map<String,Object> getPassThroughAttributes()
 189  
     {
 190  0
         return getPassThroughAttributes(true);
 191  
     }
 192  
     
 193  
     /**
 194  
      * @since 2.2
 195  
      * @param create
 196  
      * @return A {@code Map} instance, or {@code null}.
 197  
      */
 198  
     public Map<String,Object> getPassThroughAttributes(boolean create)
 199  
     {
 200  0
         return Collections.emptyMap();
 201  
     }
 202  
 
 203  
     /**
 204  
      *
 205  
      * {@inheritDoc}
 206  
      *
 207  
      * @since 2.0
 208  
      */
 209  
     public boolean initialStateMarked()
 210  
     {
 211  25482
         return _initialStateMarked;
 212  
     }
 213  
 
 214  
     /**
 215  
      * Invokes the <code>invokeContextCallback</code> method with the component, specified by <code>clientId</code>.
 216  
      *
 217  
      * @param context
 218  
      *            <code>FacesContext</code> for the current request
 219  
      * @param clientId
 220  
      *            the id of the desired <code>UIComponent</code> clazz
 221  
      * @param callback
 222  
      *            Implementation of the <code>ContextCallback</code> to be called
 223  
      * @return has component been found ?
 224  
      * @throws javax.faces.FacesException
 225  
      */
 226  
     public boolean invokeOnComponent(FacesContext context, String clientId, ContextCallback callback)
 227  
             throws FacesException
 228  
     {
 229  
         // java.lang.NullPointerException - if any of the arguments are null
 230  24
         if (context == null || clientId == null || callback == null)
 231  
         {
 232  6
             throw new NullPointerException();
 233  
         }
 234  
 
 235  18
         pushComponentToEL(context, this);
 236  
         try
 237  
         {
 238  
             // searching for this component?
 239  18
             boolean found = clientId.equals(this.getClientId(context));
 240  18
             if (found)
 241  
             {
 242  
                 try
 243  
                 {
 244  8
                     callback.invokeContextCallback(context, this);
 245  
                 }
 246  2
                 catch (Exception e)
 247  
                 {
 248  2
                     throw new FacesException(e);
 249  6
                 }
 250  6
                 return found;
 251  
             }
 252  
             // Searching for this component's children/facets
 253  
             // [perf] Use getFacetsAndChildren() is nicer but this one prevents
 254  
             // create 1 iterator per component class that does not have
 255  
             // facets attached, which is a common case. 
 256  10
             if (this.getFacetCount() > 0)
 257  
             {
 258  0
                 for (Iterator<UIComponent> it = this.getFacets().values().iterator(); !found && it.hasNext(); )
 259  
                 {
 260  0
                     found = it.next().invokeOnComponent(context, clientId, callback);
 261  
                 }                
 262  
             }
 263  10
             if (this.getChildCount() > 0)
 264  
             {
 265  8
                 for (int i = 0, childCount = getChildCount(); !found && (i < childCount); i++)
 266  
                 {
 267  4
                     UIComponent child = getChildren().get(i);
 268  4
                     found = child.invokeOnComponent(context, clientId, callback);
 269  
                 }
 270  
             }
 271  10
             return found;
 272  
         }
 273  
         finally
 274  
         {
 275  
             //all components must call popComponentFromEl after visiting is finished
 276  16
             popComponentFromEL(context);
 277  
         }
 278  
     }
 279  
 
 280  
     /**
 281  
      *
 282  
      * @param component
 283  
      * @return true if the component is a composite component otherwise false is returned
 284  
      *
 285  
      *
 286  
      * @throws NullPointerException if the component is null
 287  
      * @since 2.0
 288  
      */
 289  
     public static boolean isCompositeComponent(UIComponent component)
 290  
     {
 291  
 
 292  
         //since _isCompositeComponent does it the same way we do it here also although I
 293  
         //would prefer following method
 294  
 
 295  
         //return component.getRendererType().equals("javax.faces.Composite");
 296  
 
 297  734
         return component.getAttributes().containsKey(Resource.COMPONENT_RESOURCE_KEY);
 298  
     }
 299  
 
 300  
     /**
 301  
      * Indicate if this component is inside a view,
 302  
      * or in other words is contained by an UIViewRoot
 303  
      * instance (which represents the view). If this component
 304  
      * is a UIViewRoot instance, the components "always"
 305  
      * is on the view.
 306  
      *
 307  
      * By default it is false but for UIViewRoot instances is
 308  
      * true. 
 309  
      *
 310  
      * @return
 311  
      *
 312  
      * @since 2.0
 313  
      */
 314  
     public boolean isInView()
 315  
     {
 316  338
         return _inView;
 317  
     }
 318  
 
 319  
     public abstract boolean isRendered();
 320  
 
 321  
     public void markInitialState()
 322  
     {
 323  328
         _initialStateMarked = true;
 324  328
     }
 325  
 
 326  
     /**
 327  
      *
 328  
      * This method indicates if a component is visitable
 329  
      * according to the hints passed by the VisitContext parameter!
 330  
      *
 331  
      * This method internally is used by visitTree and if it returns false
 332  
      * it short circuits the visitTree execution.
 333  
      *
 334  
      *
 335  
      *
 336  
      * @param context
 337  
      * @return
 338  
      *
 339  
      * @since 2.0
 340  
      */
 341  
     protected boolean isVisitable(VisitContext context)
 342  
     {
 343  
 
 344  72
         Collection<VisitHint> hints = context.getHints();
 345  
 
 346  72
         if (hints.contains(VisitHint.SKIP_TRANSIENT) && this.isTransient())
 347  
         {
 348  0
             return false;
 349  
         }
 350  
 
 351  72
         if (hints.contains(VisitHint.SKIP_UNRENDERED) && !this.isRendered())
 352  
         {
 353  0
             return false;
 354  
         }
 355  
 
 356  
         //executable cannot be handled here because we do not have any method to determine
 357  
         //whether a component is executable or not, this seems to be a hole in the spec!
 358  
         //but we can resolve it on ppr context level, where it is needed!
 359  
         //maybe in the long run we can move it down here, if it makes sense
 360  
 
 361  72
         return true;
 362  
     }
 363  
 
 364  
     /**
 365  
      * @deprecated Replaced by setValueExpression
 366  
      */
 367  
     public abstract void setValueBinding(String name, ValueBinding binding);
 368  
 
 369  
     public void setValueExpression(String name, ValueExpression expression)
 370  
     {
 371  118
         if (name == null)
 372  
         {
 373  2
             throw new NullPointerException("name");
 374  
         }
 375  116
         if (name.equals("id"))
 376  
         {
 377  2
             throw new IllegalArgumentException("Can't set a ValueExpression for the 'id' property.");
 378  
         }
 379  114
         if (name.equals("parent"))
 380  
         {
 381  2
             throw new IllegalArgumentException("Can't set a ValueExpression for the 'parent' property.");
 382  
         }
 383  
 
 384  112
         if (expression == null)
 385  
         {
 386  
             //if (bindings != null) {
 387  
             //    bindings.remove(name);
 388  
             //    if (bindings.isEmpty()) {
 389  
             //        bindings = null;
 390  
             //    }
 391  
             //}
 392  2
             getStateHelper().remove(PropertyKeys.bindings, name);
 393  
         }
 394  
         else
 395  
         {
 396  110
             if (expression.isLiteralText())
 397  
             {
 398  
                 try
 399  
                 {
 400  4
                     Object value = expression.getValue(getFacesContext().getELContext());
 401  2
                     getAttributes().put(name, value);
 402  2
                     return;
 403  
                 }
 404  2
                 catch (ELException e)
 405  
                 {
 406  2
                     throw new FacesException(e);
 407  
                 }
 408  
             }
 409  
 
 410  
             //if (bindings == null) {
 411  
             //    bindings = new HashMap<String, ValueExpression>();
 412  
             //}
 413  
             //
 414  
             //bindings.put(name, expression);
 415  106
             getStateHelper().put(PropertyKeys.bindings, name, expression);
 416  
         }
 417  108
     }
 418  
 
 419  
     public String getClientId()
 420  
     {
 421  68
         return getClientId(getFacesContext());
 422  
     }
 423  
 
 424  
     public abstract String getClientId(FacesContext context);
 425  
 
 426  
     /**
 427  
      * search for the nearest parent composite component, if no parent is found
 428  
      * it has to return null!
 429  
      *
 430  
      * if the component itself is null we have to return null as well!
 431  
      *
 432  
      * @param component the component to start from
 433  
      * @return the parent composite component if found otherwise null
 434  
      *
 435  
      * @since 2.0
 436  
      */
 437  
     public static UIComponent getCompositeComponentParent(UIComponent component)
 438  
     {
 439  
 
 440  62
         if (component == null)
 441  
         {
 442  0
             return null;
 443  
         }
 444  62
         UIComponent parent = component;
 445  
 
 446  
         do
 447  
         {
 448  122
             parent = parent.getParent();
 449  122
             if (parent != null && UIComponent.isCompositeComponent(parent))
 450  
             {
 451  0
                 return parent;
 452  
             }
 453  122
         } while (parent != null);
 454  62
         return null;
 455  
     }
 456  
 
 457  
     /**
 458  
      * @since 1.2
 459  
      */
 460  
     public String getContainerClientId(FacesContext ctx)
 461  
     {
 462  956
         if (ctx == null)
 463  
         {
 464  2
             throw new NullPointerException("FacesContext ctx");
 465  
         }
 466  
 
 467  954
         return getClientId(ctx);
 468  
     }
 469  
 
 470  
     /**
 471  
      *
 472  
      * @param context
 473  
      * @return
 474  
      *
 475  
      * @since 2.0
 476  
      */
 477  
     public static UIComponent getCurrentComponent(FacesContext context)
 478  
     {
 479  96
         Boolean honorCurrentComponentAttributes = null;
 480  
 
 481  96
         if (context.getViewRoot() != null)
 482  
         {
 483  96
             honorCurrentComponentAttributes = ((UIComponent)context.getViewRoot())._honorCurrentComponentAttributes;
 484  96
             if (honorCurrentComponentAttributes == null)
 485  
             {
 486  92
                 honorCurrentComponentAttributes = _getHonorCurrentComponentAttributes(context);
 487  
             }
 488  
         }
 489  
         else
 490  
         {
 491  0
             honorCurrentComponentAttributes = _getHonorCurrentComponentAttributes(context);
 492  
         }
 493  
 
 494  96
         if (Boolean.TRUE.equals(honorCurrentComponentAttributes))
 495  
         {
 496  0
             return (UIComponent) context.getAttributes().get(UIComponent.CURRENT_COMPONENT);
 497  
         }
 498  
         else
 499  
         {
 500  96
             List<UIComponent> componentStack
 501  
                     = (List<UIComponent>) context.getAttributes().get(UIComponent._COMPONENT_STACK);
 502  96
             if (componentStack == null)
 503  
             {
 504  0
                 return null;
 505  
             }
 506  
             else
 507  
             {
 508  96
                 if (componentStack.size() > 0)
 509  
                 {
 510  94
                     return componentStack.get(componentStack.size()-1);
 511  
                 }
 512  
                 else
 513  
                 {
 514  2
                     return null;
 515  
                 }
 516  
             }
 517  
         }
 518  
     }
 519  
 
 520  
     /**
 521  
      *
 522  
      * @param context
 523  
      * @return
 524  
      *
 525  
      * @since 2.0
 526  
      */
 527  
     public static UIComponent getCurrentCompositeComponent(FacesContext context)
 528  
     {
 529  0
         Boolean honorCurrentComponentAttributes = null;
 530  
 
 531  0
         if (context.getViewRoot() != null)
 532  
         {
 533  0
             honorCurrentComponentAttributes = ((UIComponent)context.getViewRoot())._honorCurrentComponentAttributes;
 534  0
             if (honorCurrentComponentAttributes == null)
 535  
             {
 536  0
                 honorCurrentComponentAttributes = _getHonorCurrentComponentAttributes(context);
 537  
             }
 538  
         }
 539  
         else
 540  
         {
 541  0
             honorCurrentComponentAttributes = _getHonorCurrentComponentAttributes(context);
 542  
         }
 543  
 
 544  0
         if (Boolean.TRUE.equals(honorCurrentComponentAttributes))
 545  
         {
 546  0
             return (UIComponent) context.getAttributes().get(UIComponent.CURRENT_COMPOSITE_COMPONENT);
 547  
         }
 548  
         else
 549  
         {
 550  0
             return (UIComponent) context.getAttributes().get(UIComponent._CURRENT_COMPOSITE_COMPONENT_KEY);
 551  
         }
 552  
     }
 553  
 
 554  
     public abstract String getFamily();
 555  
 
 556  
     public abstract String getId();
 557  
 
 558  
     public List<SystemEventListener> getListenersForEventClass(Class<? extends SystemEvent> eventClass)
 559  
     {
 560  
         List<SystemEventListener> listeners;
 561  178
         if (_systemEventListenerClassMap == null)
 562  
         {
 563  178
             listeners = Collections.emptyList();
 564  
         }
 565  
         else
 566  
         {
 567  0
             listeners = _systemEventListenerClassMap.get(eventClass);
 568  0
             if (listeners == null)
 569  
             {
 570  0
                 listeners = Collections.emptyList();
 571  
             }
 572  
             else
 573  
             {
 574  0
                 listeners = Collections.unmodifiableList(listeners);
 575  
             }
 576  
         }
 577  
 
 578  178
         return listeners;
 579  
     }
 580  
 
 581  
     /**
 582  
      *
 583  
      * @return
 584  
      *
 585  
      * @since 2.0
 586  
      */
 587  
     public UIComponent getNamingContainer()
 588  
     {
 589  
         // Starting with "this", return the closest component in the ancestry that is a NamingContainer 
 590  
         // or null if none can be found.
 591  0
         UIComponent component = this;
 592  
         do
 593  
         {
 594  0
             if (component instanceof NamingContainer)
 595  
             {
 596  0
                 return component;
 597  
             }
 598  
 
 599  0
             component = component.getParent();
 600  0
         } while (component != null);
 601  
 
 602  0
         return null;
 603  
     }
 604  
 
 605  
     public abstract void setId(String id);
 606  
 
 607  
     /**
 608  
      * Define if the component is on the view or not.
 609  
      * <p>
 610  
      * This value is set in the following conditions:
 611  
      * </p>
 612  
      * <ul>
 613  
      * <li>Component / Facet added: if the parent isInView = true, 
 614  
      *     set it to true and all their children or facets,
 615  
      *     otherwise take no action</li>
 616  
      * <li>Component / Facet removed: if the parent isInView = false,
 617  
      *     set it to false and all their children or facets,
 618  
      *     otherwise take no action</li>
 619  
      * <ul>
 620  
      * @param isInView
 621  
      *
 622  
      * @since 2.0
 623  
      */
 624  
     public void setInView(boolean isInView)
 625  
     {
 626  152
         _inView = isInView;
 627  152
     }
 628  
 
 629  
     /**
 630  
      * For JSF-framework internal use only. Don't call this method to add components to the component tree. Use
 631  
      * <code>parent.getChildren().add(child)</code> instead.
 632  
      */
 633  
     public abstract void setParent(UIComponent parent);
 634  
 
 635  
     /**
 636  
      * Returns the parent of the component. Children can be added to or removed from a component even if this method
 637  
      * returns null for the child.
 638  
      */
 639  
     public abstract UIComponent getParent();
 640  
 
 641  
     public abstract void setRendered(boolean rendered);
 642  
 
 643  
     public abstract String getRendererType();
 644  
 
 645  
     public abstract void setRendererType(String rendererType);
 646  
 
 647  
     public abstract boolean getRendersChildren();
 648  
 
 649  
     public Map<String, String> getResourceBundleMap()
 650  
     {
 651  0
         if (_resourceBundleMap == null)
 652  
         {
 653  0
             FacesContext context = getFacesContext();
 654  0
             Locale locale = context.getViewRoot().getLocale();
 655  0
             ClassLoader loader = _ClassUtils.getContextClassLoader();
 656  
 
 657  
             try
 658  
             {
 659  
                 // looks for a ResourceBundle with a base name equal to the fully qualified class
 660  
                 // name of the current UIComponent this and Locale equal to the Locale of the current UIViewRoot.
 661  0
                 _resourceBundleMap = new BundleMap(ResourceBundle.getBundle(getClass().getName(), locale, loader));
 662  
             }
 663  0
             catch (MissingResourceException e)
 664  
             {
 665  
                 // If no such bundle is found, and the component is a composite component
 666  0
                 if (this._isCompositeComponent())
 667  
                 {
 668  
                     // No need to check componentResource (the resource used to build the composite
 669  
                     // component instance) to null since it is already done on this._isCompositeComponent()
 670  0
                     Resource componentResource = (Resource) getAttributes().get(Resource.COMPONENT_RESOURCE_KEY);
 671  
                     // Let resourceName be the resourceName of the Resource for this composite component,
 672  
                     // replacing the file extension with ".properties"
 673  0
                     int extensionIndex = componentResource.getResourceName().lastIndexOf('.');
 674  0
                     String resourceName = (extensionIndex < 0
 675  
                             ? componentResource.getResourceName()
 676  
                             : componentResource.getResourceName().substring(0, extensionIndex)) + ".properties";
 677  
 
 678  
                     // Let libraryName be the libraryName of the the Resource for this composite component.
 679  
                     // Call ResourceHandler.createResource(java.lang.String,java.lang.String), passing the derived
 680  
                     // resourceName and
 681  
                     // libraryName.
 682  0
                     Resource bundleResource = context.getApplication().getResourceHandler()
 683  
                             .createResource(resourceName, componentResource.getLibraryName());
 684  
 
 685  0
                     if (bundleResource != null)
 686  
                     {
 687  
                         // If the resultant Resource exists and can be found, the InputStream for the resource
 688  
                         // is used to create a ResourceBundle. If either of the two previous steps for obtaining the
 689  
                         // ResourceBundle
 690  
                         // for this component is successful, the ResourceBundle is wrapped in a Map<String, String> and
 691  
                         // returned.
 692  
                         try
 693  
                         {
 694  0
                             _resourceBundleMap
 695  
                                     = new BundleMap(new PropertyResourceBundle(bundleResource.getInputStream()));
 696  
                         }
 697  0
                         catch (IOException e1)
 698  
                         {
 699  
                             // Nothing happens, then resourceBundleMap is set as empty map
 700  0
                         }
 701  
                     }
 702  
                 }
 703  
                 // Otherwise Collections.EMPTY_MAP is returned.
 704  0
                 if (_resourceBundleMap == null)
 705  
                 {
 706  0
                     _resourceBundleMap = Collections.emptyMap();
 707  
                 }
 708  0
             }
 709  
         }
 710  
 
 711  0
         return _resourceBundleMap;
 712  
     }
 713  
 
 714  
     /**
 715  
      * @deprecated Replaced by getValueExpression
 716  
      */
 717  
     public abstract ValueBinding getValueBinding(String name);
 718  
 
 719  
     public ValueExpression getValueExpression(String name)
 720  
     {
 721  1390
         if (name == null)
 722  
         {
 723  0
             throw new NullPointerException("name can not be null");
 724  
         }
 725  
 
 726  1390
         Map<String, Object> bindings = (Map<String, Object>) getStateHelper().
 727  
                 get(PropertyKeys.bindings);
 728  
 
 729  1390
         if (bindings == null)
 730  
         {
 731  1108
             if (!(this instanceof UIComponentBase))
 732  
             {
 733  
                 // if the component does not inherit from UIComponentBase and don't implements JSF 1.2 or later
 734  6
                 ValueBinding vb = getValueBinding(name);
 735  6
                 if (vb != null)
 736  
                 {
 737  
                     //bindings = new HashMap<String, ValueExpression>();
 738  2
                     ValueExpression ve = new _ValueBindingToValueExpression(vb);
 739  2
                     getStateHelper().put(PropertyKeys.bindings, name, ve);
 740  2
                     return ve;
 741  
                 }
 742  4
             }
 743  
         }
 744  
         else
 745  
         {
 746  
             //return bindings.get(name);
 747  282
             return (ValueExpression) bindings.get(name);
 748  
         }
 749  1106
         return null;
 750  
     }
 751  
 
 752  
     public abstract List<UIComponent> getChildren();
 753  
 
 754  
     public abstract int getChildCount();
 755  
 
 756  
     public abstract UIComponent findComponent(String expr);
 757  
 
 758  
     public abstract Map<String, UIComponent> getFacets();
 759  
 
 760  
     public abstract UIComponent getFacet(String name);
 761  
 
 762  
     public abstract Iterator<UIComponent> getFacetsAndChildren();
 763  
 
 764  
     public abstract void broadcast(FacesEvent event) throws AbortProcessingException;
 765  
 
 766  
     /**
 767  
      * {@inheritDoc}
 768  
      *
 769  
      * @since 2.0
 770  
      */
 771  
     public void clearInitialState()
 772  
     {
 773  86
         _initialStateMarked = false;
 774  86
     }
 775  
 
 776  
     public abstract void decode(FacesContext context);
 777  
 
 778  
     public abstract void encodeBegin(FacesContext context) throws IOException;
 779  
 
 780  
     public abstract void encodeChildren(FacesContext context) throws IOException;
 781  
 
 782  
     public abstract void encodeEnd(FacesContext context) throws IOException;
 783  
 
 784  
     public void encodeAll(FacesContext context) throws IOException
 785  
     {
 786  2
         if (context == null)
 787  
         {
 788  2
             throw new NullPointerException();
 789  
         }
 790  
 
 791  0
         pushComponentToEL(context, this);
 792  
         try
 793  
         {
 794  0
             if (!isRendered())
 795  
             {
 796  
                 return;
 797  
             }
 798  
         }
 799  
         finally
 800  
         {
 801  0
             popComponentFromEL(context);
 802  0
         }
 803  
 
 804  
         //if (isRendered()) {
 805  0
         this.encodeBegin(context);
 806  
 
 807  
         // rendering children
 808  0
         if (this.getRendersChildren())
 809  
         {
 810  0
             this.encodeChildren(context);
 811  
         } // let children render itself
 812  
         else
 813  
         {
 814  0
             if (this.getChildCount() > 0)
 815  
             {
 816  0
                 for (int i = 0; i < this.getChildCount(); i++)
 817  
                 {
 818  0
                     UIComponent comp = this.getChildren().get(i);
 819  0
                     comp.encodeAll(context);
 820  
                 }
 821  
             }
 822  
         }
 823  0
         this.encodeEnd(context);
 824  
         //}
 825  0
     }
 826  
 
 827  
     protected abstract void addFacesListener(FacesListener listener);
 828  
 
 829  
     protected abstract FacesListener[] getFacesListeners(Class clazz);
 830  
 
 831  
     protected abstract void removeFacesListener(FacesListener listener);
 832  
 
 833  
     public abstract void queueEvent(FacesEvent event);
 834  
 
 835  
     public abstract void processRestoreState(FacesContext context, Object state);
 836  
 
 837  
     public abstract void processDecodes(FacesContext context);
 838  
 
 839  
     public void processEvent(ComponentSystemEvent event) throws AbortProcessingException
 840  
     {
 841  
         // The default implementation performs the following action. If the argument event is an instance of
 842  
         // AfterRestoreStateEvent,
 843  0
         if (event instanceof PostRestoreStateEvent)
 844  
         {
 845  
 
 846  
             // call this.getValueExpression(java.lang.String) passing the literal string "binding"
 847  0
             ValueExpression expression = getValueExpression("binding");
 848  
 
 849  
             // If the result is non-null, set the value of the ValueExpression to be this.
 850  0
             if (expression != null)
 851  
             {
 852  0
                 expression.setValue(getFacesContext().getELContext(), this);
 853  
             }
 854  
 
 855  
             //we issue a PostRestoreStateEvent
 856  
             //we issue it here because the spec clearly states what UIComponent is allowed to do
 857  
             //the main issue is that the spec does not say anything about a global dispatch on this level
 858  
             //but a quick blackbox test against the ri revealed that the event clearly is dispatched
 859  
             //at restore level for every component so we either issue it here or in UIViewRoot and/or the facelet
 860  
             // and jsp restore state triggers, a central point is preferrble so we do it here
 861  
             //TODO ask the EG the spec clearly contradicts blackbox RI behavior here 
 862  
 
 863  
             //getFacesContext().getApplication().publishEvent(getFacesContext(),
 864  
             // PostRestoreStateEvent.class, UIComponent.class, this);
 865  
             
 866  
             // JSF 2.2 vdl.createComponent() requires special handling to refresh
 867  
             // dynamic parts when refreshing is done. The only way to do it is 
 868  
             // attaching a listener to PostRestoreStateEvent, so we need to do this
 869  
             // invocation here.
 870  
             // Do it inside UIComponent.processEvent() is better because in facelets
 871  
             // UILeaf we can skip this part just overriding the method.
 872  
             
 873  0
             List<SystemEventListener> listeners = this.getListenersForEventClass(
 874  
                 PostRestoreStateEvent.class);
 875  0
             if (!listeners.isEmpty())
 876  
             {
 877  0
                 for (int i  = 0, size = listeners.size(); i < size; i++)
 878  
                 {
 879  0
                     SystemEventListener listener = listeners.get(i);
 880  0
                     if (listener.isListenerForSource(this))
 881  
                     {
 882  
                         // Check if the listener points again to the component, to
 883  
                         // avoid StackoverflowException
 884  0
                         boolean shouldProcessEvent = true;
 885  0
                         if (listener instanceof EventListenerWrapper && 
 886  
                             ((EventListenerWrapper)listener).listenerCapability == 
 887  
                                 EventListenerWrapper.LISTENER_TYPE_COMPONENT)
 888  
                         {
 889  0
                             shouldProcessEvent = false;
 890  
                         }
 891  0
                         if (shouldProcessEvent)
 892  
                         {
 893  0
                             listener.processEvent(event);
 894  
                         }
 895  
                     }
 896  
                 }
 897  
             }
 898  
         }
 899  0
     }
 900  
 
 901  
     public abstract void processValidators(FacesContext context);
 902  
 
 903  
     public abstract void processUpdates(FacesContext context);
 904  
 
 905  
     public abstract java.lang.Object processSaveState(FacesContext context);
 906  
 
 907  
     public void subscribeToEvent(Class<? extends SystemEvent> eventClass,
 908  
                                  ComponentSystemEventListener componentListener)
 909  
     {
 910  
         // The default implementation creates an inner SystemEventListener instance that wraps argument
 911  
         // componentListener as the listener argument.
 912  0
         if (eventClass == null)
 913  
         {
 914  0
             throw new NullPointerException("eventClass required");
 915  
         }
 916  0
         if (componentListener == null)
 917  
         {
 918  0
             throw new NullPointerException("componentListener required");
 919  
         }
 920  
 
 921  0
         SystemEventListener listener = new EventListenerWrapper(this, componentListener);
 922  
 
 923  
         // Make sure the map exists
 924  0
         if (_systemEventListenerClassMap == null)
 925  
         {
 926  0
             _systemEventListenerClassMap = new HashMap<Class<? extends SystemEvent>, List<SystemEventListener>>();
 927  
         }
 928  
 
 929  0
         List<SystemEventListener> listeners = _systemEventListenerClassMap.get(eventClass);
 930  
         // Make sure the list for class exists
 931  0
         if (listeners == null)
 932  
         {
 933  
             // how many listeners per event type can single component have? 
 934  
             // We use 3 here as expected number, but it is a question 
 935  0
             listeners = new _DeltaList<SystemEventListener>(new ArrayList<SystemEventListener>(3));
 936  0
             _systemEventListenerClassMap.put(eventClass, listeners);
 937  
         }
 938  
 
 939  
         // Deal with contains? Spec is silent
 940  0
         listeners.add(listener);
 941  0
     }
 942  
 
 943  
     public void unsubscribeFromEvent(Class<? extends SystemEvent> eventClass,
 944  
                                      ComponentSystemEventListener componentListener)
 945  
     {
 946  
         /*
 947  
          * When doing the comparison to determine if an existing listener is equal to the argument componentListener
 948  
          * (and thus must be removed), the equals() method on the existing listener must be invoked, passing the
 949  
          * argument componentListener, rather than the other way around.
 950  
          * 
 951  
          * -=Simon Lessard=- What is that supposed to mean? Are we supposed to keep
 952  
          * an internal map of created listener wrappers?
 953  
          * -= Leonardo Uribe=- Yes, it is supposed a wrapper should be used to hold listener references, to prevent
 954  
          * serialize component instances on the state.
 955  
          */
 956  0
         if (eventClass == null)
 957  
         {
 958  0
             throw new NullPointerException("eventClass required");
 959  
         }
 960  0
         if (componentListener == null)
 961  
         {
 962  0
             throw new NullPointerException("componentListener required");
 963  
         }
 964  
 
 965  0
         if (_systemEventListenerClassMap != null)
 966  
         {
 967  0
             List<SystemEventListener> listeners = _systemEventListenerClassMap.get(eventClass);
 968  
 
 969  0
             if (listeners != null && !listeners.isEmpty())
 970  
             {
 971  0
                 for (Iterator<SystemEventListener> it = listeners.iterator(); it.hasNext(); )
 972  
                 {
 973  0
                     ComponentSystemEventListener listener
 974  
                             = ((EventListenerWrapper) it.next()).getComponentSystemEventListener();
 975  0
                     if (listener != null && listener.equals(componentListener))
 976  
                     {
 977  0
                         it.remove();
 978  0
                         break;
 979  
                     }
 980  0
                 }
 981  
             }
 982  
         }
 983  0
     }
 984  
 
 985  
     /**
 986  
      * The visit tree method, visit tree walks over a subtree and processes
 987  
      * the callback object to perform some operation on the subtree
 988  
      * <p>
 989  
      * there are some details in the implementation which according to the spec have
 990  
      * to be in place:
 991  
      * a) before calling the callback and traversing into the subtree  pushComponentToEL
 992  
      * has to be called
 993  
      * b) after the processing popComponentFromEL has to be performed to remove the component
 994  
      * from the el
 995  
      * </p>
 996  
      * <p>
 997  
      * The tree traversal optimizations are located in the visit context and can be replaced
 998  
      * via the VisitContextFactory in the faces-config factory section
 999  
      * </p>
 1000  
      *
 1001  
      * @param context the visit context which handles the processing details
 1002  
      * @param callback the callback to be performed
 1003  
      * @return false if the processing is not done true if we can shortcut
 1004  
      * the visiting because we are done with everything
 1005  
      *
 1006  
      * @since 2.0
 1007  
      */
 1008  
     public boolean visitTree(VisitContext context, VisitCallback callback)
 1009  
     {
 1010  
         try
 1011  
         {
 1012  62
             pushComponentToEL(context.getFacesContext(), this);
 1013  
 
 1014  62
             if (!isVisitable(context))
 1015  
             {
 1016  0
                 return false;
 1017  
             }
 1018  
 
 1019  62
             VisitResult res = context.invokeVisitCallback(this, callback);
 1020  62
             switch (res)
 1021  
             {
 1022  
                 //we are done nothing has to be processed anymore
 1023  
                 case COMPLETE:
 1024  0
                     return true;
 1025  
 
 1026  
                 case REJECT:
 1027  0
                     return false;
 1028  
 
 1029  
                 //accept
 1030  
                 default:
 1031  62
                     if (getFacetCount() > 0)
 1032  
                     {
 1033  4
                         for (UIComponent facet : getFacets().values())
 1034  
                         {
 1035  4
                             if (facet.visitTree(context, callback))
 1036  
                             {
 1037  0
                                 return true;
 1038  
                             }
 1039  4
                         }
 1040  
                     }
 1041  62
                     int childCount = getChildCount();
 1042  62
                     if (childCount > 0)
 1043  
                     {
 1044  8
                         for (int i = 0; i < childCount; i++)
 1045  
                         {
 1046  4
                             UIComponent child = getChildren().get(i);
 1047  4
                             if (child.visitTree(context, callback))
 1048  
                             {
 1049  0
                                 return true;
 1050  
                             }
 1051  
                         }
 1052  
                     }
 1053  62
                     return false;
 1054  
             }
 1055  
         }
 1056  
         finally
 1057  
         {
 1058  
             //all components must call popComponentFromEl after visiting is finished
 1059  62
             popComponentFromEL(context.getFacesContext());
 1060  
         }
 1061  
     }
 1062  
 
 1063  
     protected abstract FacesContext getFacesContext();
 1064  
 
 1065  
     protected abstract Renderer getRenderer(FacesContext context);
 1066  
 
 1067  
     /**
 1068  
      * Note that id, clientId properties
 1069  
      * never change its value after the component is populated,
 1070  
      * so we don't need to store it on StateHelper or restore it when
 1071  
      * initialStateMarked == true
 1072  
      * (Note that rendererType is suspicious, in theory this field is
 1073  
      * initialized on constructor, but on 1.1 and 1.2 is saved and restored,
 1074  
      * so to keep backward behavior we put it on StateHelper )
 1075  
      *
 1076  
      * Also, facesListeners can't be wrapped on StateHelper because it
 1077  
      * needs to handle PartialStateHolder instances when it is saved and
 1078  
      * restored and this interface does not implement PartialStateHolder,
 1079  
      * so we can't propagate calls to markInitialState and clearInitialState,
 1080  
      * in other words, the List wrapped by StateHelper does not handle
 1081  
      * PartialStateHolder items.
 1082  
      *
 1083  
      * "bindings" map does not need to deal with PartialStateHolder instances,
 1084  
      *  so we can use StateHelper feature (handle delta for this map or in
 1085  
      *  other words track add/removal from bindings map as delta).
 1086  
      */
 1087  16
     enum PropertyKeys
 1088  
     {
 1089  2
         rendered,
 1090  2
         rendererType,
 1091  2
         attributesMap,
 1092  2
         bindings,
 1093  2
         facesListeners,
 1094  2
         passThroughAttributesMap
 1095  
     }
 1096  
 
 1097  
     protected StateHelper getStateHelper()
 1098  
     {
 1099  47294
         return getStateHelper(true);
 1100  
     }
 1101  
 
 1102  
     /**
 1103  
      * returns a delta state saving enabled state helper
 1104  
      * for the current component
 1105  
      * @param create if true a state helper is created if not already existing
 1106  
      * @return an implementation of the StateHelper interface or null if none exists and create is set to false
 1107  
      */
 1108  
     protected StateHelper getStateHelper(boolean create)
 1109  
     {
 1110  48634
         if (_stateHelper != null)
 1111  
         {
 1112  47154
             return _stateHelper;
 1113  
         }
 1114  1480
         if (create)
 1115  
         {
 1116  1168
             _stateHelper = new _DeltaStateHelper(this);
 1117  
         }
 1118  1480
         return _stateHelper;
 1119  
     }
 1120  
 
 1121  
     public final TransientStateHelper getTransientStateHelper()
 1122  
     {
 1123  368
         return getTransientStateHelper(true);
 1124  
     }
 1125  
 
 1126  
     public TransientStateHelper getTransientStateHelper(boolean create)
 1127  
     {
 1128  368
         if (_stateHelper != null)
 1129  
         {
 1130  354
             return _stateHelper;
 1131  
         }
 1132  14
         if (create)
 1133  
         {
 1134  14
             _stateHelper = new _DeltaStateHelper(this);
 1135  
         }
 1136  14
         return _stateHelper;
 1137  
     }
 1138  
 
 1139  
     public void restoreTransientState(FacesContext context, Object state)
 1140  
     {
 1141  176
         getTransientStateHelper().restoreTransientState(context, state);
 1142  176
     }
 1143  
 
 1144  
     public Object saveTransientState(FacesContext context)
 1145  
     {
 1146  176
         return getTransientStateHelper().saveTransientState(context);
 1147  
     }
 1148  
 
 1149  
     @SuppressWarnings("unchecked")
 1150  
     public final void popComponentFromEL(FacesContext context)
 1151  
     {
 1152  328
         Map<Object, Object> contextAttributes = context.getAttributes();
 1153  
 
 1154  322
         if (_honorCurrentComponentAttributes == null)
 1155  
         {
 1156  6
             _honorCurrentComponentAttributes = _getHonorCurrentComponentAttributes(context);
 1157  
         }
 1158  
 
 1159  322
         if (Boolean.TRUE.equals(_honorCurrentComponentAttributes))
 1160  
         {
 1161  
             // Pop the current UIComponent from the FacesContext attributes map so that the previous 
 1162  
             // UIComponent, if any, becomes the current component.
 1163  0
             List<UIComponent> componentStack
 1164  
                     = (List<UIComponent>) contextAttributes.get(UIComponent._COMPONENT_STACK);
 1165  
 
 1166  0
             UIComponent oldCurrent = (UIComponent) contextAttributes.get(UIComponent.CURRENT_COMPONENT);
 1167  
 
 1168  0
             UIComponent newCurrent = null;
 1169  0
             if (componentStack != null && !componentStack.isEmpty())
 1170  
             {
 1171  0
                 if (!this.equals(oldCurrent))
 1172  
                 {
 1173  
                     //Check on the componentStack if it can be found
 1174  0
                     int componentIndex = componentStack.lastIndexOf(this);
 1175  0
                     if (componentIndex >= 0)
 1176  
                     {
 1177  
                         //for (int i = 0; i < (componentIndex + 1); i++)
 1178  0
                         for (int i = componentStack.size()-1; i >= componentIndex ; i--)
 1179  
                         {
 1180  0
                             newCurrent = componentStack.remove(componentStack.size()-1);
 1181  
                         }
 1182  
                     }
 1183  
                     else
 1184  
                     {
 1185  
                         //Component not found on the stack. Do not pop.
 1186  0
                         return;
 1187  
                     }
 1188  0
                 }
 1189  
                 else
 1190  
                 {
 1191  0
                     newCurrent = componentStack.remove(componentStack.size()-1);
 1192  
                 }
 1193  
             }
 1194  
             else
 1195  
             {
 1196  
                 //Reset the current composite component
 1197  0
                 contextAttributes.put(UIComponent.CURRENT_COMPOSITE_COMPONENT, null);
 1198  
             }
 1199  0
             oldCurrent = (UIComponent) contextAttributes.put(UIComponent.CURRENT_COMPONENT, newCurrent);
 1200  
 
 1201  0
             if (oldCurrent != null && oldCurrent._isCompositeComponent() && newCurrent != null)
 1202  
             {
 1203  
                 // Recalculate the current composite component
 1204  0
                 if (newCurrent._isCompositeComponent())
 1205  
                 {
 1206  0
                     contextAttributes.put(UIComponent.CURRENT_COMPOSITE_COMPONENT, newCurrent);
 1207  
                 }
 1208  
                 else
 1209  
                 {
 1210  0
                     UIComponent previousCompositeComponent = null;
 1211  0
                     for (int i = componentStack.size()-1; i >= 0; i--)
 1212  
                     {
 1213  0
                         UIComponent component = componentStack.get(i);
 1214  0
                         if (component._isCompositeComponent())
 1215  
                         {
 1216  0
                             previousCompositeComponent = component;
 1217  0
                             break;
 1218  
                         }
 1219  
                     }
 1220  0
                     contextAttributes.put(UIComponent.CURRENT_COMPOSITE_COMPONENT, previousCompositeComponent);
 1221  
                 }
 1222  
             }
 1223  0
         }
 1224  
         else
 1225  
         {
 1226  
             // Pop the current UIComponent from the FacesContext attributes map so that the previous 
 1227  
             // UIComponent, if any, becomes the current component.
 1228  322
             List<UIComponent> componentStack
 1229  
                     = (List<UIComponent>) contextAttributes.get(UIComponent._COMPONENT_STACK);
 1230  
 
 1231  322
             UIComponent oldCurrent = null;
 1232  322
             if (componentStack != null && !componentStack.isEmpty())
 1233  
             {
 1234  322
                 int componentIndex = componentStack.lastIndexOf(this);
 1235  322
                 if (componentIndex >= 0)
 1236  
                 {
 1237  644
                     for (int i = componentStack.size()-1; i >= componentIndex ; i--)
 1238  
                     {
 1239  322
                         oldCurrent = componentStack.remove(componentStack.size()-1);
 1240  
                     }
 1241  
                 }
 1242  
                 else
 1243  
                 {
 1244  0
                     return;
 1245  
                 }
 1246  
             }
 1247  
 
 1248  322
             if (oldCurrent != null && oldCurrent._isCompositeComponent())
 1249  
             {
 1250  
                 // Recalculate the current composite component
 1251  0
                 UIComponent previousCompositeComponent = null;
 1252  0
                 for (int i = componentStack.size()-1; i >= 0; i--)
 1253  
                 {
 1254  0
                     UIComponent component = componentStack.get(i);
 1255  0
                     if (component._isCompositeComponent())
 1256  
                     {
 1257  0
                         previousCompositeComponent = component;
 1258  0
                         break;
 1259  
                     }
 1260  
                 }
 1261  0
                 contextAttributes.put(UIComponent._CURRENT_COMPOSITE_COMPONENT_KEY, previousCompositeComponent);
 1262  
             }
 1263  
         }
 1264  322
     }
 1265  
 
 1266  
     @SuppressWarnings("unchecked")
 1267  
     public final void pushComponentToEL(FacesContext context, UIComponent component)
 1268  
     {
 1269  358
         if (component == null)
 1270  
         {
 1271  28
             component = this;
 1272  
         }
 1273  
 
 1274  358
         Map<Object, Object> contextAttributes = context.getAttributes();
 1275  
 
 1276  352
         if (_honorCurrentComponentAttributes == null)
 1277  
         {
 1278  168
             _honorCurrentComponentAttributes = _getHonorCurrentComponentAttributes(context);
 1279  
         }
 1280  
 
 1281  352
         if (Boolean.TRUE.equals(_honorCurrentComponentAttributes))
 1282  
         {
 1283  0
             UIComponent currentComponent = (UIComponent) contextAttributes.get(UIComponent.CURRENT_COMPONENT);
 1284  
 
 1285  0
             if (currentComponent != null)
 1286  
             {
 1287  0
                 List<UIComponent> componentStack
 1288  
                         = (List<UIComponent>) contextAttributes.get(UIComponent._COMPONENT_STACK);
 1289  0
                 if (componentStack == null)
 1290  
                 {
 1291  0
                     componentStack = new ArrayList<UIComponent>();
 1292  0
                     contextAttributes.put(UIComponent._COMPONENT_STACK, componentStack);
 1293  
                 }
 1294  
 
 1295  0
                 componentStack.add(currentComponent);
 1296  
             }
 1297  
 
 1298  
             // Push the current UIComponent this to the FacesContext  attribute map using the key CURRENT_COMPONENT 
 1299  
             // saving the previous UIComponent associated with CURRENT_COMPONENT for a subsequent call to 
 1300  
             // popComponentFromEL(javax.faces.context.FacesContext).
 1301  0
             contextAttributes.put(UIComponent.CURRENT_COMPONENT, component);
 1302  
 
 1303  0
             if (component._isCompositeComponent())
 1304  
             {
 1305  0
                 contextAttributes.put(UIComponent.CURRENT_COMPOSITE_COMPONENT, component);
 1306  
             }
 1307  0
         }
 1308  
         else
 1309  
         {
 1310  352
             List<UIComponent> componentStack
 1311  
                     = (List<UIComponent>) contextAttributes.get(UIComponent._COMPONENT_STACK);
 1312  352
             if (componentStack == null)
 1313  
             {
 1314  98
                 componentStack = new ArrayList<UIComponent>();
 1315  98
                 contextAttributes.put(UIComponent._COMPONENT_STACK, componentStack);
 1316  
             }
 1317  352
             componentStack.add(component);
 1318  352
             if (component._isCompositeComponent())
 1319  
             {
 1320  0
                 contextAttributes.put(UIComponent._CURRENT_COMPOSITE_COMPONENT_KEY, component);
 1321  
             }
 1322  
         }
 1323  352
     }
 1324  
 
 1325  
     /**
 1326  
      * @since 1.2
 1327  
      */
 1328  
     public int getFacetCount()
 1329  
     {
 1330  
         // not sure why the RI has this method in both
 1331  
         // UIComponent and UIComponentBase
 1332  4
         Map<String, UIComponent> facets = getFacets();
 1333  4
         return facets == null ? 0 : facets.size();
 1334  
     }
 1335  
 
 1336  
     private boolean _isCompositeComponent()
 1337  
     {
 1338  
         //moved to the static method
 1339  674
         return UIComponent.isCompositeComponent(this);
 1340  
     }
 1341  
     
 1342  
     boolean isCachedFacesContext()
 1343  
     {
 1344  0
         return false;
 1345  
     }
 1346  
 
 1347  
     // Dummy method to prevent cast for UIComponentBase when caching
 1348  
     void setCachedFacesContext(FacesContext facesContext)
 1349  
     {
 1350  0
     }
 1351  
 
 1352  
     /**
 1353  
      * Gets value of "javax.faces.HONOR_CURRENT_COMPONENT_ATTRIBUTES" parameter cached in facesContext.attributes 
 1354  
      * or resolves that param and caches its value in facesContext.attributes.    
 1355  
      *
 1356  
      * @return canonical Boolean value for parameter "javax.faces.HONOR_CURRENT_COMPONENT_ATTRIBUTES"
 1357  
      */
 1358  
     private static Boolean _getHonorCurrentComponentAttributes(FacesContext facesContext)
 1359  
     {
 1360  
         // performance note: we cache value in facesContext.attributes because
 1361  
         // 1) methods pushComponentToEL, popComponentFromEl, getCurrentComponent a getCurrentCompositeComponent
 1362  
         // can use that value
 1363  
         // 2) getExternalContext().getInitParameter has undetermined performance. In typical JSF app, there
 1364  
         // are one or two wrappers around external context; servletContext.getInitParameter has also unknown 
 1365  
         // implementation and performance
 1366  266
         Map<Object, Object> attributes = facesContext.getAttributes();
 1367  266
         Boolean paramValue = (Boolean) attributes.get(HONOR_CURRENT_COMPONENT_ATTRIBUTES_PARAM_NAME);
 1368  266
         if (paramValue == null)
 1369  
         {
 1370  98
             String param
 1371  
                     = facesContext.getExternalContext().getInitParameter(HONOR_CURRENT_COMPONENT_ATTRIBUTES_PARAM_NAME);
 1372  98
             paramValue = Boolean.valueOf((param != null && Boolean.valueOf(param).booleanValue()));
 1373  98
             attributes.put(HONOR_CURRENT_COMPONENT_ATTRIBUTES_PARAM_NAME, paramValue);
 1374  
         }
 1375  266
         return paramValue;
 1376  
     }
 1377  
 
 1378  0
     private static class BundleMap implements Map<String, String>
 1379  
     {
 1380  
 
 1381  
         private ResourceBundle _bundle;
 1382  
         private List<String> _values;
 1383  
 
 1384  
         public BundleMap(ResourceBundle bundle)
 1385  0
         {
 1386  0
             _bundle = bundle;
 1387  0
         }
 1388  
 
 1389  
         // Optimized methods
 1390  
         public String get(Object key)
 1391  
         {
 1392  
             try
 1393  
             {
 1394  0
                 return (String) _bundle.getObject(key.toString());
 1395  
             }
 1396  0
             catch (Exception e)
 1397  
             {
 1398  0
                 return "???" + key + "???";
 1399  
             }
 1400  
         }
 1401  
 
 1402  
         public boolean isEmpty()
 1403  
         {
 1404  0
             return !_bundle.getKeys().hasMoreElements();
 1405  
         }
 1406  
 
 1407  
         public boolean containsKey(Object key)
 1408  
         {
 1409  
             try
 1410  
             {
 1411  0
                 return _bundle.getObject(key.toString()) != null;
 1412  
             }
 1413  0
             catch (MissingResourceException e)
 1414  
             {
 1415  0
                 return false;
 1416  
             }
 1417  
         }
 1418  
 
 1419  
         // Unoptimized methods
 1420  
         public Collection<String> values()
 1421  
         {
 1422  0
             if (_values == null)
 1423  
             {
 1424  0
                 _values = new ArrayList<String>();
 1425  0
                 for (Enumeration<String> enumer = _bundle.getKeys(); enumer.hasMoreElements(); )
 1426  
                 {
 1427  0
                     String v = _bundle.getString(enumer.nextElement());
 1428  0
                     _values.add(v);
 1429  0
                 }
 1430  
             }
 1431  0
             return _values;
 1432  
         }
 1433  
 
 1434  
         public int size()
 1435  
         {
 1436  0
             return values().size();
 1437  
         }
 1438  
 
 1439  
         public boolean containsValue(Object value)
 1440  
         {
 1441  0
             return values().contains(value);
 1442  
         }
 1443  
 
 1444  
         public Set<Map.Entry<String, String>> entrySet()
 1445  
         {
 1446  0
             Set<Entry<String, String>> set = new HashSet<Entry<String, String>>();
 1447  0
             for (Enumeration<String> enumer = _bundle.getKeys(); enumer.hasMoreElements(); )
 1448  
             {
 1449  0
                 final String k = enumer.nextElement();
 1450  0
                 set.add(new Map.Entry<String, String>()
 1451  0
                 {
 1452  
 
 1453  
                     public String getKey()
 1454  
                     {
 1455  0
                         return k;
 1456  
                     }
 1457  
 
 1458  
                     public String getValue()
 1459  
                     {
 1460  0
                         return (String) _bundle.getObject(k);
 1461  
                     }
 1462  
 
 1463  
                     public String setValue(String value)
 1464  
                     {
 1465  0
                         throw new UnsupportedOperationException();
 1466  
                     }
 1467  
                 });
 1468  0
             }
 1469  
 
 1470  0
             return set;
 1471  
         }
 1472  
 
 1473  
         public Set<String> keySet()
 1474  
         {
 1475  0
             Set<String> set = new HashSet<String>();
 1476  0
             for (Enumeration<String> enumer = _bundle.getKeys(); enumer.hasMoreElements(); )
 1477  
             {
 1478  0
                 set.add(enumer.nextElement());
 1479  
             }
 1480  0
             return set;
 1481  
         }
 1482  
 
 1483  
         // Unsupported methods
 1484  
         public String remove(Object key)
 1485  
         {
 1486  0
             throw new UnsupportedOperationException();
 1487  
         }
 1488  
 
 1489  
         public void putAll(Map<? extends String, ? extends String> t)
 1490  
         {
 1491  0
             throw new UnsupportedOperationException();
 1492  
         }
 1493  
 
 1494  
         public String put(String key, String value)
 1495  
         {
 1496  0
             throw new UnsupportedOperationException();
 1497  
         }
 1498  
 
 1499  
         public void clear()
 1500  
         {
 1501  0
             throw new UnsupportedOperationException();
 1502  
         }
 1503  
     }
 1504  
 
 1505  2
     static class EventListenerWrapper implements SystemEventListener, PartialStateHolder
 1506  
     {
 1507  
 
 1508  
         private Class<?> componentClass;
 1509  
         private ComponentSystemEventListener listener;
 1510  
 
 1511  
         private boolean _initialStateMarked;
 1512  
 
 1513  
         private int listenerCapability;
 1514  
         private transient UIComponent _component;
 1515  
 
 1516  
         private static final int LISTENER_SAVE_STATE_HOLDER = 1;
 1517  
         private static final int LISTENER_SAVE_PARTIAL_STATE_HOLDER = 2;
 1518  
         private static final int LISTENER_TYPE_COMPONENT = 4;
 1519  
         private static final int LISTENER_TYPE_RENDERER = 8;
 1520  
         private static final int LISTENER_TYPE_OTHER = 16;
 1521  
 
 1522  
         public EventListenerWrapper()
 1523  
         {
 1524  
             //need a no-arg constructor for state saving purposes
 1525  12
             super();
 1526  12
         }
 1527  
 
 1528  
         /**
 1529  
          * Note we have two cases:
 1530  
          *
 1531  
          * 1. listener is an instance of UIComponent. In this case we cannot save and restore
 1532  
          *    it because we need to point to the real component, but we can assume the instance
 1533  
          *    is the same because UIComponent.subscribeToEvent says so. Also take into account
 1534  
          *    this case is the reason why we need a wrapper for UIComponent.subscribeToEvent
 1535  
          * 2. listener is an instance of Renderer. In this case we can assume the same renderer
 1536  
          *    used by the source component is the one used by the listener (ListenerFor). 
 1537  
          * 3. listener is an instance of ComponentSystemEventListener but not from UIComponent.
 1538  
          *    In this case, the instance could implement StateHolder, PartialStateHolder or do
 1539  
          *    implement anything, so we have to deal with that case as usual.
 1540  
          *
 1541  
          * @param component
 1542  
          * @param listener
 1543  
          */
 1544  
         public EventListenerWrapper(UIComponent component, ComponentSystemEventListener listener)
 1545  64
         {
 1546  64
             assert component != null;
 1547  64
             assert listener != null;
 1548  
 
 1549  64
             this.componentClass = component.getClass();
 1550  64
             this.listener = listener;
 1551  64
             this._component = component;
 1552  64
             initListenerCapability();
 1553  64
         }
 1554  
 
 1555  
         private void initListenerCapability()
 1556  
         {
 1557  64
             this.listenerCapability = 0;
 1558  64
             if (this.listener instanceof UIComponent)
 1559  
             {
 1560  10
                 this.listenerCapability = LISTENER_TYPE_COMPONENT;
 1561  
             }
 1562  54
             else if (this.listener instanceof Renderer)
 1563  
             {
 1564  10
                 this.listenerCapability = LISTENER_TYPE_RENDERER;
 1565  
             }
 1566  
             else
 1567  
             {
 1568  44
                 if (this.listener instanceof PartialStateHolder)
 1569  
                 {
 1570  14
                     this.listenerCapability = LISTENER_TYPE_OTHER | LISTENER_SAVE_PARTIAL_STATE_HOLDER;
 1571  
                 }
 1572  30
                 else if (this.listener instanceof StateHolder)
 1573  
                 {
 1574  10
                     this.listenerCapability = LISTENER_TYPE_OTHER | LISTENER_SAVE_STATE_HOLDER;
 1575  
                 }
 1576  
                 else
 1577  
                 {
 1578  20
                     this.listenerCapability = LISTENER_TYPE_OTHER;
 1579  
                 }
 1580  
             }
 1581  64
         }
 1582  
 
 1583  
         @Override
 1584  
         public boolean equals(Object o)
 1585  
         {
 1586  0
             if (o == this)
 1587  
             {
 1588  0
                 return true;
 1589  
             }
 1590  0
             else if (o instanceof EventListenerWrapper)
 1591  
             {
 1592  0
                 EventListenerWrapper other = (EventListenerWrapper) o;
 1593  0
                 return componentClass.equals(other.componentClass) && listener.equals(other.listener);
 1594  
             }
 1595  
             else
 1596  
             {
 1597  0
                 return false;
 1598  
             }
 1599  
         }
 1600  
 
 1601  
         @Override
 1602  
         public int hashCode()
 1603  
         {
 1604  0
             return componentClass.hashCode() + listener.hashCode();
 1605  
         }
 1606  
 
 1607  
         public boolean isListenerForSource(Object source)
 1608  
         {
 1609  
             // and its implementation of SystemEventListener.isListenerForSource(java.lang.Object) must return true
 1610  
             // if the instance class of this UIComponent is assignable from the argument to isListenerForSource.
 1611  
 
 1612  0
             return source.getClass().isAssignableFrom(componentClass);
 1613  
         }
 1614  
 
 1615  
         public ComponentSystemEventListener getComponentSystemEventListener()
 1616  
         {
 1617  114
             return listener;
 1618  
         }
 1619  
 
 1620  
         public void processEvent(SystemEvent event)
 1621  
         {
 1622  
             // This inner class must call through to the argument componentListener in its implementation of
 1623  
             // SystemEventListener.processEvent(javax.faces.event.SystemEvent)
 1624  
 
 1625  0
             assert event instanceof ComponentSystemEvent;
 1626  
 
 1627  0
             listener.processEvent((ComponentSystemEvent) event);
 1628  0
         }
 1629  
 
 1630  
         public void clearInitialState()
 1631  
         {
 1632  
             //if (!(listener instanceof UIComponent) && listener instanceof PartialStateHolder)
 1633  12
             if ((listenerCapability & LISTENER_SAVE_PARTIAL_STATE_HOLDER) != 0)
 1634  
             {
 1635  2
                 ((PartialStateHolder) listener).clearInitialState();
 1636  
             }
 1637  12
             _initialStateMarked = false;
 1638  12
         }
 1639  
 
 1640  
         public boolean initialStateMarked()
 1641  
         {
 1642  
             //if (!(listener instanceof UIComponent) && listener instanceof PartialStateHolder)
 1643  38
             if ((listenerCapability & LISTENER_SAVE_PARTIAL_STATE_HOLDER) != 0)
 1644  
             {
 1645  8
                 return ((PartialStateHolder) listener).initialStateMarked();
 1646  
             }
 1647  
             //return false;
 1648  30
             return _initialStateMarked;
 1649  
         }
 1650  
 
 1651  
         public void markInitialState()
 1652  
         {
 1653  
             //if (!(listener instanceof UIComponent) && listener instanceof PartialStateHolder)
 1654  52
             if ((listenerCapability & LISTENER_SAVE_PARTIAL_STATE_HOLDER) != 0)
 1655  
             {
 1656  12
                 ((PartialStateHolder) listener).markInitialState();
 1657  
             }
 1658  52
             _initialStateMarked = true;
 1659  52
         }
 1660  
 
 1661  
         public boolean isTransient()
 1662  
         {
 1663  
             //if ( listener instanceof StateHolder)
 1664  0
             if ((listenerCapability & LISTENER_SAVE_PARTIAL_STATE_HOLDER) != 0 ||
 1665  
                     (listenerCapability & LISTENER_SAVE_STATE_HOLDER) != 0)
 1666  
             {
 1667  0
                 return ((StateHolder) listener).isTransient();
 1668  
             }
 1669  0
             return false;
 1670  
         }
 1671  
 
 1672  
         public void restoreState(FacesContext context, Object state)
 1673  
         {
 1674  38
             if (state == null)
 1675  
             {
 1676  10
                 return;
 1677  
             }
 1678  28
             Object[] values = (Object[]) state;
 1679  28
             componentClass = (Class) values[0];
 1680  28
             if (values[1] instanceof _AttachedDeltaWrapper)
 1681  
             {
 1682  4
                 ((StateHolder) listener).restoreState(context,
 1683  
                         ((_AttachedDeltaWrapper) values[1]).getWrappedStateObject());
 1684  
             }
 1685  
             else
 1686  
             {
 1687  
                 //Full restore
 1688  24
                 listenerCapability = (Integer) values[2];
 1689  
 
 1690  24
                 _component = UIComponent.getCurrentComponent(context);
 1691  24
                 if ((listenerCapability & LISTENER_TYPE_COMPONENT) != 0)
 1692  
                 {
 1693  4
                     listener = _component;
 1694  
                 }
 1695  20
                 else if ((listenerCapability & LISTENER_TYPE_RENDERER) != 0)
 1696  
                 {
 1697  
                     //listener = (ComponentSystemEventListener)
 1698  
                     //        UIComponent.getCurrentComponent(context).getRenderer(context);
 1699  4
                     Renderer renderer = _component.getRenderer(context);
 1700  4
                     Integer i = (Integer) values[1];
 1701  4
                     if (i != null && i >= 0)
 1702  
                     {
 1703  4
                         while (i > 0)
 1704  
                         {
 1705  0
                             renderer = ((RendererWrapper) renderer).getWrapped();
 1706  0
                             i--;
 1707  
                         }
 1708  
                     }
 1709  4
                     listener = (ComponentSystemEventListener) renderer;
 1710  4
                 }
 1711  
                 else
 1712  
                 {
 1713  16
                     listener = (ComponentSystemEventListener)
 1714  
                             UIComponentBase.restoreAttachedState(context, values[1]);
 1715  
                 }
 1716  
                 /*
 1717  
                 listener = values[1] == null ? 
 1718  
                         UIComponent.getCurrentComponent(context) : 
 1719  
                             (ComponentSystemEventListener) UIComponentBase.restoreAttachedState(context, values[1]);
 1720  
                             */
 1721  
             }
 1722  28
         }
 1723  
 
 1724  
         public Object saveState(FacesContext context)
 1725  
         {
 1726  38
             if (!initialStateMarked())
 1727  
             {
 1728  
                 /*
 1729  
                 Object[] state = new Object[2];
 1730  
                 state[0] = componentClass;
 1731  
                 if (!(listener instanceof UIComponent))
 1732  
                 {
 1733  
                     state[1] = UIComponentBase.saveAttachedState(context, listener);
 1734  
                 }
 1735  
                 return state;
 1736  
                 */
 1737  24
                 Object[] state = new Object[3];
 1738  24
                 state[0] = componentClass;
 1739  
                 //If this is not a component or a renderer, save it calling UIComponent.saveAttachedState
 1740  24
                 if (!((listenerCapability & LISTENER_TYPE_COMPONENT) != 0 ||
 1741  
                         (listenerCapability & LISTENER_TYPE_RENDERER) != 0))
 1742  
                 {
 1743  16
                     state[1] = UIComponentBase.saveAttachedState(context, listener);
 1744  
                 }
 1745  
                 else
 1746  
                 {
 1747  8
                     if ( (listenerCapability & LISTENER_TYPE_RENDERER) != 0)
 1748  
                     {
 1749  4
                         UIComponent componentRef = _component != null ? _component : getCurrentComponent(context);
 1750  4
                         Renderer renderer = componentRef.getRenderer(context);
 1751  4
                         int i = 0;
 1752  4
                         while (renderer != null && !renderer.getClass().equals(listener.getClass()))
 1753  
                         {
 1754  0
                             if (renderer instanceof RendererWrapper)
 1755  
                             {
 1756  0
                                 renderer = ((RendererWrapper) renderer).getWrapped();
 1757  0
                                 i++;
 1758  
                             }
 1759  
                             else
 1760  
                             {
 1761  0
                                 renderer = null;
 1762  0
                                 i = -1;
 1763  
                             }
 1764  
                         }
 1765  4
                         if (i != -1)
 1766  
                         {
 1767  
                             // Store the number so we can get the right wrapper to invoke the method.
 1768  4
                             state[1] = i;
 1769  
                         }
 1770  
                         else
 1771  
                         {
 1772  0
                             state[1] = null;
 1773  
                         }
 1774  4
                     }
 1775  
                     else
 1776  
                     {
 1777  4
                         state[1] = null;
 1778  
                     }
 1779  
                 }
 1780  24
                 state[2] = (Integer) listenerCapability;
 1781  24
                 return state;
 1782  
             }
 1783  
             else
 1784  
             {
 1785  
                 // If initialStateMarked() == true means two things:
 1786  
                 // 1. PSS is being used
 1787  14
                 if ((listenerCapability & LISTENER_TYPE_COMPONENT) != 0)
 1788  
                 {
 1789  2
                     return null;
 1790  
                 }
 1791  12
                 else if ((listenerCapability & LISTENER_TYPE_RENDERER) != 0)
 1792  
                 {
 1793  2
                     return null;
 1794  
                 }
 1795  
                 else
 1796  
                 {
 1797  10
                     if ((listenerCapability & LISTENER_SAVE_STATE_HOLDER) != 0 ||
 1798  
                             (listenerCapability & LISTENER_SAVE_PARTIAL_STATE_HOLDER) != 0)
 1799  
                     {
 1800  6
                         Object listenerSaved = ((StateHolder) listener).saveState(context);
 1801  6
                         if (listenerSaved == null)
 1802  
                         {
 1803  2
                             return null;
 1804  
                         }
 1805  4
                         return new Object[]{componentClass,
 1806  
                                             new _AttachedDeltaWrapper(listener.getClass(), listenerSaved)};
 1807  
                     }
 1808  
                     else
 1809  
                     {
 1810  
                         //This is not necessary, because the instance is considered serializable!
 1811  4
                         return null;
 1812  
                     }
 1813  
                 }
 1814  
                 /*
 1815  
                 Object listenerSaved = ((StateHolder) listener).saveState(context);
 1816  
                 if (listenerSaved == null)
 1817  
                 {
 1818  
                     return null;
 1819  
                 }
 1820  
                 return new Object[]{componentClass, new _AttachedDeltaWrapper(listener.getClass(), listenerSaved)};
 1821  
                 */
 1822  
             }
 1823  
         }
 1824  
 
 1825  
         public void setTransient(boolean newTransientValue)
 1826  
         {
 1827  0
             if ((listenerCapability & LISTENER_SAVE_PARTIAL_STATE_HOLDER) != 0 ||
 1828  
                     (listenerCapability & LISTENER_SAVE_STATE_HOLDER) != 0)
 1829  
             {
 1830  0
                 ((StateHolder) listener).setTransient(newTransientValue);
 1831  
             }
 1832  0
         }
 1833  
     }
 1834  
 }