Make workspace indexer and JCR file system more robust.
[lgpl/argeo-commons.git] / org.argeo.jcr / src / org / argeo / jcr / fs / JcrPath.java
index 1f79434845eb84c54ce2aa9ab08bbdafb5d76113..c5d86f679970e012a54da1b5e7d21dc8f90541a4 100644 (file)
@@ -19,6 +19,7 @@ import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
+/** A {@link Path} which contains a reference to a JCR {@link Node}. */
 public class JcrPath implements Path {
        private final static String delimStr = "/";
        private final static char delimChar = '/';
@@ -31,8 +32,6 @@ public class JcrPath implements Path {
        private final int hashCode;
 
        public JcrPath(JcrFileSystem filesSystem, String path) {
-               // this(filesSystem, path.equals("/") ? null : path.split("/"), path ==
-               // null ? true : path.startsWith("/"));
                this.fs = filesSystem;
                if (path == null)
                        throw new JcrFsException("Path cannot be null");
@@ -47,10 +46,20 @@ public class JcrPath implements Path {
                        this.hashCode = "".hashCode();
                        return;
                }
+
+               if (path.equals("~")) {// home
+                       path = filesSystem.getUserHomePath();
+                       if (path == null)
+                               throw new JcrFsException("No home directory available");
+               }
+
                this.absolute = path.charAt(0) == delimChar ? true : false;
                String trimmedPath = path.substring(absolute ? 1 : 0,
                                path.charAt(path.length() - 1) == delimChar ? path.length() - 1 : path.length());
                this.path = trimmedPath.split(delimStr);
+               for (int i = 0; i < this.path.length; i++) {
+                       this.path[i] = Text.unescapeIllegalJcrChars(this.path[i]);
+               }
                this.hashCode = this.path[this.path.length - 1].hashCode();
        }
 
@@ -102,6 +111,20 @@ public class JcrPath implements Path {
                return sb.toString();
        }
 
+       public String toJcrPath() {
+               if (path == null)
+                       return "/";
+               StringBuilder sb = new StringBuilder();
+               if (isAbsolute())
+                       sb.append('/');
+               for (int i = 0; i < path.length; i++) {
+                       if (i != 0)
+                               sb.append('/');
+                       sb.append(Text.escapeIllegalJcrChars(path[i]));
+               }
+               return sb.toString();
+       }
+
        @Override
        public Path getFileName() {
                if (path == null)
@@ -237,15 +260,18 @@ public class JcrPath implements Path {
                if (other.startsWith(this)) {
                        String p1 = toString();
                        String p2 = other.toString();
-                       return new JcrPath(fs, p2.substring(p1.length(), p2.length()));
+                       String relative = p2.substring(p1.length(), p2.length());
+                       if (relative.charAt(0) == '/')
+                               relative = relative.substring(1);
+                       return new JcrPath(fs, relative);
                }
-               throw new IllegalArgumentException(other + " cannot be realtivized against " + this);
+               throw new IllegalArgumentException(other + " cannot be relativized against " + this);
        }
 
        @Override
        public URI toUri() {
                try {
-                       return new URI("jcr", toString(), null);
+                       return new URI(fs.provider().getScheme(), toString(), null);
                } catch (URISyntaxException e) {
                        throw new JcrFsException("Cannot create URI for " + toString(), e);
                }
@@ -288,7 +314,7 @@ public class JcrPath implements Path {
        public Node getNode() throws RepositoryException {
                if (!isAbsolute())// TODO default dir
                        throw new JcrFsException("Cannot get node from relative path");
-               String pathStr = toString();
+               String pathStr = toJcrPath();
                Session session = fs.getSession();
                // TODO synchronize on the session ?
                if (!session.itemExists(pathStr))