001: /*
002: * $Header$
003: * $Revision: 3530 $
004: * $Date: 2003-10-16 12:17:28 +0000 (Thu, 16 Oct 2003) $
005: *
006: * ====================================================================
007: *
008: * The Apache Software License, Version 1.1
009: *
010: * Copyright (c) 2001 The Apache Software Foundation. All rights
011: * reserved.
012: *
013: * Redistribution and use in source and binary forms, with or without
014: * modification, are permitted provided that the following conditions
015: * are met:
016: *
017: * 1. Redistributions of source code must retain the above copyright
018: * notice, this list of conditions and the following disclaimer.
019: *
020: * 2. Redistributions in binary form must reproduce the above copyright
021: * notice, this list of conditions and the following disclaimer in
022: * the documentation and/or other materials provided with the
023: * distribution.
024: *
025: * 3. The end-user documentation included with the redistribution, if
026: * any, must include the following acknowlegement:
027: * "This product includes software developed by the
028: * Apache Software Foundation (http://www.apache.org/)."
029: * Alternately, this acknowlegement may appear in the software itself,
030: * if and wherever such third-party acknowlegements normally appear.
031: *
032: * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
033: * Foundation" must not be used to endorse or promote products derived
034: * from this software without prior written permission. For written
035: * permission, please contact apache@apache.org.
036: *
037: * 5. Products derived from this software may not be called "Apache"
038: * nor may "Apache" appear in their names without prior written
039: * permission of the Apache Group.
040: *
041: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
042: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
043: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
044: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
045: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
046: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
047: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
048: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
049: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
050: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
051: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
052: * SUCH DAMAGE.
053: * ====================================================================
054: *
055: * This software consists of voluntary contributions made by many
056: * individuals on behalf of the Apache Software Foundation. For more
057: * information on the Apache Software Foundation, please see
058: * <http://www.apache.org/>.
059: *
060: */
061:
062: package org.objectweb.jonas.webapp.taglib;
063:
064: import java.io.Serializable;
065: import java.util.ArrayList;
066:
067: /**
068: * <p>An individual node of a tree control represented by an instance of
069: * <code>TreeControl</code>, and rendered by an instance of
070: * <code>TreeControlTag</code>.</p>
071: *
072: * @author Jazmin Jonson
073: * @author Craig R. McClanahan
074: * @version $Revision: 3530 $
075: */
076:
077: public class TreeControlNode implements Serializable {
078:
079: // ----------------------------------------------------------- Constructors
080:
081: /**
082: * Construct a new TreeControlNode with the specified parameters.
083: *
084: * @param name Internal name of this node (must be unique within
085: * the entire tree)
086: * @param icon Pathname of the image file for the icon to be displayed
087: * when this node is visible, relative to the image directory
088: * for our images
089: * @param label The label that will be displayed to the user if
090: * this node is visible
091: * @param action The hyperlink to be selected if the user
092: * selects this node, or <code>null</code> if this node's label should
093: * not be a hyperlink
094: * @param target The window target in which the <code>action</code>
095: * hyperlink's results will be displayed, or <code>null</code> for
096: * the current window
097: * @param expanded Should this node be expanded?
098: */
099: public TreeControlNode(String name, String icon, String label,
100: String action, String target, boolean expanded) {
101:
102: super ();
103: this .name = name;
104: this .icon = icon;
105: this .label = label;
106: this .action = action;
107: this .target = target;
108: this .expanded = expanded;
109:
110: }
111:
112: public TreeControlNode(TreeControlNode p_Node) {
113: super ();
114: this .name = p_Node.getName();
115: this .icon = p_Node.getIcon();
116: this .label = p_Node.getLabel();
117: this .action = p_Node.getAction();
118: this .target = p_Node.getTarget();
119: this .expanded = p_Node.isExpanded();
120: }
121:
122: // ----------------------------------------------------- Instance Variables
123:
124: /**
125: * The set of child <code>TreeControlNodes</code> for this node, in the
126: * order that they should be displayed.
127: */
128: protected ArrayList children = new ArrayList();
129:
130: // ------------------------------------------------------------- Properties
131:
132: /**
133: * The hyperlink to which control will be directed if this node
134: * is selected by the user.
135: */
136: protected String action = null;
137:
138: public String getAction() {
139: return (this .action);
140: }
141:
142: /**
143: * Is this node currently expanded?
144: */
145: protected boolean expanded = false;
146:
147: public boolean isExpanded() {
148: return (this .expanded);
149: }
150:
151: public void setExpanded(boolean expanded) {
152: this .expanded = expanded;
153: }
154:
155: /**
156: * The pathname to the icon file displayed when this node is visible,
157: * relative to the image directory for our images.
158: */
159: protected String icon = null;
160:
161: public String getIcon() {
162: return (this .icon);
163: }
164:
165: /**
166: * The label that will be displayed when this node is visible.
167: */
168: protected String label = null;
169:
170: public String getLabel() {
171: return (this .label);
172: }
173:
174: /**
175: * Is this the last node in the set of children for our parent node?
176: */
177: protected boolean last = false;
178:
179: public boolean isLast() {
180: return (this .last);
181: }
182:
183: void setLast(boolean last) {
184: this .last = last;
185: }
186:
187: /**
188: * Is this a "leaf" node (i.e. one with no children)?
189: */
190: public boolean isLeaf() {
191: synchronized (children) {
192: return (children.size() < 1);
193: }
194: }
195:
196: /**
197: * The unique (within the entire tree) name of this node.
198: */
199: protected String name = null;
200:
201: public String getName() {
202: return (this .name);
203: }
204:
205: /**
206: * The parent node of this node, or <code>null</code> if this
207: * is the root node.
208: */
209: protected TreeControlNode parent = null;
210:
211: public TreeControlNode getParent() {
212: return (this .parent);
213: }
214:
215: void setParent(TreeControlNode parent) {
216: this .parent = parent;
217: if (parent == null) {
218: width = 1;
219: } else {
220: width = parent.getWidth() + 1;
221: }
222: }
223:
224: /**
225: * Is this node currently selected?
226: */
227: protected boolean selected = false;
228:
229: public boolean isSelected() {
230: return (this .selected);
231: }
232:
233: public void setSelected(boolean selected) {
234: this .selected = selected;
235: }
236:
237: /**
238: * The window target for the hyperlink identified by the
239: * <code>action</code> property, if this node is selected
240: * by the user.
241: */
242: protected String target = null;
243:
244: public String getTarget() {
245: return (this .target);
246: }
247:
248: /**
249: * The <code>TreeControl</code> instance representing the
250: * entire tree.
251: */
252: protected TreeControl tree = null;
253:
254: public TreeControl getTree() {
255: return (this .tree);
256: }
257:
258: void setTree(TreeControl tree) {
259: this .tree = tree;
260: }
261:
262: /**
263: * The display width necessary to display this item (if it is visible).
264: * If this item is not visible, the calculated width will be that of our
265: * most immediately visible parent.
266: */
267: protected int width = 0;
268:
269: public int getWidth() {
270: return (this .width);
271: }
272:
273: // --------------------------------------------------------- Public Methods
274:
275: /**
276: * Add a new child node to the end of the list.
277: *
278: * @param child The new child node
279: *
280: * @exception IllegalArgumentException if the name of the new child
281: * node is not unique
282: */
283: public void addChild(TreeControlNode child)
284: throws IllegalArgumentException {
285:
286: tree.addNode(child);
287: child.setParent(this );
288: synchronized (children) {
289: int n = children.size();
290: if (n > 0) {
291: TreeControlNode node = (TreeControlNode) children
292: .get(n - 1);
293: node.setLast(false);
294: }
295: child.setLast(true);
296: children.add(child);
297: }
298:
299: }
300:
301: /**
302: * Add a new child node at the specified position in the child list.
303: *
304: * @param offset Zero-relative offset at which the new node
305: * should be inserted
306: * @param child The new child node
307: *
308: * @exception IllegalArgumentException if the name of the new child
309: * node is not unique
310: */
311: public void addChild(int offset, TreeControlNode child)
312: throws IllegalArgumentException {
313:
314: tree.addNode(child);
315: child.setParent(this );
316: synchronized (children) {
317: children.add(offset, child);
318: }
319:
320: }
321:
322: /**
323: * Return the set of child nodes for this node.
324: */
325: public TreeControlNode[] findChildren() {
326:
327: synchronized (children) {
328: TreeControlNode results[] = new TreeControlNode[children
329: .size()];
330: return ((TreeControlNode[]) children.toArray(results));
331: }
332:
333: }
334:
335: /**
336: * Remove this node from the tree.
337: */
338: public void remove() {
339:
340: if (tree != null) {
341: tree.removeNode(this );
342: }
343:
344: }
345:
346: /**
347: * Remove the child node (and all children of that child) at the
348: * specified position in the child list.
349: *
350: * @param offset Zero-relative offset at which the existing
351: * node should be removed
352: */
353: public void removeChild(int offset) {
354:
355: synchronized (children) {
356: TreeControlNode child = (TreeControlNode) children
357: .get(offset);
358: tree.removeNode(child);
359: child.setParent(null);
360: children.remove(offset);
361: }
362:
363: }
364:
365: public String toString() {
366: StringBuffer sb = new StringBuffer();
367: sb.append(getName());
368: sb.append(" - ");
369: sb.append(isExpanded());
370:
371: return sb.toString();
372: }
373:
374: // -------------------------------------------------------- Package Methods
375:
376: /**
377: * Remove the specified child node. It is assumed that all of the
378: * children of this child node have already been removed.
379: *
380: * @param child Child node to be removed
381: */
382: void removeChild(TreeControlNode child) {
383:
384: if (child == null) {
385: return;
386: }
387: synchronized (children) {
388: int n = children.size();
389: for (int i = 0; i < n; i++) {
390: if (child == (TreeControlNode) children.get(i)) {
391: children.remove(i);
392: return;
393: }
394: }
395: }
396:
397: }
398:
399: }
|