]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.jcr/src/org/argeo/jcr/fs/JcrPath.java
Rename Eclipse 4 dependencies
[lgpl/argeo-commons.git] / org.argeo.jcr / src / org / argeo / jcr / fs / JcrPath.java
1 package org.argeo.jcr.fs;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.net.URI;
6 import java.net.URISyntaxException;
7 import java.nio.file.FileSystem;
8 import java.nio.file.LinkOption;
9 import java.nio.file.Path;
10 import java.nio.file.WatchEvent.Kind;
11 import java.nio.file.WatchEvent.Modifier;
12 import java.nio.file.WatchKey;
13 import java.nio.file.WatchService;
14 import java.util.Arrays;
15 import java.util.Iterator;
16 import java.util.NoSuchElementException;
17
18 import javax.jcr.Node;
19 import javax.jcr.RepositoryException;
20 import javax.jcr.Session;
21
22 public class JcrPath implements Path {
23 private final static String delimStr = "/";
24 private final static char delimChar = '/';
25
26 private final JcrFileSystem fs;
27 private final String[] path;// null means root
28 private final boolean absolute;
29
30 // optim
31 private final int hashCode;
32
33 public JcrPath(JcrFileSystem filesSystem, String path) {
34 this.fs = filesSystem;
35 if (path == null)
36 throw new JcrFsException("Path cannot be null");
37 if (path.equals(delimStr)) {// root
38 this.path = null;
39 this.absolute = true;
40 this.hashCode = 0;
41 return;
42 } else if (path.equals("")) {// empty path
43 this.path = new String[] { "" };
44 this.absolute = false;
45 this.hashCode = "".hashCode();
46 return;
47 }
48
49 if (path.equals("~")) {// home
50 path = filesSystem.getUserHomePath();
51 if (path == null)
52 throw new JcrFsException("No home directory available");
53 }
54
55 this.absolute = path.charAt(0) == delimChar ? true : false;
56 String trimmedPath = path.substring(absolute ? 1 : 0,
57 path.charAt(path.length() - 1) == delimChar ? path.length() - 1 : path.length());
58 this.path = trimmedPath.split(delimStr);
59 for (int i = 0; i < this.path.length; i++) {
60 this.path[i] = Text.unescapeIllegalJcrChars(this.path[i]);
61 }
62 this.hashCode = this.path[this.path.length - 1].hashCode();
63 }
64
65 public JcrPath(JcrFileSystem filesSystem, Node node) throws RepositoryException {
66 this(filesSystem, node.getPath());
67 }
68
69 /** Internal optimisation */
70 private JcrPath(JcrFileSystem filesSystem, String[] path, boolean absolute) {
71 this.fs = filesSystem;
72 this.path = path;
73 this.absolute = path == null ? true : absolute;
74 this.hashCode = path == null ? 0 : path[path.length - 1].hashCode();
75 }
76
77 @Override
78 public FileSystem getFileSystem() {
79 return fs;
80 }
81
82 @Override
83 public boolean isAbsolute() {
84 return absolute;
85 }
86
87 @Override
88 public Path getRoot() {
89 try {
90 if (path == null)
91 return this;
92 return new JcrPath(fs, fs.getSession().getRootNode());
93 } catch (RepositoryException e) {
94 throw new JcrFsException("Cannot get root", e);
95 }
96 }
97
98 @Override
99 public String toString() {
100 if (path == null)
101 return "/";
102 StringBuilder sb = new StringBuilder();
103 if (isAbsolute())
104 sb.append('/');
105 for (int i = 0; i < path.length; i++) {
106 if (i != 0)
107 sb.append('/');
108 sb.append(path[i]);
109 }
110 return sb.toString();
111 }
112
113 public String toJcrPath() {
114 if (path == null)
115 return "/";
116 StringBuilder sb = new StringBuilder();
117 if (isAbsolute())
118 sb.append('/');
119 for (int i = 0; i < path.length; i++) {
120 if (i != 0)
121 sb.append('/');
122 sb.append(Text.escapeIllegalJcrChars(path[i]));
123 }
124 return sb.toString();
125 }
126
127 @Override
128 public Path getFileName() {
129 if (path == null)
130 return null;
131 return new JcrPath(fs, path[path.length - 1]);
132 }
133
134 @Override
135 public Path getParent() {
136 if (path == null)
137 return null;
138 if (path.length == 1)// root
139 return new JcrPath(fs, delimStr);
140 String[] parentPath = Arrays.copyOfRange(path, 0, path.length - 1);
141 return new JcrPath(fs, parentPath, absolute);
142 }
143
144 @Override
145 public int getNameCount() {
146 if (path == null)
147 return 0;
148 return path.length;
149 }
150
151 @Override
152 public Path getName(int index) {
153 if (path == null)
154 return null;
155 return new JcrPath(fs, path[index]);
156 }
157
158 @Override
159 public Path subpath(int beginIndex, int endIndex) {
160 if (path == null)
161 return null;
162 String[] parentPath = Arrays.copyOfRange(path, beginIndex, endIndex);
163 return new JcrPath(fs, parentPath, false);
164 }
165
166 @Override
167 public boolean startsWith(Path other) {
168 return toString().startsWith(other.toString());
169 }
170
171 @Override
172 public boolean startsWith(String other) {
173 return toString().startsWith(other);
174 }
175
176 @Override
177 public boolean endsWith(Path other) {
178 return toString().endsWith(other.toString());
179 }
180
181 @Override
182 public boolean endsWith(String other) {
183 return toString().endsWith(other);
184 }
185
186 @Override
187 public Path normalize() {
188 // always normalized
189 return this;
190 }
191
192 @Override
193 public Path resolve(Path other) {
194 JcrPath otherPath = (JcrPath) other;
195 if (otherPath.isAbsolute())
196 return other;
197 String[] newPath;
198 if (path == null) {
199 newPath = new String[otherPath.path.length];
200 System.arraycopy(otherPath.path, 0, newPath, 0, otherPath.path.length);
201 } else {
202 newPath = new String[path.length + otherPath.path.length];
203 System.arraycopy(path, 0, newPath, 0, path.length);
204 System.arraycopy(otherPath.path, 0, newPath, path.length, otherPath.path.length);
205 }
206 return new JcrPath(fs, newPath, absolute);
207 }
208
209 @Override
210 public final Path resolve(String other) {
211 return resolve(getFileSystem().getPath(other));
212 }
213
214 @Override
215 public final Path resolveSibling(Path other) {
216 if (other == null)
217 throw new NullPointerException();
218 Path parent = getParent();
219 return (parent == null) ? other : parent.resolve(other);
220 }
221
222 @Override
223 public final Path resolveSibling(String other) {
224 return resolveSibling(getFileSystem().getPath(other));
225 }
226
227 @Override
228 public final Iterator<Path> iterator() {
229 return new Iterator<Path>() {
230 private int i = 0;
231
232 @Override
233 public boolean hasNext() {
234 return (i < getNameCount());
235 }
236
237 @Override
238 public Path next() {
239 if (i < getNameCount()) {
240 Path result = getName(i);
241 i++;
242 return result;
243 } else {
244 throw new NoSuchElementException();
245 }
246 }
247
248 @Override
249 public void remove() {
250 throw new UnsupportedOperationException();
251 }
252 };
253 }
254
255 @Override
256 public Path relativize(Path other) {
257 if (equals(other))
258 return new JcrPath(fs, "");
259 if (other.startsWith(this)) {
260 String p1 = toString();
261 String p2 = other.toString();
262 return new JcrPath(fs, p2.substring(p1.length(), p2.length()));
263 }
264 throw new IllegalArgumentException(other + " cannot be realtivized against " + this);
265 }
266
267 @Override
268 public URI toUri() {
269 try {
270 return new URI("jcr", toString(), null);
271 } catch (URISyntaxException e) {
272 throw new JcrFsException("Cannot create URI for " + toString(), e);
273 }
274 }
275
276 @Override
277 public Path toAbsolutePath() {
278 if (isAbsolute())
279 return this;
280 return new JcrPath(fs, path, true);
281 }
282
283 @Override
284 public Path toRealPath(LinkOption... options) throws IOException {
285 return this;
286 }
287
288 @Override
289 public File toFile() {
290 throw new UnsupportedOperationException();
291 }
292
293 @Override
294 public WatchKey register(WatchService watcher, Kind<?>[] events, Modifier... modifiers) throws IOException {
295 // TODO Auto-generated method stub
296 return null;
297 }
298
299 @Override
300 public WatchKey register(WatchService watcher, Kind<?>... events) throws IOException {
301 // TODO Auto-generated method stub
302 return null;
303 }
304
305 @Override
306 public int compareTo(Path other) {
307 return toString().compareTo(other.toString());
308 }
309
310 public Node getNode() throws RepositoryException {
311 if (!isAbsolute())// TODO default dir
312 throw new JcrFsException("Cannot get node from relative path");
313 String pathStr = toJcrPath();
314 Session session = fs.getSession();
315 // TODO synchronize on the session ?
316 if (!session.itemExists(pathStr))
317 return null;
318 return session.getNode(pathStr);
319 }
320
321 @Override
322 public boolean equals(Object obj) {
323 if (!(obj instanceof JcrPath))
324 return false;
325 JcrPath other = (JcrPath) obj;
326
327 if (path == null) {// root
328 if (other.path == null)// root
329 return true;
330 else
331 return false;
332 } else {
333 if (other.path == null)// root
334 return false;
335 }
336 // non root
337 if (path.length != other.path.length)
338 return false;
339 for (int i = 0; i < path.length; i++) {
340 if (!path[i].equals(other.path[i]))
341 return false;
342 }
343 return true;
344 }
345
346 @Override
347 public int hashCode() {
348 return hashCode;
349 }
350
351 @Override
352 protected Object clone() throws CloneNotSupportedException {
353 return new JcrPath(fs, toString());
354 }
355
356 @Override
357 protected void finalize() throws Throwable {
358 Arrays.fill(path, null);
359 }
360
361 }