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=e7b3656cfd8e5e7e195a873924f65b92c95eefcb;hb=a093e5c849e70bbc754fa4462dbb6c2b59979973;hp=b32e4404e61b260b74d4c6c6c78a8612d6b8b034;hpb=43179ae5b61ba2dad93b2f74241f0b09572cee54;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 b32e4404e..e7b3656cf 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 @@ -17,6 +17,9 @@ package org.argeo.jcr; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; @@ -64,6 +67,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.util.security.DigestUtils; import org.argeo.util.security.SimplePrincipal; /** Utility methods to simplify common JCR operations. */ @@ -290,6 +294,54 @@ public class JcrUtils implements ArgeoJcrConstants { .addNode(childName); } + /** Convert a {@link NodeIterator} to a list of {@link Node} */ + public static List nodeIteratorToList(NodeIterator nodeIterator) { + List nodes = new ArrayList(); + while (nodeIterator.hasNext()) { + nodes.add(nodeIterator.nextNode()); + } + return nodes; + } + + /* + * PROPERTIES + */ + + /** + * Concisely get the string value of a property or null if this node doesn't + * have this property + */ + public static String get(Node node, String propertyName) { + try { + if (!node.hasProperty(propertyName)) + return null; + return node.getProperty(propertyName).getString(); + } catch (RepositoryException e) { + throw new ArgeoException("Cannot get property " + propertyName + + " of " + node, e); + } + } + + /** Concisely get the boolean value of a property */ + public static Boolean check(Node node, String propertyName) { + try { + return node.getProperty(propertyName).getBoolean(); + } catch (RepositoryException e) { + throw new ArgeoException("Cannot get property " + propertyName + + " of " + node, e); + } + } + + /** Concisely get the bytes array value of a property */ + public static byte[] getBytes(Node node, String propertyName) { + try { + return getBinaryAsBytes(node.getProperty(propertyName)); + } catch (RepositoryException e) { + throw new ArgeoException("Cannot get property " + propertyName + + " of " + node, e); + } + } + /** Creates the nodes making path, if they don't exist. */ public static Node mkdirs(Session session, String path) { return mkdirs(session, path, null, null, false); @@ -337,6 +389,14 @@ public class JcrUtils implements ArgeoJcrConstants { return mkdirsSafe(session, path, null); } + /** + * Creates the nodes making the path as {@link NodeType#NT_FOLDER} + */ + public static Node mkfolders(Session session, String path) { + return mkdirs(session, path, NodeType.NT_FOLDER, NodeType.NT_FOLDER, + false); + } + /** * Creates the nodes making path, if they don't exist. This is up to the * caller to save the session. Use with caution since it can create @@ -351,7 +411,8 @@ public class JcrUtils implements ArgeoJcrConstants { if (session.itemExists(path)) { Node node = session.getNode(path); // check type - if (type != null && !node.isNodeType(type)) + if (type != null && !node.isNodeType(type) + && !node.getPath().equals("/")) throw new ArgeoException("Node " + node + " exists but is of type " + node.getPrimaryNodeType().getName() @@ -882,6 +943,90 @@ public class JcrUtils implements ArgeoJcrConstants { } } + /** + * Copy a file as an nt:file, assuming an nt:folder hierarchy. The session + * is NOT saved. + * + * @return the created file node + */ + public static Node copyFile(Node folderNode, File file) { + InputStream in = null; + try { + in = new FileInputStream(file); + return copyStreamAsFile(folderNode, file.getName(), in); + } catch (IOException e) { + throw new ArgeoException("Cannot copy file " + file + " under " + + folderNode, e); + } finally { + IOUtils.closeQuietly(in); + } + } + + /** Copy bytes as an nt:file */ + public static Node copyBytesAsFile(Node folderNode, String fileName, + byte[] bytes) { + InputStream in = null; + try { + in = new ByteArrayInputStream(bytes); + return copyStreamAsFile(folderNode, fileName, in); + } catch (Exception e) { + throw new ArgeoException("Cannot copy file " + fileName + " under " + + folderNode, e); + } finally { + IOUtils.closeQuietly(in); + } + } + + /** + * Copy a stream as an nt:file, assuming an nt:folder hierarchy. The session + * is NOT saved. + * + * @return the created file node + */ + public static Node copyStreamAsFile(Node folderNode, String fileName, + InputStream in) { + Binary binary = null; + try { + Node fileNode; + Node contentNode; + if (folderNode.hasNode(fileName)) { + fileNode = folderNode.getNode(fileName); + // we assume that the content node is already there + contentNode = fileNode.getNode(Node.JCR_CONTENT); + } else { + fileNode = folderNode.addNode(fileName, NodeType.NT_FILE); + contentNode = fileNode.addNode(Node.JCR_CONTENT, + NodeType.NT_RESOURCE); + } + binary = contentNode.getSession().getValueFactory() + .createBinary(in); + contentNode.setProperty(Property.JCR_DATA, binary); + return fileNode; + } catch (Exception e) { + throw new ArgeoException("Cannot create file node " + fileName + + " under " + folderNode, e); + } finally { + closeQuietly(binary); + } + } + + /** Computes the checksum of an nt:file */ + public static String checksumFile(Node fileNode, String algorithm) { + Binary data = null; + InputStream in = null; + try { + data = fileNode.getNode(Node.JCR_CONTENT) + .getProperty(Property.JCR_DATA).getBinary(); + in = data.getStream(); + return DigestUtils.digest(algorithm, in); + } catch (RepositoryException e) { + throw new ArgeoException("Cannot checksum file " + fileNode, e); + } finally { + IOUtils.closeQuietly(in); + closeQuietly(data); + } + } + /** * Creates depth from a string (typically a username) by adding levels based * on its first characters: "aBcD",2 => a/aB @@ -1406,7 +1551,7 @@ public class JcrUtils implements ArgeoJcrConstants { /** * Add privileges on a path to a {@link Principal}. The path must already - * exist. + * exist. Session is saved. */ public static void addPrivileges(Session session, String path, Principal principal, List privs) @@ -1442,6 +1587,7 @@ public class JcrUtils implements ArgeoJcrConstants { throw new ArgeoException("Don't know how to apply privileges " + privs + " to " + principal + " on " + path); } + session.save(); } }