View Javadoc

1   /*
2    * ModeShape (http://www.modeshape.org)
3    * See the COPYRIGHT.txt file distributed with this work for information
4    * regarding copyright ownership.  Some portions may be licensed
5    * to Red Hat, Inc. under one or more contributor license agreements.
6    * See the AUTHORS.txt file in the distribution for a full listing of 
7    * individual contributors. 
8    *
9    * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10   * is licensed to you under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation; either version 2.1 of
12   * the License, or (at your option) any later version.
13   *
14   * ModeShape is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this software; if not, write to the Free
21   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23   */
24  package org.modeshape.graph.property.basic;
25  
26  import java.util.Collections;
27  import java.util.Iterator;
28  import java.util.List;
29  import net.jcip.annotations.Immutable;
30  import org.modeshape.common.text.Inflector;
31  import org.modeshape.common.text.TextEncoder;
32  import org.modeshape.common.util.CheckArg;
33  import org.modeshape.graph.GraphI18n;
34  import org.modeshape.graph.property.InvalidPathException;
35  import org.modeshape.graph.property.Name;
36  import org.modeshape.graph.property.NamespaceRegistry;
37  import org.modeshape.graph.property.Path;
38  
39  /**
40   * Optimized implementation of {@link Path} that serves as the root path.
41   */
42  @Immutable
43  public class RootPath extends AbstractPath {
44  
45      /**
46       * The serializable version. Version {@value}
47       */
48      private static final long serialVersionUID = 1L;
49  
50      public static final Path INSTANCE = new RootPath();
51  
52      private static final Path.Segment[] EMPTY_SEGMENT_ARRAY = new Path.Segment[] {};
53      private static final List<Path.Segment> EMPTY_SEGMENT_LIST = Collections.emptyList();
54  
55      private RootPath() {
56      }
57  
58      /**
59       * {@inheritDoc}
60       * 
61       * @see org.modeshape.graph.property.Path#getAncestor(int)
62       */
63      public Path getAncestor( int degree ) {
64          CheckArg.isNonNegative(degree, "degree");
65          if (degree == 0) {
66              return this;
67          }
68          String msg = GraphI18n.pathAncestorDegreeIsInvalid.text(this.getString(), Inflector.getInstance().ordinalize(degree));
69          throw new InvalidPathException(msg);
70      }
71  
72      /**
73       * {@inheritDoc}
74       * 
75       * @see org.modeshape.graph.property.basic.AbstractPath#getSegmentsOfParent()
76       */
77      @Override
78      protected Iterator<Segment> getSegmentsOfParent() {
79          return EMPTY_PATH_ITERATOR;
80      }
81  
82      /**
83       * {@inheritDoc}
84       * 
85       * @see org.modeshape.graph.property.Path#getCanonicalPath()
86       */
87      @Override
88      public Path getCanonicalPath() {
89          return this;
90      }
91  
92      /**
93       * {@inheritDoc}
94       * 
95       * @see org.modeshape.graph.property.Path#getCommonAncestor(org.modeshape.graph.property.Path)
96       */
97      @Override
98      public Path getCommonAncestor( Path that ) {
99          CheckArg.isNotNull(that, "that");
100         return this;
101     }
102 
103     /**
104      * {@inheritDoc}
105      * 
106      * @see org.modeshape.graph.property.Path#getLastSegment()
107      */
108     @Override
109     public Segment getLastSegment() {
110         return null;
111     }
112 
113     /**
114      * {@inheritDoc}
115      * 
116      * @see org.modeshape.graph.property.basic.AbstractPath#endsWith(org.modeshape.graph.property.Name)
117      */
118     @Override
119     public boolean endsWith( Name nameOfLastSegment ) {
120         return false;
121     }
122 
123     /**
124      * {@inheritDoc}
125      * 
126      * @see org.modeshape.graph.property.basic.AbstractPath#endsWith(org.modeshape.graph.property.Name, int)
127      */
128     @Override
129     public boolean endsWith( Name nameOfLastSegment,
130                              int snsIndex ) {
131         return false;
132     }
133 
134     /**
135      * {@inheritDoc}
136      * 
137      * @see org.modeshape.graph.property.Path#getNormalizedPath()
138      */
139     @Override
140     public Path getNormalizedPath() {
141         return this;
142     }
143 
144     /**
145      * {@inheritDoc}
146      * 
147      * @see org.modeshape.graph.property.basic.AbstractPath#relativeToRoot()
148      */
149     @Override
150     public Path relativeToRoot() {
151         return BasicPath.SELF_PATH;
152     }
153 
154     /**
155      * {@inheritDoc}
156      * 
157      * @see org.modeshape.graph.property.basic.AbstractPath#resolve(org.modeshape.graph.property.Path)
158      */
159     @Override
160     public Path resolve( Path relativePath ) {
161         CheckArg.isNotNull(relativePath, "relative path");
162         if (relativePath.isAbsolute()) {
163             String msg = GraphI18n.pathIsNotRelative.text(relativePath);
164             throw new InvalidPathException(msg);
165         }
166         // Make an absolute path out of the supplied relative path ...
167         return new BasicPath(relativePath.getSegmentsList(), true).getNormalizedPath();
168     }
169 
170     /**
171      * {@inheritDoc}
172      * 
173      * @see org.modeshape.graph.property.Path#getParent()
174      */
175     @Override
176     public Path getParent() {
177         return null;
178     }
179 
180     /**
181      * {@inheritDoc}
182      * 
183      * @see org.modeshape.graph.property.Path#getSegment(int)
184      */
185     @Override
186     public Segment getSegment( int index ) {
187         CheckArg.isNonNegative(index, "index");
188         EMPTY_SEGMENT_LIST.get(index); // throws IndexOutOfBoundsException
189         return null;
190     }
191 
192     /**
193      * {@inheritDoc}
194      * 
195      * @see org.modeshape.graph.property.Path#getSegmentsArray()
196      */
197     @Override
198     public Segment[] getSegmentsArray() {
199         // Can return the same array every time, since it's empty ...
200         return EMPTY_SEGMENT_ARRAY;
201     }
202 
203     /**
204      * {@inheritDoc}
205      * 
206      * @see org.modeshape.graph.property.Path#getSegmentsList()
207      */
208     public List<Segment> getSegmentsList() {
209         return EMPTY_SEGMENT_LIST;
210     }
211 
212     /**
213      * {@inheritDoc}
214      * 
215      * @see org.modeshape.graph.property.Path#getString()
216      */
217     @Override
218     public String getString() {
219         return Path.DELIMITER_STR;
220     }
221 
222     /**
223      * {@inheritDoc}
224      * 
225      * @see org.modeshape.graph.property.Path#getString(org.modeshape.common.text.TextEncoder)
226      */
227     @Override
228     public String getString( TextEncoder encoder ) {
229         return Path.DELIMITER_STR;
230     }
231 
232     /**
233      * {@inheritDoc}
234      * 
235      * @see org.modeshape.graph.property.Path#getString(org.modeshape.graph.property.NamespaceRegistry)
236      */
237     @Override
238     public String getString( NamespaceRegistry namespaceRegistry ) {
239         CheckArg.isNotNull(namespaceRegistry, "namespaceRegistry");
240         return Path.DELIMITER_STR;
241     }
242 
243     /**
244      * {@inheritDoc}
245      * 
246      * @see org.modeshape.graph.property.Path#getString(org.modeshape.graph.property.NamespaceRegistry,
247      *      org.modeshape.common.text.TextEncoder)
248      */
249     @Override
250     public String getString( NamespaceRegistry namespaceRegistry,
251                              TextEncoder encoder ) {
252         CheckArg.isNotNull(namespaceRegistry, "namespaceRegistry");
253         return Path.DELIMITER_STR;
254     }
255 
256     /**
257      * {@inheritDoc}
258      * 
259      * @see org.modeshape.graph.property.Path#getString(org.modeshape.graph.property.NamespaceRegistry,
260      *      org.modeshape.common.text.TextEncoder, org.modeshape.common.text.TextEncoder)
261      */
262     @Override
263     public String getString( NamespaceRegistry namespaceRegistry,
264                              TextEncoder encoder,
265                              TextEncoder delimiterEncoder ) {
266         return (delimiterEncoder == null) ? DELIMITER_STR : delimiterEncoder.encode(DELIMITER_STR);
267     }
268 
269     /**
270      * {@inheritDoc}
271      * 
272      * @see org.modeshape.graph.property.Path#hasSameAncestor(org.modeshape.graph.property.Path)
273      */
274     @Override
275     public boolean hasSameAncestor( Path that ) {
276         CheckArg.isNotNull(that, "that");
277         return true;
278     }
279 
280     /**
281      * {@inheritDoc}
282      * 
283      * @see org.modeshape.graph.property.Path#isAbsolute()
284      */
285     public boolean isAbsolute() {
286         return true;
287     }
288 
289     /**
290      * {@inheritDoc}
291      * 
292      * @see org.modeshape.graph.property.Path#isAncestorOf(org.modeshape.graph.property.Path)
293      */
294     @Override
295     public boolean isAncestorOf( Path decendant ) {
296         CheckArg.isNotNull(decendant, "decendant");
297         return !decendant.isRoot();
298     }
299 
300     /**
301      * {@inheritDoc}
302      * 
303      * @see org.modeshape.graph.property.Path#isAtOrAbove(org.modeshape.graph.property.Path)
304      */
305     @Override
306     public boolean isAtOrAbove( Path other ) {
307         CheckArg.isNotNull(other, "other");
308         return true;
309     }
310 
311     /**
312      * {@inheritDoc}
313      * 
314      * @see org.modeshape.graph.property.Path#isAtOrBelow(org.modeshape.graph.property.Path)
315      */
316     @Override
317     public boolean isAtOrBelow( Path other ) {
318         CheckArg.isNotNull(other, "other");
319         return other.isRoot();
320     }
321 
322     /**
323      * {@inheritDoc}
324      * 
325      * @see org.modeshape.graph.property.Path#isDecendantOf(org.modeshape.graph.property.Path)
326      */
327     @Override
328     public boolean isDecendantOf( Path ancestor ) {
329         CheckArg.isNotNull(ancestor, "ancestor");
330         return false;
331     }
332 
333     /**
334      * {@inheritDoc}
335      * 
336      * @see org.modeshape.graph.property.Path#isNormalized()
337      */
338     public boolean isNormalized() {
339         return true;
340     }
341 
342     /**
343      * {@inheritDoc}
344      * 
345      * @see org.modeshape.graph.property.Path#isRoot()
346      */
347     public boolean isRoot() {
348         return true;
349     }
350 
351     /**
352      * {@inheritDoc}
353      * 
354      * @see org.modeshape.graph.property.Path#isSameAs(org.modeshape.graph.property.Path)
355      */
356     @Override
357     public boolean isSameAs( Path other ) {
358         CheckArg.isNotNull(other, "other");
359         return other.isRoot();
360     }
361 
362     /**
363      * {@inheritDoc}
364      * 
365      * @see org.modeshape.graph.property.Path#iterator()
366      */
367     @Override
368     public Iterator<Segment> iterator() {
369         return EMPTY_SEGMENT_LIST.iterator();
370     }
371 
372     /**
373      * {@inheritDoc}
374      * 
375      * @see org.modeshape.graph.property.Path#pathsFromRoot()
376      */
377     @Override
378     public Iterator<Path> pathsFromRoot() {
379         return new SingleIterator<Path>(this);
380     }
381 
382     /**
383      * {@inheritDoc}
384      * 
385      * @see org.modeshape.graph.property.Path#size()
386      */
387     public int size() {
388         return 0;
389     }
390 
391     /**
392      * {@inheritDoc}
393      * 
394      * @see org.modeshape.graph.property.Path#subpath(int)
395      */
396     @Override
397     public Path subpath( int beginIndex ) {
398         CheckArg.isNonNegative(beginIndex, "beginIndex");
399         if (beginIndex == 0) return this;
400         EMPTY_SEGMENT_LIST.get(1); // throws IndexOutOfBoundsException
401         return null;
402     }
403 
404     /**
405      * {@inheritDoc}
406      * 
407      * @see org.modeshape.graph.property.Path#subpath(int, int)
408      */
409     @Override
410     public Path subpath( int beginIndex,
411                          int endIndex ) {
412         CheckArg.isNonNegative(beginIndex, "beginIndex");
413         CheckArg.isNonNegative(endIndex, "endIndex");
414         if (endIndex >= 1) {
415             EMPTY_SEGMENT_LIST.get(endIndex); // throws IndexOutOfBoundsException
416         }
417         return this;
418     }
419 
420     /**
421      * {@inheritDoc}
422      * 
423      * @see java.lang.Comparable#compareTo(java.lang.Object)
424      */
425     @Override
426     public int compareTo( Path other ) {
427         return other.isRoot() ? 0 : -1;
428     }
429 
430     /**
431      * {@inheritDoc}
432      * 
433      * @see java.lang.Object#equals(java.lang.Object)
434      */
435     @Override
436     public boolean equals( Object obj ) {
437         if (obj == this) return true;
438         if (obj instanceof Path) {
439             Path that = (Path)obj;
440             return that.isRoot();
441         }
442         return false;
443     }
444 
445 }