1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.myfaces.custom.tree.model;
20
21 import java.io.Serializable;
22
23
24 /**
25 * @author <a href="mailto:oliver@rossmueller.com">Oliver Rossmueller</a>
26 * @version $Revision: 472638 $ $Date: 2006-11-08 15:54:13 -0500 (Wed, 08 Nov 2006) $
27 */
28 public final class TreePath
29 extends Object
30 implements Serializable
31 {
32 private static final long serialVersionUID = 8972939732002296134L;
33 private Object[] elements;
34
35
36 /**
37 * Construct a pathElements from an array of Objects
38 *
39 * @param pathElements an array of Objects representing the pathElements to a node
40 */
41 public TreePath(Object[] pathElements)
42 {
43 if (pathElements == null || pathElements.length == 0)
44 {
45 throw new IllegalArgumentException("pathElements must be non null and not empty");
46 }
47
48 elements = pathElements;
49 }
50
51
52 /**
53 * Construct a new TreePath, which is the path identified by
54 * parent ending in lastElement.
55 */
56 protected TreePath(TreePath parent, Object lastElement)
57 {
58 elements = new Object[parent.elements.length + 1];
59
60 System.arraycopy(parent.elements, 0, elements, 0, elements.length - 1);
61 elements[elements.length - 1] = lastElement;
62 }
63
64
65 /**
66 * Construct a new TreePath from an array of objects.
67 *
68 * @param pathElements path elements
69 * @param length lenght of the new path
70 */
71 protected TreePath(Object[] pathElements, int length)
72 {
73 Object[] elements = new Object[length];
74
75 System.arraycopy(pathElements, 0, elements, 0, length);
76 }
77
78
79 /**
80 * Return an array of Objects containing the components of this
81 * TreePath.
82 *
83 * @return an array of Objects representing the TreePath
84 */
85 public Object[] getPath()
86 {
87 Object[] answer = new Object[elements.length];
88 System.arraycopy(elements, 0, answer, 0, elements.length);
89 return answer;
90 }
91
92
93 /**
94 * Returns the last component of this path.
95 *
96 * @return the Object at the end of the path
97 */
98 public Object getLastPathComponent()
99 {
100 return elements[elements.length - 1];
101 }
102
103
104 /**
105 * Return the number of elements in the path.
106 *
107 * @return an int giving a count of items the path
108 */
109 public int getPathCount()
110 {
111 return elements.length;
112 }
113
114
115 /**
116 * Return the path component at the specified index.
117 *
118 * @param index int specifying an index in the path
119 * @return the Object at that index location
120 * @throws IllegalArgumentException if the index is beyond the length
121 * of the path
122 */
123 public Object getPathComponent(int index)
124 {
125 if (index < 0 || index >= elements.length)
126 {
127 throw new IllegalArgumentException("Index " + index + " is out of range");
128 }
129
130 return elements[index];
131 }
132
133
134 /**
135 * Test two TreePaths for equality by checking each element of the
136 * paths for equality. Two paths are considered equal if they are of
137 * the same length and all element positions are equal.
138 *
139 * @param o the Object to compare
140 */
141 public boolean equals(Object o)
142 {
143 if (o == this)
144 {
145 return true;
146 }
147
148 if (!(o instanceof TreePath))
149 {
150 return false;
151 }
152 TreePath other = (TreePath)o;
153
154 if (elements.length != other.elements.length)
155 {
156 return false;
157 }
158
159 for (int i = 0; i < elements.length; i++)
160 {
161 Object thisElement = elements[i];
162 Object otherElement = other.elements[i];
163
164 if (!thisElement.equals(otherElement))
165 {
166 return false;
167 }
168 }
169 return true;
170 }
171
172
173 /**
174 * Return the hashCode for the object. The hash code of a TreePath
175 * is defined to be the hash code of the last component in the path.
176 *
177 * @return the hashCode for the object
178 */
179 public int hashCode()
180 {
181 return elements[elements.length - 1].hashCode();
182 }
183
184
185 /**
186 * Return true if <code>path</code> is a
187 * descendant of this
188 * TreePath. A TreePath P1 is a descendent of a TreePath P2
189 * if P1 contains all of the components that make up
190 * P2's path. If P1 and P2 are equal P2 is not considered a descendant of
191 * P1.
192 *
193 * @return true if <code>path</code> is a descendant of this path
194 */
195 public boolean isDescendant(TreePath path)
196 {
197 if (path == null)
198 {
199 return false;
200 }
201
202 if (elements.length < path.elements.length)
203 {
204 // Can't be a descendant, has fewer components in the path.
205 return false;
206 }
207
208 for (int i = 0; i < elements.length; i++)
209 {
210 Object thisElement = elements[i];
211 Object otherElement = path.elements[i];
212
213 if (!thisElement.equals(otherElement))
214 {
215 return false;
216 }
217 }
218 return true;
219 }
220
221
222 /**
223 * Return a new path by appending child to this path.
224 *
225 * @param child element to append
226 * @return new path
227 * @throws NullPointerException if child is null
228 */
229 public TreePath pathByAddingChild(Object child)
230 {
231 if (child == null)
232 {
233 throw new NullPointerException("Null child not allowed");
234 }
235
236 return new TreePath(this, child);
237 }
238
239
240 /**
241 * Return a path containing all the elements of this object, except
242 * the last path component.
243 */
244 public TreePath getParentPath()
245 {
246 return new TreePath(elements, elements.length - 1);
247 }
248
249
250 /**
251 * Return a string that displays and identifies this
252 * object's properties.
253 *
254 * @return a String representation of this object
255 */
256 public String toString()
257 {
258 StringBuffer buffer = new StringBuffer("[");
259
260 for (int i = 0; i < elements.length; i++)
261 {
262 if (i > 0)
263 {
264 buffer.append(", ");
265 }
266 buffer.append(elements[i]);
267
268 }
269
270 buffer.append("]");
271 return buffer.toString();
272 }
273 }
274