View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  
19  package org.apache.webapp.admin;
20  
21  
22  import java.io.Serializable;
23  import java.util.ArrayList;
24  
25  
26  /***
27   * <p>An individual node of a tree control represented by an instance of
28   * <code>TreeControl</code>, and rendered by an instance of
29   * <code>TreeControlTag</code>.</p>
30   *
31   * @author Jazmin Jonson
32   * @author Craig R. McClanahan
33   * @version $Revision: 516448 $ $Date: 2007-03-09 17:25:47 +0100 (Fri, 09 Mar 2007) $
34   */
35  
36  public class TreeControlNode implements Serializable 
37  {
38      private static final long serialVersionUID = 1;    
39  
40  
41      // ----------------------------------------------------------- Constructors
42  
43  	/***
44       * Construct a new TreeControlNode with the specified parameters.
45       *
46       * @param name Internal name of this node (must be unique within
47       *  the entire tree)
48       * @param icon Pathname of the image file for the icon to be displayed
49       *  when this node is visible, relative to the image directory
50       *  for our images
51       * @param label The label that will be displayed to the user if
52       *  this node is visible
53       * @param action The hyperlink to be selected if the user
54       *  selects this node, or <code>null</code> if this node's label should
55       *  not be a hyperlink
56       * @param target The window target in which the <code>action</code>
57       *  hyperlink's results will be displayed, or <code>null</code> for
58       *  the current window
59       * @param expanded Should this node be expanded?
60       * @param domain Identifier for the kind of node.
61       */
62  	public TreeControlNode(String name,
63              String icon, String label,
64              String action, String target,
65              boolean expanded, String domain) {
66  		this(name, icon, label, action, target, expanded, domain, null, false);
67  	}
68  	
69  	/***
70       * Construct a new TreeControlNode with the specified parameters.
71       *
72       * @param name Internal name of this node (must be unique within
73       *  the entire tree)
74       * @param icon Pathname of the image file for the icon to be displayed
75       *  when this node is visible, relative to the image directory
76       *  for our images
77       * @param label The label that will be displayed to the user if
78       *  this node is visible
79       * @param action The hyperlink to be selected if the user
80       *  selects this node, or <code>null</code> if this node's label should
81       *  not be a hyperlink
82       * @param target The window target in which the <code>action</code>
83       *  hyperlink's results will be displayed, or <code>null</code> for
84       *  the current window
85       * @param expanded Should this node be expanded?
86       * @param domain Identifier for the kind of node.
87       * @param CSSClass The css class to apply to the node
88       */
89  	public TreeControlNode(String name,
90              String icon, String label,
91              String action, String target,
92              boolean expanded, String domain, String CSSClass) {
93  		this(name, icon, label, action, target, expanded, domain, CSSClass, false);
94  	}
95  
96      /***
97       * Construct a new TreeControlNode with the specified parameters.
98       *
99       * @param name Internal name of this node (must be unique within
100      *  the entire tree)
101      * @param icon Pathname of the image file for the icon to be displayed
102      *  when this node is visible, relative to the image directory
103      *  for our images
104      * @param label The label that will be displayed to the user if
105      *  this node is visible
106      * @param action The hyperlink to be selected if the user
107      *  selects this node, or <code>null</code> if this node's label should
108      *  not be a hyperlink
109      * @param target The window target in which the <code>action</code>
110      *  hyperlink's results will be displayed, or <code>null</code> for
111      *  the current window
112      * @param expanded Should this node be expanded?
113      * @param domain Identifier for the kind of node.
114      * @param CSSClass The css class to apply to the node
115      * @param lazy Is this node's children lazy loaded?
116      */
117     public TreeControlNode(String name,
118                            String icon, String label,
119                            String action, String target,
120                            boolean expanded, String domain, String CSSClass,
121 						   boolean lazy) {
122 
123         super();
124         this.name = name;
125         this.icon = icon;
126         this.label = label;
127         this.action = action;
128         this.target = target;
129         this.expanded = expanded;
130         this.domain = domain;
131         this.CSSClass = CSSClass;
132         this.lazy = lazy;
133         this.loaded = false;
134     }
135 
136 
137     // ----------------------------------------------------- Instance Variables
138 
139 
140     /***
141      * The set of child <code>TreeControlNodes</code> for this node, in the
142      * order that they should be displayed.
143      */
144     protected ArrayList children = new ArrayList();
145 
146 
147     // ------------------------------------------------------------- Properties
148 
149 
150     /***
151      * The hyperlink to which control will be directed if this node
152      * is selected by the user.
153      */
154     protected String action = null;
155 
156     public String getAction() {
157         return (this.action);
158     }
159 
160     /***
161      * The domain of this node.
162      */
163     protected String domain = null;
164 
165     public String getDomain() {
166         return (this.domain);
167     }
168 
169     /***
170      * Is this node currently expanded?
171      */
172     protected boolean expanded = false;
173 
174     public boolean isExpanded() {
175         return (this.expanded);
176     }
177 
178     public void setExpanded(boolean expanded) {
179         this.expanded = expanded;
180     }
181 
182 
183     /***
184      * The pathname to the icon file displayed when this node is visible,
185      * relative to the image directory for our images.
186      */
187     protected String icon = null;
188 
189     public String getIcon() {
190         return (this.icon);
191     }
192 
193 
194     /***
195      * The label that will be displayed when this node is visible.
196      */
197     protected String label = null;
198 
199     public String getLabel() {
200         return (this.label);
201     }
202     
203     /***
204      * The label that will be displayed when this node is visible.
205      */
206     protected String title = null;
207 
208     public String getTitle() {
209         return (this.title);
210     }
211     
212     public void setTitle(String title)
213     {
214         this.title = title;
215     }
216 
217     public void setLabel(String label)
218     {
219         this.label = label;
220     }
221     
222 
223     /***
224      * Is this the last node in the set of children for our parent node?
225      */
226     protected boolean last = false;
227 
228     public boolean isLast() {
229         return (this.last);
230     }
231 
232     void setLast(boolean last) {
233         this.last = last;
234     }
235     
236     protected boolean lazy = false;
237     
238     public boolean isLazy() {
239     	return (this.lazy);
240     }
241 
242 
243     /***
244      * Is this a "leaf" node (i.e. one with no children)?
245      */
246     protected boolean leaf = true;
247     
248     public boolean isLeaf() {
249     	if(lazy)
250     	{
251     		return leaf;
252     	}
253     	else
254     	{
255 	        synchronized (children) {
256 	            return (children.size() < 1);
257 	        }
258     	}
259     }
260     
261     public void setLeaf(boolean leaf)
262     {
263     	this.leaf = leaf;
264     }
265     
266     protected boolean loaded = false;
267     
268     public boolean isLoaded() {
269     	return (this.loaded);
270     }
271     
272     public void setLoaded(boolean loaded)
273     {
274     	this.loaded = loaded;
275     }
276 
277 
278     /***
279      * The unique (within the entire tree) name of this node.
280      */
281     protected String name = null;
282 
283     public String getName() {
284         return (this.name);
285     }
286 
287 
288     /***
289      * The parent node of this node, or <code>null</code> if this
290      * is the root node.
291      */
292     protected TreeControlNode parent = null;
293 
294     public TreeControlNode getParent() {
295         return (this.parent);
296     }
297 
298     void setParent(TreeControlNode parent) {
299         this.parent = parent;
300         if (parent == null)
301             width = 1;
302         else
303             width = parent.getWidth() + 1;
304     }
305 
306 
307     /***
308      * Is this node currently selected?
309      */
310     protected boolean selected = false;
311 
312     public boolean isSelected() {
313         return (this.selected);
314     }
315 
316     public void setSelected(boolean selected) {
317         this.selected = selected;
318     }
319 
320 
321     /***
322      * The window target for the hyperlink identified by the
323      * <code>action</code> property, if this node is selected
324      * by the user.
325      */
326     protected String target = null;
327 
328     public String getTarget() {
329         return (this.target);
330     }
331 
332 
333     /***
334      * The <code>TreeControl</code> instance representing the
335      * entire tree.
336      */
337     protected TreeControl tree = null;
338 
339     public TreeControl getTree() {
340         return (this.tree);
341     }
342 
343     void setTree(TreeControl tree) {
344         this.tree = tree;
345     }
346 
347 
348     /***
349      * The display width necessary to display this item (if it is visible).
350      * If this item is not visible, the calculated width will be that of our
351      * most immediately visible parent.
352      */
353     protected int width = 0;
354 
355     public int getWidth() {
356         return (this.width);
357     }
358     
359     protected String CSSClass;
360     
361     /***
362 	 * @return Returns the cSSClass.
363 	 */
364 	public String getCSSClass() {
365 		return CSSClass;
366 	}
367 	/***
368 	 * @param class1 The cSSClass to set.
369 	 */
370 	public void setCSSClass(String CSSClass) {
371 		this.CSSClass = CSSClass;
372 	}
373     
374     protected boolean expandWhenClicked = false;
375     
376     public boolean isExpandWhenClicked()
377     {
378         return expandWhenClicked;
379     }
380     
381     public void setExpandWhenClicked(boolean expandWhenClicked)
382     {
383         this.expandWhenClicked = expandWhenClicked;
384     }
385     
386 
387     // --------------------------------------------------------- Public Methods
388 
389 
390     /***
391      * Add a new child node to the end of the list.
392      *
393      * @param child The new child node
394      *
395      * @exception IllegalArgumentException if the name of the new child
396      *  node is not unique
397      */
398     public void addChild(TreeControlNode child)
399         throws IllegalArgumentException {
400 
401         tree.addNode(child);
402         child.setParent(this);
403         synchronized (children) {
404             int n = children.size();
405             if (n > 0) {
406                 TreeControlNode node = (TreeControlNode) children.get(n - 1);
407                 node.setLast(false);
408             }
409             child.setLast(true);
410             children.add(child);
411         }
412 
413     }
414 
415 
416     /***
417      * Add a new child node at the specified position in the child list.
418      *
419      * @param offset Zero-relative offset at which the new node
420      *  should be inserted
421      * @param child The new child node
422      *
423      * @exception IllegalArgumentException if the name of the new child
424      *  node is not unique
425      */
426     public void addChild(int offset, TreeControlNode child)
427         throws IllegalArgumentException {
428 
429         tree.addNode(child);
430         child.setParent(this);
431         synchronized (children) {
432             children.add(offset, child);
433         }
434 
435     }
436 
437 
438     /***
439      * Return the set of child nodes for this node.
440      */
441     public TreeControlNode[] findChildren() {
442 
443         synchronized (children) {
444             TreeControlNode results[] = new TreeControlNode[children.size()];
445             return ((TreeControlNode[]) children.toArray(results));
446         }
447 
448     }
449 
450 
451     /***
452      * Remove this node from the tree.
453      */
454     public void remove() {
455 
456         if (tree != null) {
457             tree.removeNode(this);
458         }
459 
460     }
461 
462 
463     /***
464      * Remove the child node (and all children of that child) at the
465      * specified position in the child list.
466      *
467      * @param offset Zero-relative offset at which the existing
468      *  node should be removed
469      */
470     public void removeChild(int offset) {
471 
472         synchronized (children) {
473             TreeControlNode child =
474                 (TreeControlNode) children.get(offset);
475             tree.removeNode(child);
476             child.setParent(null);
477             children.remove(offset);
478         }
479 
480     }
481 
482 
483     // -------------------------------------------------------- Package Methods
484 
485 
486     /***
487      * Remove the specified child node.  It is assumed that all of the
488      * children of this child node have already been removed.
489      *
490      * @param child Child node to be removed
491      */
492     void removeChild(TreeControlNode child) {
493 
494         if (child == null) {
495             return;
496         }
497         synchronized (children) {
498             int n = children.size();
499             for (int i = 0; i < n; i++) {
500                 if (child == (TreeControlNode) children.get(i)) {
501                     children.remove(i);
502                     return;
503                 }
504             }
505         }
506 
507     }
508 }