]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java
Fix bug in copyFiles
[lgpl/argeo-commons.git] / server / runtime / org.argeo.server.jcr / src / main / java / org / argeo / jcr / JcrUtils.java
index 3364ebfea896fbb79d391756bb8ec4cd27ae6e8e..83ab7a0b1cf776032e5919a286dfc13aed8e2d69 100644 (file)
@@ -64,6 +64,7 @@ import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.ArgeoException;
+import org.argeo.ArgeoMonitor;
 import org.argeo.util.security.DigestUtils;
 import org.argeo.util.security.SimplePrincipal;
 
@@ -113,6 +114,20 @@ public class JcrUtils implements ArgeoJcrConstants {
                return node;
        }
 
+       /** Retrieves the node name from the provided path */
+       public static String nodeNameFromPath(String path) {
+               if (path.equals("/"))
+                       return "";
+               if (path.charAt(0) != '/')
+                       throw new ArgeoException("Path " + path + " must start with a '/'");
+               String pathT = path;
+               if (pathT.charAt(pathT.length() - 1) == '/')
+                       pathT = pathT.substring(0, pathT.length() - 2);
+
+               int index = pathT.lastIndexOf('/');
+               return pathT.substring(index + 1);
+       }
+
        /** Retrieves the parent path of the provided path */
        public static String parentPath(String path) {
                if (path.equals("/"))
@@ -629,6 +644,9 @@ public class JcrUtils implements ArgeoJcrConstants {
         */
        public static void copy(Node fromNode, Node toNode) {
                try {
+                       if (toNode.getDefinition().isProtected())
+                               return;
+
                        // process properties
                        PropertyIterator pit = fromNode.getProperties();
                        properties: while (pit.hasNext()) {
@@ -684,6 +702,79 @@ public class JcrUtils implements ArgeoJcrConstants {
                }
        }
 
+       /**
+        * Copy only nt:folder and nt:file, without their additional types and
+        * properties.
+        * 
+        * @param recursive
+        *            if true copies folders as well, otherwise only first level
+        *            files
+        * @return how many files were copied
+        */
+       public static Long copyFiles(Node fromNode, Node toNode, Boolean recursive,
+                       ArgeoMonitor monitor) {
+               long count = 0l;
+
+               Binary binary = null;
+               InputStream in = null;
+               try {
+                       NodeIterator fromChildren = fromNode.getNodes();
+                       while (fromChildren.hasNext()) {
+                               if (monitor != null && monitor.isCanceled())
+                                       throw new ArgeoException(
+                                                       "Copy cancelled before it was completed");
+
+                               Node fromChild = fromChildren.nextNode();
+                               String fileName = fromChild.getName();
+                               if (fromChild.isNodeType(NodeType.NT_FILE)) {
+                                       if (monitor != null)
+                                               monitor.subTask("Copy " + fileName);
+                                       binary = fromChild.getNode(Node.JCR_CONTENT)
+                                                       .getProperty(Property.JCR_DATA).getBinary();
+                                       in = binary.getStream();
+                                       copyStreamAsFile(toNode, fileName, in);
+                                       IOUtils.closeQuietly(in);
+                                       JcrUtils.closeQuietly(binary);
+
+                                       // save session
+                                       toNode.getSession().save();
+                                       count++;
+
+                                       if (log.isDebugEnabled())
+                                               log.debug("Copied file " + fromChild.getPath());
+                                       if (monitor != null)
+                                               monitor.worked(1);
+                               } else if (fromChild.isNodeType(NodeType.NT_FOLDER)
+                                               && recursive) {
+                                       Node toChildFolder;
+                                       if (toNode.hasNode(fileName)) {
+                                               toChildFolder = toNode.getNode(fileName);
+                                               if (!toChildFolder.isNodeType(NodeType.NT_FOLDER))
+                                                       throw new ArgeoException(toChildFolder
+                                                                       + " is not of type nt:folder");
+                                       } else {
+                                               toChildFolder = toNode.addNode(fileName,
+                                                               NodeType.NT_FOLDER);
+
+                                               // save session
+                                               toNode.getSession().save();
+                                       }
+                                       count = count
+                                                       + copyFiles(fromChild, toChildFolder, recursive,
+                                                                       monitor);
+                               }
+                       }
+                       return count;
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot copy files between " + fromNode
+                                       + " and " + toNode);
+               } finally {
+                       // in case there was an exception
+                       IOUtils.closeQuietly(in);
+                       JcrUtils.closeQuietly(binary);
+               }
+       }
+
        /**
         * Check whether all first-level properties (except jcr:* properties) are
         * equal. Skip jcr:* properties
@@ -988,6 +1079,9 @@ public class JcrUtils implements ArgeoJcrConstants {
                        Node contentNode;
                        if (folderNode.hasNode(fileName)) {
                                fileNode = folderNode.getNode(fileName);
+                               if (!fileNode.isNodeType(NodeType.NT_FILE))
+                                       throw new ArgeoException(fileNode
+                                                       + " is not of type nt:file");
                                // we assume that the content node is already there
                                contentNode = fileNode.getNode(Node.JCR_CONTENT);
                        } else {
@@ -1116,8 +1210,14 @@ public class JcrUtils implements ArgeoJcrConstants {
                try {
                        session.getWorkspace()
                                        .getObservationManager()
-                                       .addEventListener(listener, eventTypes, basePath, true,
-                                                       null, new String[] { nodeType }, true);
+                                       .addEventListener(
+                                                       listener,
+                                                       eventTypes,
+                                                       basePath,
+                                                       true,
+                                                       null,
+                                                       nodeType == null ? null : new String[] { nodeType },
+                                                       true);
                } catch (RepositoryException e) {
                        throw new ArgeoException("Cannot add JCR listener " + listener
                                        + " to session " + session, e);
@@ -1289,6 +1389,23 @@ public class JcrUtils implements ArgeoJcrConstants {
                        Principal principal, List<Privilege> privs)
                        throws RepositoryException {
                AccessControlManager acm = session.getAccessControlManager();
+               AccessControlList acl = getAccessControlList(acm, path);
+               acl.addAccessControlEntry(principal,
+                               privs.toArray(new Privilege[privs.size()]));
+               acm.setPolicy(path, acl);
+               if (log.isDebugEnabled()) {
+                       StringBuffer privBuf = new StringBuffer();
+                       for (Privilege priv : privs)
+                               privBuf.append(priv.getName());
+                       log.debug("Added privileges " + privBuf + " to " + principal
+                                       + " on " + path);
+               }
+               session.save();
+       }
+
+       /** Gets access control list for this path, throws exception if not found */
+       public static AccessControlList getAccessControlList(
+                       AccessControlManager acm, String path) throws RepositoryException {
                // search for an access control list
                AccessControlList acl = null;
                AccessControlPolicyIterator policyIterator = acm
@@ -1307,19 +1424,21 @@ public class JcrUtils implements ArgeoJcrConstants {
                                        acl = ((AccessControlList) acp);
                        }
                }
+               if (acl != null)
+                       return acl;
+               else
+                       throw new ArgeoException("ACL not found at " + path);
+       }
 
-               if (acl != null) {
-                       acl.addAccessControlEntry(principal,
-                                       privs.toArray(new Privilege[privs.size()]));
-                       acm.setPolicy(path, acl);
-                       if (log.isDebugEnabled())
-                               log.debug("Added privileges " + privs + " to " + principal
-                                               + " on " + path);
-               } else {
-                       throw new ArgeoException("Don't know how to apply  privileges "
-                                       + privs + " to " + principal + " on " + path);
+       /** Clear authorizations for a user at this path */
+       public static void clearAccessControList(Session session, String path,
+                       String username) throws RepositoryException {
+               AccessControlManager acm = session.getAccessControlManager();
+               AccessControlList acl = getAccessControlList(acm, path);
+               for (AccessControlEntry ace : acl.getAccessControlEntries()) {
+                       if (ace.getPrincipal().getName().equals(username)) {
+                               acl.removeAccessControlEntry(ace);
+                       }
                }
-               session.save();
        }
-
 }