KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > dtree > AbstractDataTree


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.internal.dtree;
12
13 import org.eclipse.core.internal.utils.Messages;
14 import org.eclipse.core.runtime.IPath;
15 import org.eclipse.core.runtime.Path;
16 import org.eclipse.osgi.util.NLS;
17
18 /**
19  * Data trees can be viewed as generic multi-leaf trees. The tree points to a single
20  * rootNode, and each node can contain an arbitrary number of children.<p>
21  *
22  * <p>Internally, data trees can be either complete trees (DataTree class), or delta
23  * trees (<code>DeltaDataTree</code> class). A DataTree is a stand-alone tree
24  * that contains all its own data. A <code>DeltaDataTree</code> only stores the
25  * differences between itself and its parent tree. This sparse representation allows
26  * the API user to retain chains of delta trees that represent incremental changes to
27  * a system. Using the delta trees, the user can undo changes to a tree by going up to
28  * the parent tree.
29  *
30  * <p>Both representations of the tree support the same API, so the user of a tree
31  * never needs to know if they're dealing with a complete tree or a chain of deltas.
32  * Delta trees support an extended API of delta operations. See the <code>DeltaDataTree
33  * </code> class for details.
34  *
35  * @see DataTree
36  * @see DeltaDataTree
37  */

38
39 public abstract class AbstractDataTree {
40
41     /**
42      * Whether modifications to the given source tree are allowed
43      */

44     private boolean immutable = false;
45
46     /**
47      * Singleton indicating no children
48      */

49     protected static final IPath[] NO_CHILDREN = new IPath[0];
50
51     /**
52      * Creates a new empty tree
53      */

54     public AbstractDataTree() {
55         this.empty();
56     }
57
58     /**
59      * Returns a copy of the receiver, which shares the receiver's
60      * instance variables.
61      */

62     protected AbstractDataTree copy() {
63         AbstractDataTree newTree = this.createInstance();
64         newTree.setImmutable(this.isImmutable());
65         newTree.setRootNode(this.getRootNode());
66         return newTree;
67     }
68
69     /**
70      * Returns a copy of the node subtree rooted at the given key.
71      *
72      */

73     public abstract AbstractDataTreeNode copyCompleteSubtree(IPath key);
74
75     /**
76      * Creates a new child in the tree. If a child with such a name exists,
77      * it is replaced with the new child
78      *
79      * @param parentKey key of parent for new child.
80      * @param localName name for new child.
81      * @exception ObjectNotFoundException
82      * parentKey does not exist in the receiver
83      * @exception RuntimeException
84      * receiver is immutable
85      */

86     public abstract void createChild(IPath parentKey, String JavaDoc localName);
87
88     /**
89      * Creates a new child in the tree. If a child with such a name exists,
90      * it is replaced with the new child
91      *
92      * @param parentKey key of parent for new child.
93      * @param localName name for new child.
94      * @param object the data for the new child
95      * @exception ObjectNotFoundException
96      * parentKey does not exist in the receiver
97      * @exception RuntimeException
98      * receiver is immutable
99      */

100     public abstract void createChild(IPath parentKey, String JavaDoc localName, Object JavaDoc object);
101
102     /**
103      * Creates and returns a new instance of the tree. This is an
104      * implementation of the factory method creational pattern for allowing
105      * abstract methods to create instances.
106      *
107      * @return the new tree.
108      */

109     protected abstract AbstractDataTree createInstance();
110
111     /**
112      * Creates or replaces a subtree in the tree. The parent node must exist.
113      *
114      * @param key key of parent of subtree to create/replace
115      * @param subtree new subtree to add to tree
116      * @exception RuntimeException receiver is immutable
117      */

118     public abstract void createSubtree(IPath key, AbstractDataTreeNode subtree);
119
120     /**
121      * Deletes a child from the tree.
122      *
123      * <p>Note: this method requires both parentKey and localName,
124      * making it impossible to delete the root node.
125      *
126      * @param parentKey parent of node to delete.
127      * @param localName name of node to delete.
128      * @exception ObjectNotFoundException
129      * a child of parentKey with name localName does not exist in the receiver
130      * @exception RuntimeException
131      * receiver is immutable
132      */

133     public abstract void deleteChild(IPath parentKey, String JavaDoc localName);
134
135     /**
136      * Initializes the receiver so that it is a complete, empty tree. The
137      * result does not represent a delta on another tree. An empty tree is
138      * defined to have a root node with null data and no children.
139      */

140     public abstract void empty();
141
142     /**
143      * Returns the key of a node in the tree.
144      *
145      * @param parentKey
146      * parent of child to retrieve.
147      * @param index
148      * index of the child to retrieve in its parent.
149      * @exception ObjectNotFoundException
150      * parentKey does not exist in the receiver
151      * @exception ArrayIndexOutOfBoundsException
152      * if no child with the given index (runtime exception)
153      */

154     public IPath getChild(IPath parentKey, int index) {
155         /* Get name of given child of the parent */
156         String JavaDoc child = getNameOfChild(parentKey, index);
157         return parentKey.append(child);
158     }
159
160     /**
161      * Returns the number of children of a node
162      *
163      * @param parentKey
164      * key of the node for which we want to retreive the number of children
165      * @exception ObjectNotFoundException
166      * parentKey does not exist in the receiver
167      */

168     public int getChildCount(IPath parentKey) {
169         return getNamesOfChildren(parentKey).length;
170     }
171
172     /**
173      * Returns the keys of all children of a node.
174      *
175      * @param parentKey
176      * key of parent whose children we want to retrieve.
177      * @exception ObjectNotFoundException
178      * parentKey does not exist in the receiver
179      */

180     public IPath[] getChildren(IPath parentKey) {
181         String JavaDoc names[] = getNamesOfChildren(parentKey);
182         int len = names.length;
183         if (len == 0)
184             return NO_CHILDREN;
185         IPath answer[] = new IPath[len];
186
187         for (int i = 0; i < len; i++) {
188             answer[i] = parentKey.append(names[i]);
189         }
190         return answer;
191     }
192
193     /**
194      * Returns the data of a node.
195      *
196      * @param key
197      * key of node for which we want to retrieve data.
198      * @exception ObjectNotFoundException
199      * key does not exist in the receiver
200      */

201     public abstract Object JavaDoc getData(IPath key);
202
203     /**
204      * Returns the local name of a node in the tree
205      *
206      * @param parentKey
207      * parent of node whose name we want to retrieve
208      * @param index
209      * index of node in its parent
210      * @exception ObjectNotFoundException
211      * parentKey does not exist in the receiver
212      * @exception ArrayIndexOutOfBoundsException
213      * if no child with the given index
214      */

215     public String JavaDoc getNameOfChild(IPath parentKey, int index) {
216         String JavaDoc childNames[] = getNamesOfChildren(parentKey);
217         /* Return the requested child as long as its in range */
218         return childNames[index];
219     }
220
221     /**
222      * Returns the local names for the children of a node
223      *
224      * @param parentKey
225      * key of node whose children we want to retrieve
226      * @exception ObjectNotFoundException
227      * parentKey does not exist in the receiver
228      */

229     public abstract String JavaDoc[] getNamesOfChildren(IPath parentKey);
230
231     /**
232      * Returns the root node of the tree.
233      *
234      * <p>Both subclasses must be able to return their root node. However subclasses
235      * can have different types of root nodes, so this is not enforced as an abstract
236      * method
237      */

238     AbstractDataTreeNode getRootNode() {
239         throw new AbstractMethodError JavaDoc(Messages.dtree_subclassImplement);
240     }
241
242     /**
243      * Handles the case where an attempt was made to modify
244      * the tree when it was in an immutable state. Throws
245      * an unchecked exception.
246      */

247     static void handleImmutableTree() {
248         throw new RuntimeException JavaDoc(Messages.dtree_immutable);
249     }
250
251     /**
252      * Handles the case where an attempt was made to manipulate
253      * an element in the tree that does not exist. Throws an
254      * unchecked exception.
255      */

256     static void handleNotFound(IPath key) {
257         throw new ObjectNotFoundException(NLS.bind(Messages.dtree_notFound, key));
258     }
259
260     /**
261      * Makes the tree immutable
262      */

263     public void immutable() {
264         immutable = true;
265     }
266
267     /**
268      * Returns true if the receiver includes a node with the given key, false
269      * otherwise.
270      *
271      * @param key
272      * key of node to find
273      */

274     public abstract boolean includes(IPath key);
275
276     /**
277      * Returns true if the tree is immutable, and false otherwise.
278      */

279     public boolean isImmutable() {
280         return immutable;
281     }
282
283     /**
284      * Returns an object containing:
285      * - a flag indicating whether the specified node was found
286      * - the data for the node, if it was found
287      * @param key
288      * key of node for which we want to retrieve data.
289      */

290     public abstract DataTreeLookup lookup(IPath key);
291
292     /**
293      * Returns the key of the root node.
294      */

295     public IPath rootKey() {
296         return Path.ROOT;
297     }
298
299     /**
300      * Sets the data of a node.
301      *
302      * @param key
303      * key of node for which to set data
304      * @param data
305      * new data value for node
306      * @exception ObjectNotFoundException
307      * the nodeKey does not exist in the receiver
308      * @exception IllegalArgumentException
309      * receiver is immutable
310      */

311     public abstract void setData(IPath key, Object JavaDoc data);
312
313     /**
314      * Sets the immutable field.
315      */

316     void setImmutable(boolean bool) {
317         immutable = bool;
318     }
319
320     /**
321      * Sets the root node of the tree.
322      *
323      * <p>Both subclasses must be able to set their root node. However subclasses
324      * can have different types of root nodes, so this is not enforced as an abstract
325      * method
326      */

327     void setRootNode(AbstractDataTreeNode node) {
328         throw new Error JavaDoc(Messages.dtree_subclassImplement);
329     }
330 }
331
Popular Tags