X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;ds=sidebyside;f=org.argeo.jcr%2Fsrc%2Forg%2Fargeo%2Fjcr%2Ffs%2FJcrPath.java;h=6a0c7adfe2d0ebbab10dd1ccf0b648df83ab464c;hb=d8037dd6a59ff5d38d7c7182a9ef6c26c8001a4f;hp=e25293517bcc4dfc298b5fec2c2803302a0e2957;hpb=e66b9893b0e511f8ab295e3cee42b7dc966f1597;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.jcr/src/org/argeo/jcr/fs/JcrPath.java b/org.argeo.jcr/src/org/argeo/jcr/fs/JcrPath.java index e25293517..6a0c7adfe 100644 --- a/org.argeo.jcr/src/org/argeo/jcr/fs/JcrPath.java +++ b/org.argeo.jcr/src/org/argeo/jcr/fs/JcrPath.java @@ -3,6 +3,7 @@ package org.argeo.jcr.fs; import java.io.File; import java.io.IOException; import java.net.URI; +import java.net.URISyntaxException; import java.nio.file.FileSystem; import java.nio.file.LinkOption; import java.nio.file.Path; @@ -10,147 +11,251 @@ import java.nio.file.WatchEvent.Kind; import java.nio.file.WatchEvent.Modifier; import java.nio.file.WatchKey; import java.nio.file.WatchService; +import java.util.Arrays; import java.util.Iterator; +import java.util.NoSuchElementException; import javax.jcr.Node; import javax.jcr.RepositoryException; +import javax.jcr.Session; public class JcrPath implements Path { - private JcrFileSystem filesSystem; - private String path; + private final static String delimStr = "/"; + private final static char delimChar = '/'; + + private final JcrFileSystem fs; + private final String[] path;// null means root + private final boolean absolute; + + // optim + 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"); + if (path.equals(delimStr)) {// root + this.path = null; + this.absolute = true; + this.hashCode = 0; + return; + } + 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); + this.hashCode = this.path[this.path.length - 1].hashCode(); + } - private Node node; + public JcrPath(JcrFileSystem filesSystem, Node node) throws RepositoryException { + this(filesSystem, node.getPath()); + } - public JcrPath(JcrFileSystem filesSystem, Node node) { - super(); - this.filesSystem = filesSystem; - this.node = node; + /** Internal optimisation */ + private JcrPath(JcrFileSystem filesSystem, String[] path, boolean absolute) { + this.fs = filesSystem; + this.path = path; + this.absolute = path == null ? true : absolute; + this.hashCode = path == null ? 0 : path[path.length - 1].hashCode(); } @Override public FileSystem getFileSystem() { - return filesSystem; + return fs; } @Override public boolean isAbsolute() { - return path.startsWith("/"); + return absolute; } @Override public Path getRoot() { try { - return new JcrPath(filesSystem, node.getSession().getRootNode()); + if (path == null) + return this; + return new JcrPath(fs, fs.getSession().getRootNode()); } catch (RepositoryException e) { throw new JcrFsException("Cannot get root", e); } } + @Override + public String toString() { + 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(path[i]); + } + return sb.toString(); + } + @Override public Path getFileName() { - return null; + if (path == null) + return null; + return new JcrPath(fs, path[path.length - 1]); } @Override public Path getParent() { - // TODO Auto-generated method stub - return null; + if (path == null) + return null; + if (path.length == 1)// root + return new JcrPath(fs, delimStr); + String[] parentPath = Arrays.copyOfRange(path, 0, path.length - 1); + return new JcrPath(fs, parentPath, absolute); } @Override public int getNameCount() { - // TODO Auto-generated method stub - return 0; + if (path == null) + return 0; + return path.length; } @Override public Path getName(int index) { - // TODO Auto-generated method stub - return null; + if (path == null) + return null; + return new JcrPath(fs, path[index]); } @Override public Path subpath(int beginIndex, int endIndex) { - // TODO Auto-generated method stub - return null; + if (path == null) + return null; + String[] parentPath = Arrays.copyOfRange(path, beginIndex, endIndex); + return new JcrPath(fs, parentPath, false); } @Override public boolean startsWith(Path other) { - // TODO Auto-generated method stub - return false; + return toString().startsWith(other.toString()); } @Override public boolean startsWith(String other) { - // TODO Auto-generated method stub - return false; + return toString().startsWith(other); } @Override public boolean endsWith(Path other) { - // TODO Auto-generated method stub - return false; + return toString().endsWith(other.toString()); } @Override public boolean endsWith(String other) { - // TODO Auto-generated method stub - return false; + return toString().endsWith(other); } @Override public Path normalize() { - // TODO Auto-generated method stub - return null; + // always normalized + return this; } @Override public Path resolve(Path other) { - // TODO Auto-generated method stub - return null; + JcrPath otherPath = (JcrPath) other; + if (otherPath.isAbsolute()) + return other; + String[] newPath; + if (path == null) { + newPath = new String[otherPath.path.length]; + System.arraycopy(otherPath.path, 0, newPath, 0, otherPath.path.length); + } else { + newPath = new String[path.length + otherPath.path.length]; + System.arraycopy(path, 0, newPath, 0, path.length); + System.arraycopy(otherPath.path, 0, newPath, path.length, otherPath.path.length); + } + return new JcrPath(fs, newPath, absolute); } @Override - public Path resolve(String other) { - // TODO Auto-generated method stub - return null; + public final Path resolve(String other) { + return resolve(getFileSystem().getPath(other)); } @Override - public Path resolveSibling(Path other) { - // TODO Auto-generated method stub - return null; + public final Path resolveSibling(Path other) { + if (other == null) + throw new NullPointerException(); + Path parent = getParent(); + return (parent == null) ? other : parent.resolve(other); } @Override - public Path resolveSibling(String other) { - // TODO Auto-generated method stub - return null; + public final Path resolveSibling(String other) { + return resolveSibling(getFileSystem().getPath(other)); + } + + @Override + public final Iterator iterator() { + return new Iterator() { + private int i = 0; + + @Override + public boolean hasNext() { + return (i < getNameCount()); + } + + @Override + public Path next() { + if (i < getNameCount()) { + Path result = getName(i); + i++; + return result; + } else { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; } @Override public Path relativize(Path other) { - // TODO Auto-generated method stub - return null; + if (equals(other)) + return new JcrPath(fs, ""); + if (other.startsWith(this)) { + String p1 = toString(); + String p2 = other.toString(); + return new JcrPath(fs, p2.substring(p1.length(), p2.length())); + } + throw new UnsupportedOperationException(); } @Override public URI toUri() { - // TODO Auto-generated method stub - return null; + try { + return new URI("jcr", toString(), null); + } catch (URISyntaxException e) { + throw new JcrFsException("Cannot create URI for " + toString(), e); + } } @Override public Path toAbsolutePath() { - // TODO Auto-generated method stub - return null; + if (isAbsolute()) + return this; + return new JcrPath(fs, path, true); } @Override public Path toRealPath(LinkOption... options) throws IOException { - // TODO Auto-generated method stub - return null; + return this; } @Override @@ -159,41 +264,60 @@ public class JcrPath implements Path { } @Override - public WatchKey register(WatchService watcher, Kind[] events, - Modifier... modifiers) throws IOException { - // TODO Auto-generated method stub - return null; - } - - @Override - public WatchKey register(WatchService watcher, Kind... events) - throws IOException { + public WatchKey register(WatchService watcher, Kind[] events, Modifier... modifiers) throws IOException { // TODO Auto-generated method stub return null; } @Override - public Iterator iterator() { + public WatchKey register(WatchService watcher, Kind... events) throws IOException { // TODO Auto-generated method stub return null; } @Override public int compareTo(Path other) { - // TODO Auto-generated method stub - return 0; + return toString().compareTo(other.toString()); } - public Node getNode() { + public Node getNode() throws RepositoryException { if (!isAbsolute())// TODO default dir throw new JcrFsException("Cannot get node from relative path"); - try { - if (node == null) - node = filesSystem.getSession().getNode(path); - return node; - } catch (RepositoryException e) { - throw new JcrFsException("Cannot get node", e); + String pathStr = toString(); + Session session = fs.getSession(); + // TODO synchronize on the session ? + if (!session.itemExists(pathStr)) + return null; + return session.getNode(pathStr); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof JcrPath)) + return false; + JcrPath other = (JcrPath) obj; + if (path.length != other.path.length) + return false; + for (int i = 0; i < path.length; i++) { + if (!path[i].equals(other.path[i])) + return false; } + return true; + } + + @Override + public int hashCode() { + return hashCode; + } + + @Override + protected Object clone() throws CloneNotSupportedException { + return new JcrPath(fs, toString()); + } + + @Override + protected void finalize() throws Throwable { + Arrays.fill(path, null); } }