1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
38
39 @Immutable
40 public class BasicPath extends AbstractPath {
41
42
43
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
61
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
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
88
89
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
100
101 public List<Segment> getSegmentsList() {
102 return this.segments;
103 }
104
105
106
107
108 public boolean isAbsolute() {
109 return this.absolute;
110 }
111
112
113
114
115 public boolean isNormalized() {
116 return this.normalized;
117 }
118
119
120
121
122 public boolean isRoot() {
123 return false;
124 }
125
126
127
128
129 public int size() {
130 return this.segments.size();
131 }
132
133 }