]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - org.argeo.jcr/src/org/argeo/jcr/fs/JcrFileSystemProvider.java
Improve error feedback in JCR FS
[lgpl/argeo-commons.git] / org.argeo.jcr / src / org / argeo / jcr / fs / JcrFileSystemProvider.java
index dcc59476ff646b59a97a54567958c325f19bbb84..804be94fdb752f83aa6ce830cbe39f085efbe46f 100644 (file)
@@ -30,22 +30,22 @@ import javax.jcr.Session;
 import javax.jcr.nodetype.NodeType;
 import javax.jcr.nodetype.PropertyDefinition;
 
-import org.apache.commons.io.FileExistsException;
 import org.argeo.jcr.JcrUtils;
 
 public abstract class JcrFileSystemProvider extends FileSystemProvider {
+
        @Override
        public SeekableByteChannel newByteChannel(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs)
                        throws IOException {
+               Node node = toNode(path);
                try {
-                       Node node = toNode(path);
                        if (node == null) {
                                Node parent = toNode(path.getParent());
                                if (parent == null)
-                                       throw new JcrFsException("No parent directory for " + path);
+                                       throw new IOException("No parent directory for " + path);
                                if (parent.getPrimaryNodeType().isNodeType(NodeType.NT_FILE)
                                                || parent.getPrimaryNodeType().isNodeType(NodeType.NT_LINKED_FILE))
-                                       throw new JcrFsException(path + " parent is a file");
+                                       throw new IOException(path + " parent is a file");
 
                                String fileName = path.getFileName().toString();
                                fileName = Text.escapeIllegalJcrChars(fileName);
@@ -57,7 +57,8 @@ public abstract class JcrFileSystemProvider extends FileSystemProvider {
                                throw new UnsupportedOperationException(node + " must be a file");
                        return new BinaryChannel(node);
                } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot read file", e);
+                       discardChanges(node);
+                       throw new IOException("Cannot read file", e);
                }
        }
 
@@ -65,23 +66,25 @@ public abstract class JcrFileSystemProvider extends FileSystemProvider {
        public DirectoryStream<Path> newDirectoryStream(Path dir, Filter<? super Path> filter) throws IOException {
                try {
                        Node base = toNode(dir);
+                       if (base == null)
+                               throw new IOException(dir + " is not a JCR node");
                        return new NodeDirectoryStream((JcrFileSystem) dir.getFileSystem(), base.getNodes(), filter);
                } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot list directory", e);
+                       throw new IOException("Cannot list directory", e);
                }
        }
 
        @Override
        public void createDirectory(Path dir, FileAttribute<?>... attrs) throws IOException {
+               Node node = toNode(dir);
                try {
-                       Node node = toNode(dir);
                        if (node == null) {
                                Node parent = toNode(dir.getParent());
                                if (parent == null)
                                        throw new IOException("Parent of " + dir + " does not exist");
                                if (parent.getPrimaryNodeType().isNodeType(NodeType.NT_FILE)
                                                || parent.getPrimaryNodeType().isNodeType(NodeType.NT_LINKED_FILE))
-                                       throw new JcrFsException(dir + " parent is a file");
+                                       throw new IOException(dir + " parent is a file");
                                String fileName = dir.getFileName().toString();
                                fileName = Text.escapeIllegalJcrChars(fileName);
                                node = parent.addNode(fileName, NodeType.NT_FOLDER);
@@ -89,19 +92,19 @@ public abstract class JcrFileSystemProvider extends FileSystemProvider {
                                node.addMixin(NodeType.MIX_LAST_MODIFIED);
                                node.getSession().save();
                        } else {
-                               if (!node.getPrimaryNodeType().isNodeType(NodeType.NT_FOLDER))
-                                       throw new FileExistsException(dir + " exists and is not a directory");
+                               // if (!node.getPrimaryNodeType().isNodeType(NodeType.NT_FOLDER))
+                               // throw new FileExistsException(dir + " exists and is not a directory");
                        }
                } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot create directory " + dir, e);
+                       discardChanges(node);
+                       throw new IOException("Cannot create directory " + dir, e);
                }
-
        }
 
        @Override
        public void delete(Path path) throws IOException {
+               Node node = toNode(path);
                try {
-                       Node node = toNode(path);
                        if (node == null)
                                throw new NoSuchFileException(path + " does not exist");
                        Session session = node.getSession();
@@ -114,32 +117,36 @@ public abstract class JcrFileSystemProvider extends FileSystemProvider {
                        }
                        session.save();
                } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot delete " + path, e);
+                       discardChanges(node);
+                       throw new IOException("Cannot delete " + path, e);
                }
 
        }
 
        @Override
        public void copy(Path source, Path target, CopyOption... options) throws IOException {
+               Node sourceNode = toNode(source);
+               Node targetNode = toNode(target);
                try {
-                       Node sourceNode = toNode(source);
-                       Node targetNode = toNode(target);
                        JcrUtils.copy(sourceNode, targetNode);
                        sourceNode.getSession().save();
                } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot copy from " + source + " to " + target, e);
+                       discardChanges(sourceNode);
+                       discardChanges(targetNode);
+                       throw new IOException("Cannot copy from " + source + " to " + target, e);
                }
        }
 
        @Override
        public void move(Path source, Path target, CopyOption... options) throws IOException {
+               Node sourceNode = toNode(source);
                try {
-                       Node sourceNode = toNode(source);
                        Session session = sourceNode.getSession();
                        session.move(sourceNode.getPath(), target.toString());
                        session.save();
                } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot move from " + source + " to " + target, e);
+                       discardChanges(sourceNode);
+                       throw new IOException("Cannot move from " + source + " to " + target, e);
                }
        }
 
@@ -156,7 +163,7 @@ public abstract class JcrFileSystemProvider extends FileSystemProvider {
                                Node node2 = toNode(path2);
                                return node.isSame(node2);
                        } catch (RepositoryException e) {
-                               throw new JcrFsException("Cannot check whether " + path + " and " + path2 + " are same", e);
+                               throw new IOException("Cannot check whether " + path + " and " + path2 + " are same", e);
                        }
                }
 
@@ -181,7 +188,7 @@ public abstract class JcrFileSystemProvider extends FileSystemProvider {
                                throw new NoSuchFileException(path + " does not exist");
                        // TODO check access via JCR api
                } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot delete " + path, e);
+                       throw new IOException("Cannot delete " + path, e);
                }
        }
 
@@ -194,13 +201,12 @@ public abstract class JcrFileSystemProvider extends FileSystemProvider {
        @Override
        public <A extends BasicFileAttributes> A readAttributes(Path path, Class<A> type, LinkOption... options)
                        throws IOException {
-               try {
-                       // TODO check if assignable
-                       Node node = toNode(path);
-                       return (A) new JcrBasicfileAttributes(node);
-               } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot read basic attributes of " + path, e);
+               // TODO check if assignable
+               Node node = toNode(path);
+               if (node == null) {
+                       throw new IOException("JCR node not found for " + path);
                }
+               return (A) new JcrBasicfileAttributes(node);
        }
 
        @Override
@@ -239,14 +245,14 @@ public abstract class JcrFileSystemProvider extends FileSystemProvider {
                        }
                        return res;
                } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot read attributes of " + path, e);
+                       throw new IOException("Cannot read attributes of " + path, e);
                }
        }
 
        @Override
        public void setAttribute(Path path, String attribute, Object value, LinkOption... options) throws IOException {
+               Node node = toNode(path);
                try {
-                       Node node = toNode(path);
                        if (value instanceof byte[]) {
                                JcrUtils.setBinaryAsBytes(node, attribute, (byte[]) value);
                        } else if (value instanceof Calendar) {
@@ -256,12 +262,40 @@ public abstract class JcrFileSystemProvider extends FileSystemProvider {
                        }
                        node.getSession().save();
                } catch (RepositoryException e) {
-                       throw new JcrFsException("Cannot set attribute " + attribute + " on " + path, e);
+                       discardChanges(node);
+                       throw new IOException("Cannot set attribute " + attribute + " on " + path, e);
                }
        }
 
-       protected Node toNode(Path path) throws RepositoryException {
-               return ((JcrPath) path).getNode();
+       protected Node toNode(Path path) {
+               try {
+                       return ((JcrPath) path).getNode();
+               } catch (RepositoryException e) {
+                       throw new JcrFsException("Cannot convert path " + path + " to JCR Node", e);
+               }
+       }
+
+       /** Discard changes in the underlying session */
+       protected void discardChanges(Node node) {
+               if (node == null)
+                       return;
+               try {
+                       // discard changes
+                       node.getSession().refresh(false);
+               } catch (RepositoryException e) {
+                       e.printStackTrace();
+                       // TODO log out session?
+                       // TODO use Commons logging?
+               }
        }
 
+       /**
+        * To be overriden in order to support the ~ path, with an implementation
+        * specific concept of user home.
+        * 
+        * @return null by default
+        */
+       public Node getUserHome(Session session) {
+               return null;
+       }
 }