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 public class JcrPath
implements Path
{
23 private final static String delimStr
= "/";
24 private final static char delimChar
= '/';
26 private final JcrFileSystem fs
;
27 private final String
[] path
;// null means root
28 private final boolean absolute
;
31 private final int hashCode
;
33 public JcrPath(JcrFileSystem filesSystem
, String path
) {
34 this.fs
= filesSystem
;
36 throw new JcrFsException("Path cannot be null");
37 if (path
.equals(delimStr
)) {// root
42 } else if (path
.equals("")) {// empty path
43 this.path
= new String
[] { "" };
44 this.absolute
= false;
45 this.hashCode
= "".hashCode();
49 if (path
.equals("~")) {// home
50 path
= filesSystem
.getUserHomePath();
52 throw new JcrFsException("No home directory available");
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
]);
62 this.hashCode
= this.path
[this.path
.length
- 1].hashCode();
65 public JcrPath(JcrFileSystem filesSystem
, Node node
) throws RepositoryException
{
66 this(filesSystem
, node
.getPath());
69 /** Internal optimisation */
70 private JcrPath(JcrFileSystem filesSystem
, String
[] path
, boolean absolute
) {
71 this.fs
= filesSystem
;
73 this.absolute
= path
== null ?
true : absolute
;
74 this.hashCode
= path
== null ?
0 : path
[path
.length
- 1].hashCode();
78 public FileSystem
getFileSystem() {
83 public boolean isAbsolute() {
88 public Path
getRoot() {
92 return new JcrPath(fs
, fs
.getSession().getRootNode());
93 } catch (RepositoryException e
) {
94 throw new JcrFsException("Cannot get root", e
);
99 public String
toString() {
102 StringBuilder sb
= new StringBuilder();
105 for (int i
= 0; i
< path
.length
; i
++) {
110 return sb
.toString();
113 public String
toJcrPath() {
116 StringBuilder sb
= new StringBuilder();
119 for (int i
= 0; i
< path
.length
; i
++) {
122 sb
.append(Text
.escapeIllegalJcrChars(path
[i
]));
124 return sb
.toString();
128 public Path
getFileName() {
131 return new JcrPath(fs
, path
[path
.length
- 1]);
135 public Path
getParent() {
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
);
145 public int getNameCount() {
152 public Path
getName(int index
) {
155 return new JcrPath(fs
, path
[index
]);
159 public Path
subpath(int beginIndex
, int endIndex
) {
162 String
[] parentPath
= Arrays
.copyOfRange(path
, beginIndex
, endIndex
);
163 return new JcrPath(fs
, parentPath
, false);
167 public boolean startsWith(Path other
) {
168 return toString().startsWith(other
.toString());
172 public boolean startsWith(String other
) {
173 return toString().startsWith(other
);
177 public boolean endsWith(Path other
) {
178 return toString().endsWith(other
.toString());
182 public boolean endsWith(String other
) {
183 return toString().endsWith(other
);
187 public Path
normalize() {
193 public Path
resolve(Path other
) {
194 JcrPath otherPath
= (JcrPath
) other
;
195 if (otherPath
.isAbsolute())
199 newPath
= new String
[otherPath
.path
.length
];
200 System
.arraycopy(otherPath
.path
, 0, newPath
, 0, otherPath
.path
.length
);
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
);
206 return new JcrPath(fs
, newPath
, absolute
);
210 public final Path
resolve(String other
) {
211 return resolve(getFileSystem().getPath(other
));
215 public final Path
resolveSibling(Path other
) {
217 throw new NullPointerException();
218 Path parent
= getParent();
219 return (parent
== null) ? other
: parent
.resolve(other
);
223 public final Path
resolveSibling(String other
) {
224 return resolveSibling(getFileSystem().getPath(other
));
228 public final Iterator
<Path
> iterator() {
229 return new Iterator
<Path
>() {
233 public boolean hasNext() {
234 return (i
< getNameCount());
239 if (i
< getNameCount()) {
240 Path result
= getName(i
);
244 throw new NoSuchElementException();
249 public void remove() {
250 throw new UnsupportedOperationException();
256 public Path
relativize(Path other
) {
258 return new JcrPath(fs
, "");
259 if (other
.startsWith(this)) {
260 String p1
= toString();
261 String p2
= other
.toString();
262 String relative
= p2
.substring(p1
.length(), p2
.length());
263 if (relative
.charAt(0) == '/')
264 relative
= relative
.substring(1);
265 return new JcrPath(fs
, relative
);
267 throw new IllegalArgumentException(other
+ " cannot be relativized against " + this);
273 return new URI(fs
.provider().getScheme(), toString(), null);
274 } catch (URISyntaxException e
) {
275 throw new JcrFsException("Cannot create URI for " + toString(), e
);
280 public Path
toAbsolutePath() {
283 return new JcrPath(fs
, path
, true);
287 public Path
toRealPath(LinkOption
... options
) throws IOException
{
292 public File
toFile() {
293 throw new UnsupportedOperationException();
297 public WatchKey
register(WatchService watcher
, Kind
<?
>[] events
, Modifier
... modifiers
) throws IOException
{
298 // TODO Auto-generated method stub
303 public WatchKey
register(WatchService watcher
, Kind
<?
>... events
) throws IOException
{
304 // TODO Auto-generated method stub
309 public int compareTo(Path other
) {
310 return toString().compareTo(other
.toString());
313 public Node
getNode() throws RepositoryException
{
314 if (!isAbsolute())// TODO default dir
315 throw new JcrFsException("Cannot get node from relative path");
316 String pathStr
= toJcrPath();
317 Session session
= fs
.getSession();
318 // TODO synchronize on the session ?
319 if (!session
.itemExists(pathStr
))
321 return session
.getNode(pathStr
);
325 public boolean equals(Object obj
) {
326 if (!(obj
instanceof JcrPath
))
328 JcrPath other
= (JcrPath
) obj
;
330 if (path
== null) {// root
331 if (other
.path
== null)// root
336 if (other
.path
== null)// root
340 if (path
.length
!= other
.path
.length
)
342 for (int i
= 0; i
< path
.length
; i
++) {
343 if (!path
[i
].equals(other
.path
[i
]))
350 public int hashCode() {
355 protected Object
clone() throws CloneNotSupportedException
{
356 return new JcrPath(fs
, toString());
360 protected void finalize() throws Throwable
{
361 Arrays
.fill(path
, null);