View Javadoc

1   /*
2   * The contents of this file are subject to the BT "ZEUS" Open Source 
3   * Licence (L77741), Version 1.0 (the "Licence"); you may not use this file 
4   * except in compliance with the Licence. You may obtain a copy of the Licence
5   * from $ZEUS_INSTALL/licence.html or alternatively from
6   * http://www.labs.bt.com/projects/agents/zeus/licence.htm
7   * 
8   * Except as stated in Clause 7 of the Licence, software distributed under the
9   * Licence is distributed WITHOUT WARRANTY OF ANY KIND, either express or 
10  * implied. See the Licence for the specific language governing rights and 
11  * limitations under the Licence.
12  * 
13  * The Original Code is within the package zeus.*.
14  * The Initial Developer of the Original Code is British Telecommunications
15  * public limited company, whose registered office is at 81 Newgate Street, 
16  * London, EC1A 7AJ, England. Portions created by British Telecommunications 
17  * public limited company are Copyright 1996-9. All Rights Reserved.
18  * 
19  * THIS NOTICE MUST BE INCLUDED ON ANY COPY OF THIS FILE
20  */
21  
22  
23  
24  package zeus.util;
25  
26  import java.util.*;
27  
28  public class TreeNode {
29     protected static final int NODES  = 0;
30     protected static final int VALUES = 1;
31  
32     protected Object data = null;
33     protected Vector children = null;
34     protected TreeNode parent = null;
35  
36     public TreeNode(TreeNode parent, Object data) {
37        children = new Vector();
38        setParent(parent);
39        setValue(data);
40     }
41     public TreeNode(Object data) {
42        children = new Vector();
43        setValue(data);
44     }
45  
46     class PreorderEnumerator implements Enumeration {
47        TreeNode current = null;
48        TreeNode root = null;
49        int type;
50  
51        public PreorderEnumerator(TreeNode node, int type) {
52           root = current = node;
53           this.type = type;
54        }
55        public boolean hasMoreElements() {
56           return current != null;
57        }
58        public Object nextElement() {
59           if ( current == null ) throw new NoSuchElementException();
60  
61           TreeNode token = current;
62  
63           current = token.firstChild();
64           if ( current == null && token != root )
65              current = token.nextSibling();
66           if ( current == null ) {
67              TreeNode parent = (token == root) ? null : token.getParent();
68              while( parent != null && parent != root && 
69                     (current = parent.nextSibling()) == null )
70                 parent = (parent == root) ? null : parent.getParent();
71           }
72           
73           if (type == NODES )
74              return token;
75           else if ( token != null )
76              return token.getValue();
77           else
78              return null;
79        }
80     }
81  
82     public Enumeration values() {
83        return new PreorderEnumerator(this, VALUES);
84     }
85     public Enumeration nodes() {
86        return new PreorderEnumerator(this, NODES);
87     }
88  
89     public boolean  isRoot()      { return parent == null; }
90     public boolean  isTerminal()  { return children.isEmpty(); }
91     public boolean  hasChildren() { return !children.isEmpty(); }
92     public TreeNode getParent()   { return parent; }
93     public Object   getValue()    { return data; }
94  
95     public void setValue(Object value) {
96        Assert.notNull(value);
97        data = value;
98     }
99  
100    public Vector getChildren() {
101       Vector result = new Vector();
102       for(int i = 0; i < children.size(); i++ ) 
103          result.addElement(children.elementAt(i));
104       return result;
105    }
106    public boolean hasChild(TreeNode child) {
107       return children.contains(child);
108    }
109    public void setParent(TreeNode parent) {
110       this.parent = parent;
111    }
112    public boolean containsValue(Object data) {
113       if ( this.data.equals(data) ) return true;
114       boolean status = false;
115       TreeNode node;
116       for(int i = 0; !status && i < children.size(); i++ ) {
117          node = (TreeNode)children.elementAt(i);
118          status |= node.containsValue(data);
119       }
120       return status;
121    }
122    public TreeNode addChild(TreeNode node) {
123       node.setParent(this);
124       children.addElement(node);
125       return node;
126    }
127    public TreeNode addChild(Object data) {
128       TreeNode node = new TreeNode(this,data);
129       children.addElement(node);
130       return node;
131    }
132    public TreeNode addChild(TreeNode node, int position) {
133       Assert.notFalse(position >= 0 && position <= children.size());
134       node.setParent(this);
135       children.insertElementAt(node,position);
136       return node;
137    }
138    public TreeNode addChild(Object data, int position) {
139       Assert.notFalse(position >= 0 && position <= children.size());
140       TreeNode node = new TreeNode(this,data);
141       children.insertElementAt(node,position);
142       return node;
143    }
144    public void removeChild(TreeNode node) {
145       children.removeElement(node);
146    }
147    public void removeChild(int position) {
148       Assert.notFalse(position >= 0 && position < children.size());
149       children.removeElementAt(position);
150    }
151    public TreeNode addBefore(Object data) {
152       Assert.notNull(parent);
153       TreeNode node = new TreeNode(parent,data);
154       parent.addBefore(node,this);
155       return node;
156    }
157    public TreeNode addBefore(TreeNode node) {
158       Assert.notNull(parent);
159       node.setParent(parent);
160       parent.addBefore(node,this);
161       return node;
162    }
163    public TreeNode addAfter(Object data) {
164       Assert.notNull(parent);
165       TreeNode node = new TreeNode(parent,data);
166       parent.addAfter(node,this);
167       return node;
168    }
169    public TreeNode addAfter(TreeNode node) {
170       Assert.notNull(parent);
171       node.setParent(parent);
172       parent.addAfter(node,this);
173       return node;
174    }
175    protected void addBefore(TreeNode node, TreeNode me) {
176       for(int i = 0; i < children.size(); i++ ) {
177          if ( children.elementAt(i).equals(me) ) {
178             children.insertElementAt(node,i);
179             return;
180          }
181       }
182       Assert.notNull(null);
183    }
184    
185    protected void addAfter(TreeNode node, TreeNode me) {
186       for(int i = 0; i < children.size(); i++ ) {
187          if ( children.elementAt(i).equals(me) ) {
188             children.insertElementAt(node,i+1);
189             return;
190          }
191       }
192       Assert.notNull(null);
193    }
194    public TreeNode nextSibling() {
195       return parent != null ? parent.nextSibling(this) : null;
196    }
197    public TreeNode previousSibling() {
198       return parent != null ? parent.previousSibling(this) : null;
199    }
200    protected TreeNode nextSibling(TreeNode me) {
201       for(int i = 0; i < children.size(); i++ ) {
202          if ( children.elementAt(i).equals(me) ) {
203             if ( i+1 < children.size() )
204                return (TreeNode)children.elementAt(i+1);
205             else 
206                return null;
207          }
208       }
209       Assert.notNull(null); // I am not in my dad's list of children
210       return null;
211    }
212    protected TreeNode previousSibling(TreeNode me) {
213       for(int i = 0; i < children.size(); i++ ) {
214          if ( children.elementAt(i).equals(me) ) {
215             if ( i-1 >= 0  )
216                return (TreeNode)children.elementAt(i-1);
217             else 
218                return null;
219          }
220       }
221       Assert.notNull(null); // I am not in my dad's list of children
222       return null;
223    }
224    public TreeNode firstChild() {
225       return children.isEmpty() ? null : (TreeNode)children.elementAt(0);
226    }
227    public String toString() {
228       return data.toString();
229    }
230 }