View Javadoc

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 org.apache.myfaces.custom.tree2;
20  
21  import javax.faces.component.UICommand;
22  import javax.faces.component.html.HtmlCommandLink;
23  import javax.faces.context.FacesContext;
24  import javax.faces.el.MethodBinding;
25  import javax.faces.el.ValueBinding;
26  
27  import org.apache.myfaces.component.LocationAware;
28  
29  import java.util.Map;
30  
31  /**
32   * Represents "tree data" in an HTML format.  Also provides a mechanism for maintaining expand/collapse
33   * state of the nodes in the tree.
34   *
35   * A component that provides an HTML-based tree from data supplied by a 
36   * backing bean. The tree is highly customizable and allows for 
37   * fine-grained control over the appearance of each of the nodes 
38   * depending on their type. 
39   * 
40   * Almost any type of JSF component (text, image, checkbox, etc.) can 
41   * be rendered inside the nodes and there is an option for client-side 
42   * or server-side toggling of the expand/collapse state. 
43   * 
44   * Unless otherwise specified, all attributes accept static values or EL expressions.
45   * 
46   * @JSFComponent
47   *   name = "t:tree2"
48   *   class = "org.apache.myfaces.custom.tree2.HtmlTree"
49   *   tagClass = "org.apache.myfaces.custom.tree2.TreeTag"
50   * @since 1.1.7
51   * @author Sean Schofield
52   */
53  public abstract class AbstractHtmlTree extends UITreeData
54      implements LocationAware
55  {
56      public static final String COMPONENT_TYPE = "org.apache.myfaces.HtmlTree2";
57      private static final String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.HtmlTree2";
58  
59      private UICommand _expandControl = null;
60      
61      //public abstract boolean isClientSideToggle();
62      
63      // Property: clientSideToggle
64      private boolean _clientSideToggle = true;
65      private boolean _clientSideToggleSet;
66  
67      /**
68       * Perform client-side toggling of expand/collapse state via javascript (default is true.)
69       * 
70       * @JSFProperty
71       *   defaultValue = "true"
72       * @return  the new clientSideToggle value
73       */
74      public boolean isClientSideToggle()
75      {
76        if (_clientSideToggleSet)
77        {
78          return _clientSideToggle;
79        }
80        ValueBinding expression = getValueBinding("clientSideToggle");
81        if (expression != null)
82        {
83          return ((Boolean)expression.getValue(getFacesContext())).booleanValue();
84        }
85        return true;
86      }
87  
88      /**
89       * Sets 
90       * 
91       * @param clientSideToggle  the new clientSideToggle value
92       */
93      public void setClientSideToggle(boolean clientSideToggle)
94      {
95        this._clientSideToggle = clientSideToggle;
96        this._clientSideToggleSet = true;
97      }
98      
99      
100     /**
101      * @see org.apache.myfaces.custom.tree2.UITreeData#processNodes(javax.faces.context.FacesContext, int, org.apache.myfaces.custom.tree2.TreeWalker)
102      */
103     protected void processNodes(FacesContext context, int processAction, TreeWalker walker)
104     {
105         if (isClientSideToggle()) {
106             walker.setCheckState(false);
107         }
108         super.processNodes(context, processAction, walker);
109     }
110     
111     //public abstract String getLocalVarNodeToggler();
112 
113     // see superclass for documentation
114     public void setNodeId(String nodeId)
115     {
116         super.setNodeId(nodeId);
117 
118         if (_varNodeToggler != null)
119         {
120             Map requestMap = getFacesContext().getExternalContext().getRequestMap();
121             requestMap.put(_varNodeToggler, this);
122         }
123     }
124 
125     /**
126      * Gets the expand/collapse control that can be used to handle expand/collapse nodes.  This is only used in server-side
127      * mode.  It allows the nagivation controls (if any) to be clickable as well as any commandLinks the user has set up in
128      * their JSP.
129      * 
130      * @return UICommand
131      */
132     public UICommand getExpandControl()
133     {
134         if (_expandControl == null){
135             _expandControl = new HtmlCommandLink();
136             _expandControl.setParent(this);
137         }
138         return _expandControl;
139     }
140     
141     // Property: varNodeToggler
142     private String _varNodeToggler;
143 
144     /**
145      * Gets 
146      *
147      * @JSFProperty
148      * @return  the new varNodeToggler value
149      */
150     public String getVarNodeToggler()
151     {
152       return _varNodeToggler;
153     }
154     
155     public void setVarNodeToggler(String varNodeToggler)
156     {
157         _varNodeToggler = varNodeToggler;
158 
159         // create a method binding for the expand control
160         String bindingString = "#{" + varNodeToggler + ".toggleExpanded}";
161         MethodBinding actionBinding = FacesContext.getCurrentInstance().getApplication().createMethodBinding(bindingString, null);
162         getExpandControl().setAction(actionBinding);
163     }
164     
165     public Object saveState(FacesContext facesContext)
166     {
167       Object[] values = new Object[4];
168       values[0] = super.saveState(facesContext);
169       values[1] = _varNodeToggler;
170       values[2] = Boolean.valueOf(_clientSideToggle);
171       values[3] = Boolean.valueOf(_clientSideToggleSet);
172 
173       return values;
174     }
175 
176     public void restoreState(FacesContext facesContext, Object state)
177     {
178       Object[] values = (Object[])state;
179       super.restoreState(facesContext,values[0]);
180       _varNodeToggler = (String)values[1];
181       _clientSideToggle = ((Boolean)values[2]).booleanValue();
182       _clientSideToggleSet = ((Boolean)values[3]).booleanValue();
183       
184     }
185         
186     /**
187      * Show the "plus" and "minus" navigation icons (default is true.) 
188      * Value is ignored if clientSideToggle is true.
189      * 
190      * @JSFProperty
191      *   defaultValue = "true"
192      */
193     public abstract boolean isShowNav();
194 
195     /**
196      * Show the connecting lines (default is true.)
197      * 
198      * @JSFProperty
199      *   defaultValue = "true"
200      */
201     public abstract boolean isShowLines();
202 
203     /**
204      * Include the root node when rendering the tree (default is true.)
205      * 
206      * @JSFProperty
207      *   defaultValue = "true"
208      */
209     public abstract boolean isShowRootNode();
210 
211     /**
212      * Preserve changes in client-side toggle information between 
213      * requests (default is true.)
214      * 
215      * @JSFProperty
216      *   defaultValue = "true"
217      */
218     public abstract boolean isPreserveToggle();
219 
220 }