View Javadoc

1   // WARNING: This file was automatically generated. Do not edit it directly,
2   //          or you will lose your changes.
3   
4   /*
5    * Licensed to the Apache Software Foundation (ASF) under one
6    * or more contributor license agreements.  See the NOTICE file
7    * distributed with this work for additional information
8    * regarding copyright ownership.  The ASF licenses this file
9    * to you under the Apache License, Version 2.0 (the
10   * "License"); you may not use this file except in compliance
11   * with the License.  You may obtain a copy of the License at
12   *
13   *   http://www.apache.org/licenses/LICENSE-2.0
14   *
15   * Unless required by applicable law or agreed to in writing,
16   * software distributed under the License is distributed on an
17   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18   * KIND, either express or implied.  See the License for the
19   * specific language governing permissions and limitations
20   * under the License.
21  */
22  package org.apache.myfaces.trinidad.component;
23  
24  import java.io.IOException;
25  import javax.el.MethodExpression;
26  import javax.faces.component.NamingContainer;
27  import javax.faces.component.UIComponent;
28  import javax.faces.component.visit.VisitCallback;
29  import javax.faces.component.visit.VisitContext;
30  import javax.faces.component.visit.VisitHint;
31  import javax.faces.context.FacesContext;
32  import javax.faces.el.MethodBinding;
33  import javax.faces.event.AbortProcessingException;
34  import javax.faces.event.FacesEvent;
35  import javax.faces.event.PhaseId;
36  import org.apache.myfaces.trinidad.bean.FacesBean;
37  import org.apache.myfaces.trinidad.bean.PropertyKey;
38  import org.apache.myfaces.trinidad.event.FocusListener;
39  import org.apache.myfaces.trinidad.event.RowDisclosureEvent;
40  import org.apache.myfaces.trinidad.event.RowDisclosureListener;
41  import org.apache.myfaces.trinidad.event.SelectionEvent;
42  import org.apache.myfaces.trinidad.event.SelectionListener;
43  import org.apache.myfaces.trinidad.model.CollectionModel;
44  import org.apache.myfaces.trinidad.model.ModelUtils;
45  import org.apache.myfaces.trinidad.model.RowKeySet;
46  import org.apache.myfaces.trinidad.model.RowKeySetTreeImpl;
47  import org.apache.myfaces.trinidad.model.TreeModel;
48  import org.apache.myfaces.trinidad.util.ComponentUtils;
49  
50  /**
51   *
52   * <html:p>
53   *             Apache Trinidad tree components are used to display hierarchical data. 
54   *             For example,
55   *             if we have a personnel organization chart depicting all the direct 
56   *             reports under 
57   *             each employee, we could use a tree component to display this
58   *             chart. While each element (employee) in the hierarchy may have any 
59   *             number of
60   *             child elements, each element can only have one parent element.
61   *           </html:p>
62   *       
63   *           <section name="The Tree Model">
64   *             <html:P>
65   *               The Apache Trinidad tree components use a model to access the data in the
66   *               underlying hierarchy.  The specific model class is
67   *               <html:code>org.apache.myfaces.trinidad.model.TreeModel</html:code>.
68   * 
69   *               You may find the
70   *               <html:code>org.apache.myfaces.trinidad.model.ChildPropertyTreeModel</html:code> class
71   *               useful when constructing a <html:code>TreeModel</html:code>.
72   *             </html:P>
73   *           </section>
74   * 
75   *           <section name="Data">
76   *             <html:P>
77   *               The tree components use a stamping strategy similar to the Trinidad Table
78   *               component.  Child components are used to display the
79   *               data for each element in the tree. Each child component is not recreated
80   *               per element; instead, each child is repeatedly
81   *               rendered (stamped) once per element. Because of this stamping
82   *               behavior, only certain types of components are supported as
83   *               children. Supported components include all
84   *               components with no behavior and most components that implement the
85   *               EditableValueHolder or ActionSource interfaces.
86   *             </html:P>
87   *             <html:P>
88   *               Each time a child component is stamped, the data for the current
89   *               element is copied into an EL reachable property.  The
90   *               name of this property is defined by the <html:code>var</html:code>
91   *               property on
92   *               the tree component. Once the tree has completed rendering, this property is
93   *               removed (or reverted back to its previous value).
94   *             </html:P>
95   *           </section>
96   *           <section name="Events">
97   *             <html:P>
98   *               When the user expands or collapses a subtree the tree
99   *               generates a <html:code>DisclosureEvent</html:code>. This event has an
100  *               <html:code>isExpanded</html:code> method that returns whether the user wants
101  *               to expand or collapse the subtree of a particular element. That
102  *               particular element is made current on the Tree before the event is
103  *               delivered.
104  *             </html:P>
105  *           </section>
106  * 
107  *           <section name="Expand/Collapse State">
108  *             <html:P>
109  *               The Trinidad tree components use an instance of the
110  *               <html:code>org.apache.myfaces.trinidad.model.RowKeySet</html:code>
111  *               class to keep track
112  *               of which elements are expanded. This instance is stored
113  *               as the &quot;expandedRowKeys&quot; attribute on the component. You may use this
114  *               instance to programmatically control the expand/collapse state of an
115  *               element in the hierarchy.
116  *             </html:P>
117  *           </section>
118  *
119  * <h4>Events:</h4>
120  * <table border="1" width="100%" cellpadding="3" summary="">
121  * <tr bgcolor="#CCCCFF" class="TableHeadingColor">
122  * <th align="left">Type</th>
123  * <th align="left">Phases</th>
124  * <th align="left">Description</th>
125  * </tr>
126  * <tr class="TableRowColor">
127  * <td valign="top"><code>org.apache.myfaces.trinidad.event.RowDisclosureEvent</code></td>
128  * <td valign="top" nowrap>Apply<br>Request<br>Values<br>Invoke<br>Application</td>
129  * <td valign="top">The expansion event is generated for a table when the detail facet of a row is expanded or collapsed. For tree or a treeTable, the expansion
130                        event is generated when tree nodes are expanded or collapsed.</td>
131  * </tr>
132  * <tr class="TableRowColor">
133  * <td valign="top"><code>org.apache.myfaces.trinidad.event.SelectionEvent</code></td>
134  * <td valign="top" nowrap>Apply<br>Request<br>Values<br>Invoke<br>Application</td>
135  * <td valign="top">The selection event is delivered when the table selection
136                        changes.</td>
137  * </tr>
138  * <tr class="TableRowColor">
139  * <td valign="top"><code>org.apache.myfaces.trinidad.event.FocusEvent</code></td>
140  * <td valign="top" nowrap>Apply<br>Request<br>Values<br>Invoke<br>Application</td>
141  * <td valign="top">Event delivered when user clicks to focus on (or zoom into) a particular element's subtree of children.
142       	        The TreeTable responds to this event by modifying the "focusPath" property appropriately.
143       	        Subsequently, any registered FocusListener instances are called.</td>
144  * </tr>
145  * <tr class="TableRowColor">
146  * <td valign="top"><code>org.apache.myfaces.trinidad.event.AttributeChangeEvent</code></td>
147  * <td valign="top" nowrap>Invoke<br>Application<br>Apply<br>Request<br>Values</td>
148  * <td valign="top">Event delivered to describe an attribute change.  Attribute change events are not delivered for any programmatic change to a property.  They are only delivered when a renderer changes a property without the application's specific request.  An example of an attribute change event might include the width of a column that supported client-side resizing.</td>
149  * </tr>
150  * </table>
151  */
152 public class UIXTree extends org.apache.myfaces.trinidad.component.UIXHierarchy
153                      implements NamingContainer
154 {
155   static public final FacesBean.Type TYPE = new FacesBean.Type(
156     org.apache.myfaces.trinidad.component.UIXHierarchy.TYPE);
157   static public final PropertyKey SELECTED_ROW_KEYS_KEY =
158     TYPE.registerKey("selectedRowKeys", RowKeySet.class, null, 0, PropertyKey.Mutable.OFTEN);
159   static public final PropertyKey IMMEDIATE_KEY =
160     TYPE.registerKey("immediate", Boolean.class, Boolean.FALSE);
161   static public final PropertyKey ROW_DISCLOSURE_LISTENER_KEY =
162     TYPE.registerKey("rowDisclosureListener", MethodExpression.class);
163   static public final PropertyKey DISCLOSED_ROW_KEYS_KEY =
164     TYPE.registerKey("disclosedRowKeys", RowKeySet.class, null, 0, PropertyKey.Mutable.OFTEN);
165   static public final PropertyKey SELECTION_LISTENER_KEY =
166     TYPE.registerKey("selectionListener", MethodExpression.class);
167   static public final PropertyKey VAR_STATUS_KEY =
168     TYPE.registerKey("varStatus", String.class, PropertyKey.CAP_NOT_BOUND);
169   static public final PropertyKey VALUE_KEY =
170     TYPE.registerKey("value");
171   static public final PropertyKey FOCUS_ROW_KEY_KEY =
172     TYPE.registerKey("focusRowKey");
173   static public final PropertyKey FOCUS_LISTENER_KEY =
174     TYPE.registerKey("focusListener", MethodExpression.class);
175   static public final PropertyKey INITIALLY_EXPANDED_KEY =
176     TYPE.registerKey("initiallyExpanded", Boolean.class, Boolean.FALSE);
177   static public final String NODE_STAMP_FACET = "nodeStamp";
178 
179   static public final String COMPONENT_FAMILY =
180     "org.apache.myfaces.trinidad.Tree";
181   static public final String COMPONENT_TYPE =
182     "org.apache.myfaces.trinidad.Tree";
183 
184   /**
185    * Construct an instance of the UIXTree.
186    */
187   public UIXTree()
188   {
189     super("org.apache.myfaces.trinidad.Tree");
190   }
191   
192 
193   // These are "fake" properties that allow the table to get the disclosed row keys and the
194   // selected row key without triggering the call to getCollectionModel from the
195   // RowKeyFacesBeanWrapper class. See the stamp state saving code for its usage.
196   static private final PropertyKey _DISCLOSED_ROW_KEYS_WITHOUT_MODEL_KEY =
197     TYPE.registerKey("disclosedRowKeysWithoutModel", RowKeySet.class);
198   static private final PropertyKey _SELECTED_ROW_KEYS_WITHOUT_MODEL_KEY =
199     TYPE.registerKey("selectedRowKeysWithoutModel", RowKeySet.class);
200 
201   @Deprecated
202   public void setRowDisclosureListener(MethodBinding binding)
203   {
204     setRowDisclosureListener(adaptMethodBinding(binding));
205   }
206 
207   @Deprecated
208   public void setSelectionListener(MethodBinding binding)
209   {
210     setSelectionListener(adaptMethodBinding(binding));
211   }
212 
213   /**
214    * Sets the phaseID of UI events depending on the "immediate" property.
215    */
216   @Override
217   public void queueEvent(FacesEvent event)
218   {
219     TableUtils.__handleQueueEvent(this, event);
220     super.queueEvent(event);
221   }
222 
223   /**
224    * Delivers an event.
225    * @param event
226    * @throws javax.faces.event.AbortProcessingException
227    */
228   @Override
229   public void broadcast(FacesEvent event) throws AbortProcessingException
230   {
231     if (event instanceof SelectionEvent)
232     {
233       //pu: Implicitly record a Change for 'selectionState' attribute
234       //=-=pu: This ain't getting restored. Check with Arj or file a bug.
235       addAttributeChange("selectedRowKeys",
236                          getSelectedRowKeys());
237       broadcastToMethodExpression(event, getSelectionListener());
238     }
239 
240     HierarchyUtils.__handleBroadcast(this,
241                                       event,
242                                       getDisclosedRowKeys(),
243                                       getRowDisclosureListener());
244     super.broadcast(event);
245   }
246 
247   @Override
248   protected void postCreateCollectionModel(CollectionModel model)
249   {
250     RowKeySet selectedRowKeys = getSelectedRowKeys();
251 
252     if (selectedRowKeys == null)
253     {
254       selectedRowKeys = new RowKeySetTreeImpl();
255       setSelectedRowKeys(selectedRowKeys);
256     }
257 
258     RowKeySet disclosedRowKeys = getDisclosedRowKeys();
259 
260     if (disclosedRowKeys == null)
261     {
262       disclosedRowKeys = new RowKeySetTreeImpl();
263       setDisclosedRowKeys(disclosedRowKeys);
264     }
265 
266     selectedRowKeys.setCollectionModel(model);
267     disclosedRowKeys.setCollectionModel(model);
268   }
269 
270   @Override
271   public CollectionModel createCollectionModel(CollectionModel current, Object value)
272   {
273     TreeModel model = ModelUtils.toTreeModel(value);
274     model.setRowKey(null);
275     return model;
276   }
277 
278   @Override
279   protected void processFacetsAndChildren(
280     FacesContext context,
281     PhaseId phaseId)
282   {
283     // this component has no facets that need to be processed once.
284     // instead process the "nodeStamp" facet as many times as necessary:
285     HierarchyUtils.__iterateOverTree(context,
286                                      phaseId,
287                                      this,
288                                      getDisclosedRowKeys(),
289                                      true);
290   }
291 
292   @Override
293   protected boolean visitChildren(
294     VisitContext  visitContext,
295     VisitCallback callback)
296   {
297     if (ComponentUtils.isSkipIterationVisit(visitContext))
298     {
299       return visitChildrenWithoutIterating(visitContext, callback);
300     }
301     else
302     {
303       return visitData(visitContext, callback);
304     }
305   }
306 
307   @Override
308   protected boolean visitData(
309     VisitContext  visitContext,
310     VisitCallback callback)
311   {
312     // if we are only visiting rendered stamps, then pass in the disclosed row keys, otherwise
313     // pass in null, indicating that all row keys should be visited
314     RowKeySet disclosedRowKeys = (visitContext.getHints().contains(VisitHint.SKIP_UNRENDERED))
315                                    ? getDisclosedRowKeys()
316                                    : null;
317 
318     return visitHierarchy(visitContext, callback, getStamps(), disclosedRowKeys);
319   }
320 
321   @Override
322   void __init()
323   {
324     super.__init();
325     if (getDisclosedRowKeys() == null)
326       setDisclosedRowKeys(new RowKeySetTreeImpl());
327     if (getSelectedRowKeys() == null)
328       setSelectedRowKeys(new RowKeySetTreeImpl());
329   }
330 
331 
332   /**
333    * Gets the internal state of this component.
334    */
335   @Override
336   Object __getMyStampState()
337   {
338     Object[] state = new Object[4];
339     state[0] = super.__getMyStampState();
340     state[1] = getFocusRowKey();
341 
342     // Use "hidden" property keys to allow the row key sets to be retrieved without the
343     // RowKeyFacesBeanWrapper trying to resolve the collection model to be set into the row key
344     // set. This is needed to stop the unnecessary lookup of the collection model when it is not
345     // needed during stamp state saving of the table.
346     RowKeySet selectedRowKeys = (RowKeySet)getProperty(_SELECTED_ROW_KEYS_WITHOUT_MODEL_KEY);
347     RowKeySet disclosedRowKeys = (RowKeySet)getProperty(_DISCLOSED_ROW_KEYS_WITHOUT_MODEL_KEY);
348 
349     state[2] = selectedRowKeys;
350     state[3] = disclosedRowKeys;
351 
352     return state;
353   }
354 
355   /**
356    * Sets the internal state of this component.
357    * @param stampState the internal state is obtained from this object.
358    */
359   @Override
360   @SuppressWarnings("unchecked")
361   void __setMyStampState(Object stampState)
362   {
363     Object[] state = (Object[]) stampState;
364     super.__setMyStampState(state[0]);
365     setFocusRowKey(state[1]);
366     setSelectedRowKeys((RowKeySet) state[2]);
367     setDisclosedRowKeys((RowKeySet) state[3]);
368   }
369 
370   @Override
371   void __resetMyStampState()
372   {
373     super.__resetMyStampState();
374     setFocusRowKey(null);
375     setSelectedRowKeys(null);
376     setDisclosedRowKeys(null);
377   }
378   
379   @Override
380   protected FacesBean createFacesBean(String rendererType)
381   {
382     return new RowKeyFacesBeanWrapper(super.createFacesBean(rendererType));
383   }
384 
385   private class RowKeyFacesBeanWrapper
386     extends FacesBeanWrapper
387   {
388     private boolean _retrievingDisclosedRows = false;
389     private boolean _retrievingSelectedRows = false;
390 
391     RowKeyFacesBeanWrapper(FacesBean bean)
392     {
393       super(bean);
394     }
395 
396     @Override
397     public Object getProperty(PropertyKey key)
398     {
399       if (key == _DISCLOSED_ROW_KEYS_WITHOUT_MODEL_KEY)
400       {
401         // This case is only true if the table is trying to serialize the disclosed row keys to
402         // the stamp state of a parent UIXCollection. This work-around prevents EL evaluation to
403         // get the collection model during stamp state saving. This should be permissible as the
404         // state saving code does not need the collection model to be set in the row key set in
405         // order to save its state.
406         return super.getProperty(DISCLOSED_ROW_KEYS_KEY);
407       }
408       else if (key == _SELECTED_ROW_KEYS_WITHOUT_MODEL_KEY)
409       {
410         // This case is only true if the table is trying to serialize the selected row keys to
411         // the stamp state of a parent UIXCollection. This work-around prevents EL evaluation to
412         // get the collection model during stamp state saving. This should be permissible as the
413         // state saving code does not need the collection model to be set in the row key set in
414         // order to save its state.
415         return super.getProperty(SELECTED_ROW_KEYS_KEY);
416       }
417 
418       Object value = super.getProperty(key);
419       if (key == DISCLOSED_ROW_KEYS_KEY)
420       {
421         if (!_retrievingDisclosedRows && value instanceof RowKeySet)
422         {
423           // Ensure that when we are retrieving and setting the collection model, this property
424           // is not asked for which would create an infinite loop
425           _retrievingDisclosedRows = true;
426 
427           try
428           {
429             RowKeySet rowKeys = (RowKeySet) value;
430             // row key sets need the most recent collection model, but there is no one common entry
431             // point to set this on the set besides when code asks for the value from the bean
432             rowKeys.setCollectionModel(getCollectionModel());
433           }
434           finally
435           {
436             _retrievingDisclosedRows = false;
437           }
438         }
439       }
440       else if (key == SELECTED_ROW_KEYS_KEY)
441       {
442         if (!_retrievingSelectedRows && value instanceof RowKeySet)
443         {
444           // Ensure that when we are retrieving and setting the collection model, this property
445           // is not asked for which would create an infinite loop
446           _retrievingSelectedRows = true;
447 
448           try
449           {
450             RowKeySet rowKeys = (RowKeySet) value;
451             // row key sets need the most recent collection model, but there is no one common entry
452             // point to set this on the set besides when code asks for the value from the bean
453             rowKeys.setCollectionModel(getCollectionModel());
454           }
455           finally
456           {
457             _retrievingSelectedRows = false;
458           }
459         }
460       }
461       return value;
462     }
463 
464     @Override
465     public Object saveState(FacesContext context)
466     {
467       RowKeySet rowKeys = (RowKeySet)super.getProperty(DISCLOSED_ROW_KEYS_KEY);
468       if (rowKeys != null)
469       {
470         // make sure the set does not pin the model in memory
471         rowKeys.setCollectionModel(null);
472       }
473       rowKeys = (RowKeySet)super.getProperty(SELECTED_ROW_KEYS_KEY);
474       if (rowKeys != null)
475       {
476         // make sure the set does not pin the model in memory
477         rowKeys.setCollectionModel(null);
478       }
479       return super.saveState(context);
480     }
481   }
482 
483   /**
484    * @see org.apache.myfaces.trinidad.component.UIXCollection#__encodeBegin(javax.faces.context.FacesContext)
485    */
486   @Override @SuppressWarnings("unchecked")
487   protected void __encodeBegin(FacesContext context) throws IOException
488   {
489     if (isInitiallyExpanded() && !Boolean.TRUE.equals(getAttributes().get(EXPAND_ONCE_KEY)))
490     {
491       Object oldRowKey = getRowKey();
492       try
493       {
494         Object rowKey = getFocusRowKey();
495         if (rowKey == null)
496         {
497           setRowIndex(0);
498           rowKey = getRowKey();
499         }
500 
501         setRowKey(rowKey);
502         RowKeySet old = getDisclosedRowKeys();
503         RowKeySet newset = old.clone();
504         newset.addAll();
505 
506         // use an event to ensure the row disclosure listener is called
507         broadcast(new RowDisclosureEvent(old, newset, this));
508       }
509       finally
510       {
511         setRowKey(oldRowKey);
512       }
513 
514       // use attributes to store that we have processed the initial expansion
515       // as there is no support for private properties in the plug-in at the
516       // moment
517       getAttributes().put(EXPAND_ONCE_KEY, Boolean.TRUE);
518     }
519     super.__encodeBegin(context);
520   }
521 
522   private final static String EXPAND_ONCE_KEY = "initialExpandCompleted";
523 
524   /**
525    * the component to use to stamp each element in the
526    *               tree. Only certain types of components are supported, 
527    *               including all
528    *               components with no behavior and most components that implement the
529    *               EditableValueHolder or ActionSource interfaces.  In a treeTable, this must be a column.
530    */
531   final public UIComponent getNodeStamp()
532   {
533     return getFacet(NODE_STAMP_FACET);
534   }
535 
536   /**
537    * the component to use to stamp each element in the
538    *               tree. Only certain types of components are supported, 
539    *               including all
540    *               components with no behavior and most components that implement the
541    *               EditableValueHolder or ActionSource interfaces.  In a treeTable, this must be a column.
542    */
543   @SuppressWarnings("unchecked")
544   final public void setNodeStamp(UIComponent nodeStampFacet)
545   {
546     getFacets().put(NODE_STAMP_FACET, nodeStampFacet);
547   }
548 
549   /**
550    * Gets the selection state for this component.
551    *
552    * @return  the new selectedRowKeys value
553    */
554   final public RowKeySet getSelectedRowKeys()
555   {
556     return (RowKeySet)getProperty(SELECTED_ROW_KEYS_KEY);
557   }
558 
559   /**
560    * Sets the selection state for this component.
561    * 
562    * @param selectedRowKeys  the new selectedRowKeys value
563    */
564   final public void setSelectedRowKeys(RowKeySet selectedRowKeys)
565   {
566     setProperty(SELECTED_ROW_KEYS_KEY, (selectedRowKeys));
567   }
568 
569   /**
570    * Gets whether or not data validation - client-side or
571    *             server-side -
572    *           should take place when
573    *           events are generated by this component.
574    * 
575    *           When immediate is true, the default ActionListener
576    *           provided by the JavaServer Faces implementation
577    *           should be executed during Apply Request Values phase
578    *           of the request processing lifecycle, rather than
579    *           waiting until the Invoke Application phase.
580    *
581    * @return  the new immediate value
582    */
583   final public boolean isImmediate()
584   {
585     return ComponentUtils.resolveBoolean(getProperty(IMMEDIATE_KEY), false);
586   }
587 
588   /**
589    * Sets whether or not data validation - client-side or
590    *             server-side -
591    *           should take place when
592    *           events are generated by this component.
593    * 
594    *           When immediate is true, the default ActionListener
595    *           provided by the JavaServer Faces implementation
596    *           should be executed during Apply Request Values phase
597    *           of the request processing lifecycle, rather than
598    *           waiting until the Invoke Application phase.
599    * 
600    * @param immediate  the new immediate value
601    */
602   final public void setImmediate(boolean immediate)
603   {
604     setProperty(IMMEDIATE_KEY, immediate ? Boolean.TRUE : Boolean.FALSE);
605   }
606 
607   /**
608    * Gets a method reference to an ExpansionListener
609    *
610    * @return  the new rowDisclosureListener value
611    */
612   final public MethodExpression getRowDisclosureListener()
613   {
614     return (MethodExpression)getProperty(ROW_DISCLOSURE_LISTENER_KEY);
615   }
616 
617   /**
618    * Sets a method reference to an ExpansionListener
619    * 
620    * @param rowDisclosureListener  the new rowDisclosureListener value
621    */
622   final public void setRowDisclosureListener(MethodExpression rowDisclosureListener)
623   {
624     setProperty(ROW_DISCLOSURE_LISTENER_KEY, (rowDisclosureListener));
625   }
626 
627   /**
628    * Gets the set of disclosed rows for this component.
629    * Each entry in the set is a rowKey.
630    *
631    * @return  the new disclosedRowKeys value
632    */
633   final public RowKeySet getDisclosedRowKeys()
634   {
635     return (RowKeySet)getProperty(DISCLOSED_ROW_KEYS_KEY);
636   }
637 
638   /**
639    * Sets the set of disclosed rows for this component.
640    * Each entry in the set is a rowKey.
641    * 
642    * @param disclosedRowKeys  the new disclosedRowKeys value
643    */
644   final public void setDisclosedRowKeys(RowKeySet disclosedRowKeys)
645   {
646     setProperty(DISCLOSED_ROW_KEYS_KEY, (disclosedRowKeys));
647   }
648 
649   /**
650    * Gets a method reference to a selection listener
651    *
652    * @return  the new selectionListener value
653    */
654   final public MethodExpression getSelectionListener()
655   {
656     return (MethodExpression)getProperty(SELECTION_LISTENER_KEY);
657   }
658 
659   /**
660    * Sets a method reference to a selection listener
661    * 
662    * @param selectionListener  the new selectionListener value
663    */
664   final public void setSelectionListener(MethodExpression selectionListener)
665   {
666     setProperty(SELECTION_LISTENER_KEY, (selectionListener));
667   }
668 
669   /**
670    * Gets <html>
671    *           Name of the EL variable used to reference the varStatus information.
672    *           Once this component has completed rendering, this variable is
673    *           removed (or reverted back to its previous value).
674    *           The VarStatus provides contextual information about the state of the
675    *           component to EL expressions. For components that iterate, varStatus
676    *           also provides loop counter information.  Please see the this 
677    *           component's documentation for the specific properties on the varStatus.
678    *           The common properties on varStatus include:
679    *           <ul>
680    *           <li>"model" - returns the CollectionModel for this component</li>
681    *           <li>"index" - returns the zero based row index</li>
682    *           <li>"hierarchicalIndex" - returns an array containing the row indices of heirarchy of the currrent row, for e.g. [0,1,2]
683    *               Please use this attribute with caution since it requires moving currency to calculate the row index for 
684    *               each parent collection in the tree hierarchy.
685    *           </li>
686    *           <li>"hierarchicalLabel" - returns a string label representing the hierarchy of that row, for e.g. 1.1, 1.1.1. 
687    *              It should be noted that the labels are 1 based vs 0 based for rowIndex. 
688    *             Please use this attribute with caution since it requires moving currency to calculate the row index for 
689    *               each parent collection in the tree hierarchy.
690    *           </li>
691    *           </ul></html>
692    *
693    * @return  the new varStatus value
694    */
695   final public String getVarStatus()
696   {
697     return ComponentUtils.resolveString(getProperty(VAR_STATUS_KEY));
698   }
699 
700   /**
701    * Sets <html>
702    *           Name of the EL variable used to reference the varStatus information.
703    *           Once this component has completed rendering, this variable is
704    *           removed (or reverted back to its previous value).
705    *           The VarStatus provides contextual information about the state of the
706    *           component to EL expressions. For components that iterate, varStatus
707    *           also provides loop counter information.  Please see the this 
708    *           component's documentation for the specific properties on the varStatus.
709    *           The common properties on varStatus include:
710    *           <ul>
711    *           <li>"model" - returns the CollectionModel for this component</li>
712    *           <li>"index" - returns the zero based row index</li>
713    *           <li>"hierarchicalIndex" - returns an array containing the row indices of heirarchy of the currrent row, for e.g. [0,1,2]
714    *               Please use this attribute with caution since it requires moving currency to calculate the row index for 
715    *               each parent collection in the tree hierarchy.
716    *           </li>
717    *           <li>"hierarchicalLabel" - returns a string label representing the hierarchy of that row, for e.g. 1.1, 1.1.1. 
718    *              It should be noted that the labels are 1 based vs 0 based for rowIndex. 
719    *             Please use this attribute with caution since it requires moving currency to calculate the row index for 
720    *               each parent collection in the tree hierarchy.
721    *           </li>
722    *           </ul></html>
723    * 
724    * @param varStatus  the new varStatus value
725    */
726   final public void setVarStatus(String varStatus)
727   {
728     setProperty(VAR_STATUS_KEY, (varStatus));
729   }
730 
731   /**
732    * Gets the hierarchy of tree data - must be of type 
733    *         org.apache.myfaces.trinidad.model.TreeModel
734    *
735    * @return  the new value value
736    */
737   final public Object getValue()
738   {
739     return getProperty(VALUE_KEY);
740   }
741 
742   /**
743    * Sets the hierarchy of tree data - must be of type 
744    *         org.apache.myfaces.trinidad.model.TreeModel
745    * 
746    * @param value  the new value value
747    */
748   final public void setValue(Object value)
749   {
750     setProperty(VALUE_KEY, (value));
751   }
752 
753   /**
754    * Gets the rowKey of the currently focused row.
755    *         The rowKeys of the ancestor rows of the focus row are added
756    *         to the expandedRowKeys RowKeySet by default.
757    *
758    * @return  the new focusRowKey value
759    */
760   final public Object getFocusRowKey()
761   {
762     return getProperty(FOCUS_ROW_KEY_KEY);
763   }
764 
765   /**
766    * Sets the rowKey of the currently focused row.
767    *         The rowKeys of the ancestor rows of the focus row are added
768    *         to the expandedRowKeys RowKeySet by default.
769    * 
770    * @param focusRowKey  the new focusRowKey value
771    */
772   final public void setFocusRowKey(Object focusRowKey)
773   {
774     setProperty(FOCUS_ROW_KEY_KEY, (focusRowKey));
775   }
776 
777   /**
778    * Gets a method reference to a focus listener
779    *
780    * @return  the new focusListener value
781    */
782   final public MethodExpression getFocusListener()
783   {
784     return (MethodExpression)getProperty(FOCUS_LISTENER_KEY);
785   }
786 
787   /**
788    * Sets a method reference to a focus listener
789    * 
790    * @param focusListener  the new focusListener value
791    */
792   final public void setFocusListener(MethodExpression focusListener)
793   {
794     setProperty(FOCUS_LISTENER_KEY, (focusListener));
795   }
796 
797   /**
798    * Gets If upon initial rendering, the current subtree under the focused row path
799    *         should be expanded. A RowDisclosureEvent is broadcast from the encode begin of the 
800    *         component so that listeners are properly notified of the disclosure.
801    *
802    * @return  the new initiallyExpanded value
803    */
804   final public boolean isInitiallyExpanded()
805   {
806     return ComponentUtils.resolveBoolean(getProperty(INITIALLY_EXPANDED_KEY), false);
807   }
808 
809   /**
810    * Sets If upon initial rendering, the current subtree under the focused row path
811    *         should be expanded. A RowDisclosureEvent is broadcast from the encode begin of the 
812    *         component so that listeners are properly notified of the disclosure.
813    * 
814    * @param initiallyExpanded  the new initiallyExpanded value
815    */
816   final public void setInitiallyExpanded(boolean initiallyExpanded)
817   {
818     setProperty(INITIALLY_EXPANDED_KEY, initiallyExpanded ? Boolean.TRUE : Boolean.FALSE);
819   }
820 
821   /**
822    * Adds a rowDisclosure listener.
823    *
824    * @param listener  the rowDisclosure listener to add
825    */
826   final public void addRowDisclosureListener(
827     RowDisclosureListener listener)
828   {
829     addFacesListener(listener);
830   }
831 
832   /**
833    * Removes a rowDisclosure listener.
834    *
835    * @param listener  the rowDisclosure listener to remove
836    */
837   final public void removeRowDisclosureListener(
838     RowDisclosureListener listener)
839   {
840     removeFacesListener(listener);
841   }
842 
843   /**
844    * Returns an array of attached rowDisclosure listeners.
845    *
846    * @return  an array of attached rowDisclosure listeners.
847    */
848   final public RowDisclosureListener[] getRowDisclosureListeners()
849   {
850     return (RowDisclosureListener[])getFacesListeners(RowDisclosureListener.class);
851   }
852 
853   /**
854    * Adds a selection listener.
855    *
856    * @param listener  the selection listener to add
857    */
858   final public void addSelectionListener(
859     SelectionListener listener)
860   {
861     addFacesListener(listener);
862   }
863 
864   /**
865    * Removes a selection listener.
866    *
867    * @param listener  the selection listener to remove
868    */
869   final public void removeSelectionListener(
870     SelectionListener listener)
871   {
872     removeFacesListener(listener);
873   }
874 
875   /**
876    * Returns an array of attached selection listeners.
877    *
878    * @return  an array of attached selection listeners.
879    */
880   final public SelectionListener[] getSelectionListeners()
881   {
882     return (SelectionListener[])getFacesListeners(SelectionListener.class);
883   }
884 
885   /**
886    * Adds a focus listener.
887    *
888    * @param listener  the focus listener to add
889    */
890   final public void addFocusListener(
891     FocusListener listener)
892   {
893     addFacesListener(listener);
894   }
895 
896   /**
897    * Removes a focus listener.
898    *
899    * @param listener  the focus listener to remove
900    */
901   final public void removeFocusListener(
902     FocusListener listener)
903   {
904     removeFacesListener(listener);
905   }
906 
907   /**
908    * Returns an array of attached focus listeners.
909    *
910    * @return  an array of attached focus listeners.
911    */
912   final public FocusListener[] getFocusListeners()
913   {
914     return (FocusListener[])getFacesListeners(FocusListener.class);
915   }
916 
917   @Override
918   public String getFamily()
919   {
920     return COMPONENT_FAMILY;
921   }
922 
923   @Override
924   protected FacesBean.Type getBeanType()
925   {
926     return TYPE;
927   }
928 
929   /**
930    * Construct an instance of the UIXTree.
931    */
932   protected UIXTree(
933     String rendererType
934     )
935   {
936     super(rendererType);
937   }
938 
939   static
940   {
941     TYPE.lockAndRegister("org.apache.myfaces.trinidad.Tree","org.apache.myfaces.trinidad.Tree");
942   }
943 }