View Javadoc

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