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