1 package org
.argeo
.jcr
.fs
;
4 import java
.io
.IOException
;
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
;
18 import javax
.jcr
.Node
;
19 import javax
.jcr
.RepositoryException
;
20 import javax
.jcr
.Session
;
22 /** A {@link Path} which contains a reference to a JCR {@link Node}. */
23 public class JcrPath
implements Path
{
24 private final static String delimStr
= "/";
25 private final static char delimChar
= '/';
27 private final JcrFileSystem fs
;
28 private final String
[] path
;// null means root
29 private final boolean absolute
;
32 private final int hashCode
;
34 public JcrPath(JcrFileSystem filesSystem
, String path
) {
35 this.fs
= filesSystem
;
37 throw new JcrFsException("Path cannot be null");
38 if (path
.equals(delimStr
)) {// root
43 } else if (path
.equals("")) {// empty path
44 this.path
= new String
[] { "" };
45 this.absolute
= false;
46 this.hashCode
= "".hashCode();
50 if (path
.equals("~")) {// home
51 path
= filesSystem
.getUserHomePath();
53 throw new JcrFsException("No home directory available");
56 this.absolute
= path
.charAt(0) == delimChar ?
true : false;
57 String trimmedPath
= path
.substring(absolute ?
1 : 0,
58 path
.charAt(path
.length() - 1) == delimChar ? path
.length() - 1 : path
.length());
59 this.path
= trimmedPath
.split(delimStr
);
60 for (int i
= 0; i
< this.path
.length
; i
++) {
61 this.path
[i
] = Text
.unescapeIllegalJcrChars(this.path
[i
]);
63 this.hashCode
= this.path
[this.path
.length
- 1].hashCode();
66 public JcrPath(JcrFileSystem filesSystem
, Node node
) throws RepositoryException
{
67 this(filesSystem
, node
.getPath());
70 /** Internal optimisation */
71 private JcrPath(JcrFileSystem filesSystem
, String
[] path
, boolean absolute
) {
72 this.fs
= filesSystem
;
74 this.absolute
= path
== null ?
true : absolute
;
75 this.hashCode
= path
== null ?
0 : path
[path
.length
- 1].hashCode();
79 public FileSystem
getFileSystem() {
84 public boolean isAbsolute() {
89 public Path
getRoot() {
93 return new JcrPath(fs
, fs
.getSession().getRootNode());
94 } catch (RepositoryException e
) {
95 throw new JcrFsException("Cannot get root", e
);
100 public String
toString() {
103 StringBuilder sb
= new StringBuilder();
106 for (int i
= 0; i
< path
.length
; i
++) {
111 return sb
.toString();
114 public String
toJcrPath() {
117 StringBuilder sb
= new StringBuilder();
120 for (int i
= 0; i
< path
.length
; i
++) {
123 sb
.append(Text
.escapeIllegalJcrChars(path
[i
]));
125 return sb
.toString();
129 public Path
getFileName() {
132 return new JcrPath(fs
, path
[path
.length
- 1]);
136 public Path
getParent() {
139 if (path
.length
== 1)// root
140 return new JcrPath(fs
, delimStr
);
141 String
[] parentPath
= Arrays
.copyOfRange(path
, 0, path
.length
- 1);
142 return new JcrPath(fs
, parentPath
, absolute
);
146 public int getNameCount() {
153 public Path
getName(int index
) {
156 return new JcrPath(fs
, path
[index
]);
160 public Path
subpath(int beginIndex
, int endIndex
) {
163 String
[] parentPath
= Arrays
.copyOfRange(path
, beginIndex
, endIndex
);
164 return new JcrPath(fs
, parentPath
, false);
168 public boolean startsWith(Path other
) {
169 return toString().startsWith(other
.toString());
173 public boolean startsWith(String other
) {
174 return toString().startsWith(other
);
178 public boolean endsWith(Path other
) {
179 return toString().endsWith(other
.toString());
183 public boolean endsWith(String other
) {
184 return toString().endsWith(other
);
188 public Path
normalize() {
194 public Path
resolve(Path other
) {
195 JcrPath otherPath
= (JcrPath
) other
;
196 if (otherPath
.isAbsolute())
200 newPath
= new String
[otherPath
.path
.length
];
201 System
.arraycopy(otherPath
.path
, 0, newPath
, 0, otherPath
.path
.length
);
203 newPath
= new String
[path
.length
+ otherPath
.path
.length
];
204 System
.arraycopy(path
, 0, newPath
, 0, path
.length
);
205 System
.arraycopy(otherPath
.path
, 0, newPath
, path
.length
, otherPath
.path
.length
);
207 return new JcrPath(fs
, newPath
, absolute
);
211 public final Path
resolve(String other
) {
212 return resolve(getFileSystem().getPath(other
));
216 public final Path
resolveSibling(Path other
) {
218 throw new NullPointerException();
219 Path parent
= getParent();
220 return (parent
== null) ? other
: parent
.resolve(other
);
224 public final Path
resolveSibling(String other
) {
225 return resolveSibling(getFileSystem().getPath(other
));
229 public final Iterator
<Path
> iterator() {
230 return new Iterator
<Path
>() {
234 public boolean hasNext() {
235 return (i
< getNameCount());
240 if (i
< getNameCount()) {
241 Path result
= getName(i
);
245 throw new NoSuchElementException();
250 public void remove() {
251 throw new UnsupportedOperationException();
257 public Path
relativize(Path other
) {
259 return new JcrPath(fs
, "");
260 if (other
.startsWith(this)) {
261 String p1
= toString();
262 String p2
= other
.toString();
263 String relative
= p2
.substring(p1
.length(), p2
.length());
264 if (relative
.charAt(0) == '/')
265 relative
= relative
.substring(1);
266 return new JcrPath(fs
, relative
);
268 throw new IllegalArgumentException(other
+ " cannot be relativized against " + this);
274 return new URI(fs
.provider().getScheme(), toString(), null);
275 } catch (URISyntaxException e
) {
276 throw new JcrFsException("Cannot create URI for " + toString(), e
);
281 public Path
toAbsolutePath() {
284 return new JcrPath(fs
, path
, true);
288 public Path
toRealPath(LinkOption
... options
) throws IOException
{
293 public File
toFile() {
294 throw new UnsupportedOperationException();
298 public WatchKey
register(WatchService watcher
, Kind
<?
>[] events
, Modifier
... modifiers
) throws IOException
{
299 // TODO Auto-generated method stub
304 public WatchKey
register(WatchService watcher
, Kind
<?
>... events
) throws IOException
{
305 // TODO Auto-generated method stub
310 public int compareTo(Path other
) {
311 return toString().compareTo(other
.toString());
314 public Node
getNode() throws RepositoryException
{
315 if (!isAbsolute())// TODO default dir
316 throw new JcrFsException("Cannot get node from relative path");
317 String pathStr
= toJcrPath();
318 Session session
= fs
.getSession();
319 // TODO synchronize on the session ?
320 if (!session
.itemExists(pathStr
))
322 return session
.getNode(pathStr
);
326 public boolean equals(Object obj
) {
327 if (!(obj
instanceof JcrPath
))
329 JcrPath other
= (JcrPath
) obj
;
331 if (path
== null) {// root
332 if (other
.path
== null)// root
337 if (other
.path
== null)// root
341 if (path
.length
!= other
.path
.length
)
343 for (int i
= 0; i
< path
.length
; i
++) {
344 if (!path
[i
].equals(other
.path
[i
]))
351 public int hashCode() {
356 protected Object
clone() throws CloneNotSupportedException
{
357 return new JcrPath(fs
, toString());
361 protected void finalize() throws Throwable
{
362 Arrays
.fill(path
, null);