X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=server%2Fruntime%2Forg.argeo.server.jcr%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fjcr%2FJcrUtils.java;h=83ab7a0b1cf776032e5919a286dfc13aed8e2d69;hb=8257decb84827bdec57ca72b2e57335576c19104;hp=3364ebfea896fbb79d391756bb8ec4cd27ae6e8e;hpb=2c4852dcd20d4cde88776c527ae935f242ae1e77;p=lgpl%2Fargeo-commons.git diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java index 3364ebfea..83ab7a0b1 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java @@ -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 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(); } - }