1
2
3
4 package org.rcfaces.core.internal.util;
5
6 import java.util.ArrayList;
7 import java.util.Arrays;
8 import java.util.Collections;
9 import java.util.Iterator;
10 import java.util.List;
11 import java.util.StringTokenizer;
12
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15 import org.rcfaces.core.internal.lang.StringAppender;
16
17
18
19
20
21
22 public class Path implements IPath {
23 private static final String REVISION = "$Revision: 1.2 $";
24
25 private static final Log LOG = LogFactory.getLog(Path.class);
26
27 private List segments;
28
29 private boolean absolute;
30
31 private Path(List segments, boolean absolute) {
32 this.segments = new ArrayList(segments);
33 this.absolute = absolute;
34 }
35
36 public Path(String path) {
37 StringTokenizer st = new StringTokenizer(path, "/", true);
38
39 segments = new ArrayList(st.countTokens() / 2 + 2);
40
41 for (; st.hasMoreTokens();) {
42 String token = st.nextToken();
43
44 if (token.equals("/")) {
45 if (segments.isEmpty()) {
46 absolute = true;
47 }
48
49 continue;
50 }
51
52 segments.add(token);
53 }
54
55 normalizePath(segments, absolute);
56 }
57
58 public boolean isAbsolute() {
59 return absolute;
60 }
61
62 public IPath makeAbsolute() {
63 if (absolute) {
64 return this;
65 }
66 return new Path(segments, true);
67 }
68
69 public IPath makeRelative() {
70 if (absolute == false) {
71 return this;
72 }
73 return new Path(segments, false);
74 }
75
76 public String segment(int index) {
77 if (index < 0 || index >= segments.size()) {
78 throw new IndexOutOfBoundsException();
79 }
80
81 return (String) segments.get(index);
82 }
83
84 public int segmentCount() {
85 return segments.size();
86 }
87
88 public String[] segments() {
89 return (String[]) segments.toArray(new String[segments.size()]);
90 }
91
92 public String lastSegment() {
93 return segment(segments.size() - 1);
94 }
95
96 public IPath uptoSegment(int count) {
97 if (count < 1) {
98 return new Path(Collections.EMPTY_LIST, absolute);
99 }
100
101 if (count >= segments.size()) {
102 return new Path(segments, absolute);
103 }
104
105 return new Path(segments.subList(0, count), absolute);
106 }
107
108 public IPath append(IPath path) {
109 if (path.isAbsolute()) {
110 return path;
111 }
112
113 List l = new ArrayList(segments);
114
115 l.addAll(Arrays.asList(path.segments()));
116
117 normalizePath(l, absolute);
118
119 return new Path(l, absolute);
120 }
121
122 public IPath removeFirstSegments(int count) {
123 if (count < 0 || count >= segments.size()) {
124 return new Path(Collections.EMPTY_LIST, absolute);
125 }
126
127 return new Path(segments.subList(count, segments.size()), absolute);
128 }
129
130 public IPath removeLastSegments(int count) {
131 return uptoSegment(segments.size() - count);
132 }
133
134 public int hashCode() {
135 final int prime = 31;
136 int result = 1;
137 result = prime * result + (absolute ? 1231 : 1237);
138 result = prime * result
139 + ((segments == null) ? 0 : segments.hashCode());
140 return result;
141 }
142
143 public boolean equals(Object obj) {
144 if (this == obj)
145 return true;
146 if (obj == null)
147 return false;
148 if (getClass() != obj.getClass())
149 return false;
150 final Path other = (Path) obj;
151 if (absolute != other.absolute)
152 return false;
153 if (segments == null) {
154 if (other.segments != null)
155 return false;
156 } else if (!segments.equals(other.segments))
157 return false;
158 return true;
159 }
160
161 public String toString() {
162 StringAppender sa = new StringAppender(segments.size() * 16);
163
164 boolean first = true;
165 for (Iterator it = segments.iterator(); it.hasNext();) {
166 if (first) {
167 first = false;
168 if (absolute) {
169 sa.append('/');
170 }
171 } else {
172 sa.append('/');
173 }
174
175 sa.append((String) it.next());
176 }
177
178 return sa.toString();
179 }
180
181 private static void normalizePath(List segments, boolean absolute) {
182 for (int i = 0; i < segments.size();) {
183 String segment = (String) segments.get(i);
184
185 if (segment.length() == 0 || segment.equals(".")) {
186 segments.remove(i);
187 continue;
188 }
189
190 if (segment.equals("..")) {
191 if (i == 0) {
192 if (absolute == false) {
193 i++;
194 continue;
195 }
196 segments.remove(i);
197 continue;
198 }
199
200 if (segments.get(i - 1).equals("..")) {
201 i++;
202 continue;
203 }
204
205 segments.remove(i--);
206 segments.remove(i);
207 continue;
208 }
209
210 i++;
211 }
212 }
213 }