KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > forms > formmodel > tree > TreePath


1 /*
2  * Copyright 1999-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.forms.formmodel.tree;
17
18 import java.util.StringTokenizer JavaDoc;
19
20 /**
21  * A path in a {@link TreeModel}.
22  *
23  * @version $Id: TreePath.java 326838 2005-10-20 06:26:53Z sylvain $
24  */

25 public class TreePath {
26     
27     public static final TreePath ROOT_PATH = new TreePath();
28     /**
29      * Path representing the parent, null if lastPathComponent represents the
30      * root.
31      */

32     private TreePath parentPath;
33
34     /** Last path component. */
35     private String JavaDoc key;
36     
37     /** Cached result of toString() */
38     private String JavaDoc cachedToString;
39     
40     /**
41      * Builds a path representing the root node or a tree model.
42      * Private to only be used by the ROOT_PATH constant.
43      */

44     private TreePath() {
45         this.key = "";
46         this.cachedToString = "/";
47     }
48
49     /**
50      * Constructs a TreePath containing only a single element. This is usually
51      * used to construct a TreePath for the the root of the TreeModel.
52      */

53     public TreePath(String JavaDoc key) {
54         if (key == null || key.length() == 0) {
55             throw new IllegalArgumentException JavaDoc("key must be non empty.");
56         }
57         
58         if (key.indexOf('/') != -1) {
59             throw new IllegalArgumentException JavaDoc("key cannot contain a '/'");
60         }
61         this.key = key;
62         parentPath = ROOT_PATH;
63     }
64
65     /**
66      * Constructs a new TreePath, which is the path identified by
67      * <code>parent</code> ending in <code>lastElement</code>.
68      */

69     public TreePath(TreePath parent, String JavaDoc key) {
70         this(key);
71         if (parent == null) {
72             throw new IllegalArgumentException JavaDoc("Parent path must be non null.");
73         }
74         this.parentPath = parent;
75     }
76
77     /**
78      * Returns an ordered array of Objects containing the components of this
79      * TreePath. The first element (index 0) is the root.
80      *
81      * @return an array of Objects representing the TreePath
82      * @see #TreePath(Object[])
83      */

84     public Object JavaDoc[] getObjectPath(TreeModel model) {
85         int i = getPathCount();
86         Object JavaDoc[] result = new Object JavaDoc[i--];
87
88         for (TreePath path = this; path != null; path = path.parentPath) {
89             result[i--] = path.getLastPathObject(model);
90         }
91         return result;
92     }
93
94     /**
95      * Returns the last component of this path. For a path returned by
96      * DefaultTreeModel this will return an instance of TreeNode.
97      *
98      * @return the Object at the end of the path
99      * @see #TreePath(Object[])
100      */

101     public Object JavaDoc getLastPathObject(TreeModel model) {
102         Object JavaDoc parent;
103         if (this.parentPath == ROOT_PATH) {
104             parent = model.getRoot();
105         } else {
106             parent = this.parentPath.getLastPathObject(model);
107         }
108         return model.getChild(parent, this.key);
109     }
110
111     /**
112      * Returns the number of elements in the path.
113      *
114      * @return an int giving a count of items the path
115      */

116     public int getPathCount() {
117         int result = 0;
118         for (TreePath path = this; path != null; path = path.parentPath) {
119             result++;
120         }
121         return result;
122     }
123
124 // /**
125
// * Returns the path component at the specified index.
126
// *
127
// * @param element
128
// * an int specifying an element in the path, where 0 is the first
129
// * element in the path
130
// * @return the Object at that index location
131
// * @throws IllegalArgumentException
132
// * if the index is beyond the length of the path
133
// * @see #TreePath(Object[])
134
// */
135
// public Object getPathComponent(int element) {
136
// int pathLength = getPathCount();
137
//
138
// if (element < 0 || element >= pathLength)
139
// throw new IllegalArgumentException("Index " + element + " is out of the specified range");
140
//
141
// TreePath path = this;
142
//
143
// for (int i = pathLength - 1; i != element; i--) {
144
// path = path.parentPath;
145
// }
146
// return path.lastPathComponent;
147
// }
148
//
149
/**
150      * Tests if two paths are equal. Two paths are considered equal if they are
151      * of same length and contain the same keys.
152      *
153      * @param obj the object ot compare
154      */

155     public boolean equals(Object JavaDoc obj) {
156         if (obj == this) {
157             return true;
158         }
159         if (!(obj instanceof TreePath)) {
160             return false;
161         }
162         
163         TreePath otherPath = (TreePath)obj;
164
165         if (getPathCount() != otherPath.getPathCount()) {
166             return false;
167         }
168         
169         TreePath path = this;
170         do {
171             if (otherPath == null || !path.key.equals(otherPath.key)) {
172                 return false;
173             }
174             path = path.parentPath;
175             otherPath = otherPath.parentPath;
176         } while(path != null);
177         
178         return true;
179     }
180
181     public int hashCode() {
182         // Should be enough. We may also xor with parent's hashcode.
183
return key.hashCode();
184     }
185
186     /**
187      * Returns true if <code>aTreePath</code> is a descendant of this
188      * TreePath. A TreePath P1 is a descendent of a TreePath P2 if P1 contains
189      * all of the components that make up P2's path. For example, if this object
190      * has the path [a, b], and <code>aTreePath</code> has the path [a, b, c],
191      * then <code>aTreePath</code> is a descendant of this object. However, if
192      * <code>aTreePath</code> has the path [a], then it is not a descendant of
193      * this object.
194      *
195      * @return true if <code>aTreePath</code> is a descendant of this path
196      */

197     public boolean isDescendant(TreePath aTreePath) {
198         if (aTreePath == this)
199             return true;
200
201         if (aTreePath != null) {
202             int pathLength = getPathCount();
203             int oPathLength = aTreePath.getPathCount();
204
205             if (oPathLength < pathLength)
206                 // Can't be a descendant, has fewer components in the path.
207
return false;
208             while (oPathLength-- > pathLength)
209                 aTreePath = aTreePath.getParentPath();
210             return equals(aTreePath);
211         }
212         return false;
213     }
214
215 // /**
216
// * Returns a new path containing all the elements of this object plus
217
// * <code>child</code>. <code>child</code> will be the last element of
218
// * the newly created TreePath. This will throw a NullPointerException if
219
// * child is null.
220
// */
221
// public TreePath pathByAddingChild(Object child) {
222
// if (child == null)
223
// throw new NullPointerException("Null child not allowed");
224
//
225
// return new TreePath(this, child);
226
// }
227

228     /**
229      * Returns a path containing all the elements of this object, except the
230      * last path component.
231      */

232     public TreePath getParentPath() {
233         return parentPath;
234     }
235     
236     /**
237      * Returns the key of last element of this path.
238      */

239     public String JavaDoc getLastKey() {
240         return this.key;
241     }
242
243     /**
244      * Returns a string that displays and identifies this object's properties.
245      *
246      * @return a String representation of this object
247      */

248     public String JavaDoc toString() {
249         if (this.cachedToString == null) {
250             StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
251             appendTo(buf);
252             this.cachedToString = buf.toString();
253         }
254         return this.cachedToString;
255     }
256     
257     /** Recursively build the text representation of a tree path */
258     private void appendTo(StringBuffer JavaDoc buf) {
259         if (this.parentPath != ROOT_PATH) {
260             this.parentPath.appendTo(buf);
261         }
262         buf.append('/');
263         buf.append(this.key);
264     }
265     
266     /**
267      * Returns the <code>TreePath</code> represented by a given String.
268      * @param s the string representation of the path
269      * @return a path object
270      *
271      * @see #toString()
272      */

273     public static TreePath valueOf(String JavaDoc s) {
274         // FIXME: see if some caching could be useful here.
275
if (s == null || s.length() == 0) {
276             throw new IllegalArgumentException JavaDoc("Invalid empty string");
277         }
278         StringTokenizer JavaDoc stok = new StringTokenizer JavaDoc(s, "/");
279         TreePath current = ROOT_PATH;
280         while (stok.hasMoreTokens()) {
281             String JavaDoc tok = stok.nextToken();
282             current = current == null ? new TreePath(tok) : new TreePath(current, tok);
283         }
284
285         return current;
286     }
287     
288     public Object JavaDoc getObject(TreeModel model) {
289         return this.parentPath == null ?
290                 model.getRoot() :
291                 model.getChild(this.parentPath.getObject(model), this.key);
292     }
293 }
294
Popular Tags