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.util.CheckArg;
32  import org.modeshape.graph.GraphI18n;
33  import org.modeshape.graph.property.InvalidPathException;
34  import org.modeshape.graph.property.Path;
35  
36  /**
37   * A basic implementation of {@link Path}.
38   */
39  @Immutable
40  public class BasicPath extends AbstractPath {
41  
42      /**
43       * The initial serializable version. Version {@value}
44       */
45      private static final long serialVersionUID = 1L;
46  
47      private static final List<Segment> EMPTY_SEGMENTS = Collections.emptyList();
48  
49      public static final Path EMPTY_RELATIVE = new BasicPath(EMPTY_SEGMENTS, false);
50  
51      public static final Path SELF_PATH = new BasicPath(Collections.singletonList(Path.SELF_SEGMENT), false);
52  
53      public static final Path PARENT_PATH = new BasicPath(Collections.singletonList(Path.PARENT_SEGMENT), false);
54  
55      private final List<Segment> segments;
56      private final boolean absolute;
57      private final boolean normalized;
58  
59      /**
60       * @param segments the segments
61       * @param absolute true if this path is absolute, or false otherwise
62       */
63      public BasicPath( List<Segment> segments,
64                        boolean absolute ) {
65          assert segments != null;
66          this.segments = Collections.unmodifiableList(segments);
67          this.absolute = absolute;
68          this.normalized = isNormalized(this.segments);
69      }
70  
71      /**
72       * {@inheritDoc}
73       */
74      public Path getAncestor( int degree ) {
75          CheckArg.isNonNegative(degree, "degree");
76          if (degree == 0) return this;
77          int endIndex = this.segments.size() - degree;
78          if (endIndex == 0) return this.isAbsolute() ? RootPath.INSTANCE : null;
79          if (endIndex < 0) {
80              String msg = GraphI18n.pathAncestorDegreeIsInvalid.text(this.getString(), Inflector.getInstance().ordinalize(degree));
81              throw new InvalidPathException(msg);
82          }
83          return subpath(0, endIndex);
84      }
85  
86      /**
87       * {@inheritDoc}
88       * 
89       * @see org.modeshape.graph.property.basic.AbstractPath#getSegmentsOfParent()
90       */
91      @Override
92      protected Iterator<Segment> getSegmentsOfParent() {
93          int size = this.segments.size();
94          if (size == 1) return EMPTY_PATH_ITERATOR;
95          return this.segments.subList(0, size - 1).iterator();
96      }
97  
98      /**
99       * {@inheritDoc}
100      */
101     public List<Segment> getSegmentsList() {
102         return this.segments;
103     }
104 
105     /**
106      * {@inheritDoc}
107      */
108     public boolean isAbsolute() {
109         return this.absolute;
110     }
111 
112     /**
113      * {@inheritDoc}
114      */
115     public boolean isNormalized() {
116         return this.normalized;
117     }
118 
119     /**
120      * {@inheritDoc}
121      */
122     public boolean isRoot() {
123         return false;
124     }
125 
126     /**
127      * {@inheritDoc}
128      */
129     public int size() {
130         return this.segments.size();
131     }
132 
133 }