X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.jcr%2Fsrc%2Forg%2Fargeo%2Fjcr%2FJcrUtils.java;h=56d959e08579c2306e662173227ae1a926c69e02;hb=3779305ca2c08e66d9ba2061c76eb79e278860fb;hp=af8aca69bedf7dbe766c4b31ae06957d4423a409;hpb=3b38491015a84964a3565cdf51e265b45659dd0a;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.jcr/src/org/argeo/jcr/JcrUtils.java b/org.argeo.jcr/src/org/argeo/jcr/JcrUtils.java index af8aca69b..56d959e08 100644 --- a/org.argeo.jcr/src/org/argeo/jcr/JcrUtils.java +++ b/org.argeo.jcr/src/org/argeo/jcr/JcrUtils.java @@ -6,8 +6,13 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; import java.net.MalformedURLException; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Principal; @@ -26,6 +31,7 @@ import java.util.TreeMap; import javax.jcr.Binary; import javax.jcr.Credentials; +import javax.jcr.ImportUUIDBehavior; import javax.jcr.NamespaceRegistry; import javax.jcr.NoSuchWorkspaceException; import javax.jcr.Node; @@ -37,6 +43,7 @@ import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.Value; import javax.jcr.Workspace; +import javax.jcr.nodetype.NoSuchNodeTypeException; import javax.jcr.nodetype.NodeType; import javax.jcr.observation.EventListener; import javax.jcr.query.Query; @@ -718,6 +725,33 @@ public class JcrUtils { } } + /** Copy the whole workspace via a system view XML. */ + public static void copyWorkspaceXml(Session fromSession, Session toSession) { + Workspace fromWorkspace = fromSession.getWorkspace(); + Workspace toWorkspace = toSession.getWorkspace(); + String errorMsg = "Cannot copy workspace " + fromWorkspace + " to " + toWorkspace + " via XML."; + + try (PipedInputStream in = new PipedInputStream(1024 * 1024);) { + new Thread(() -> { + try (PipedOutputStream out = new PipedOutputStream(in)) { + fromSession.exportSystemView("/", out, false, false); + out.flush(); + } catch (IOException e) { + throw new RuntimeException(errorMsg, e); + } catch (RepositoryException e) { + throw new JcrException(errorMsg, e); + } + }, "Copy workspace" + fromWorkspace + " to " + toWorkspace).start(); + + toSession.importXML("/", in, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING); + toSession.save(); + } catch (IOException e) { + throw new RuntimeException(errorMsg, e); + } catch (RepositoryException e) { + throw new JcrException(errorMsg, e); + } + } + /** * Copies recursively the content of a node to another one. Do NOT copy the * property values of {@link NodeType#MIX_CREATED} and @@ -733,7 +767,12 @@ public class JcrUtils { // add mixins for (NodeType mixinType : fromNode.getMixinNodeTypes()) { - toNode.addMixin(mixinType.getName()); + try { + toNode.addMixin(mixinType.getName()); + } catch (NoSuchNodeTypeException e) { + // ignore unknown mixins + // TODO log it + } } // process properties @@ -771,8 +810,15 @@ public class JcrUtils { Node toChild; if (toNode.hasNode(nodeRelPath)) toChild = toNode.getNode(nodeRelPath); - else - toChild = toNode.addNode(fromChild.getName(), fromChild.getPrimaryNodeType().getName()); + else { + try { + toChild = toNode.addNode(fromChild.getName(), fromChild.getPrimaryNodeType().getName()); + } catch (NoSuchNodeTypeException e) { + // ignore unknown primary types + // TODO log it + return; + } + } copy(fromChild, toChild); } } catch (RepositoryException e) { @@ -1425,6 +1471,8 @@ public class JcrUtils { // the new access control list must be applied otherwise this call: // acl.removeAccessControlEntry(ace); has no effect acm.setPolicy(path, acl); + session.refresh(true); + session.save(); } /* @@ -1532,6 +1580,7 @@ public class JcrUtils { * * @return the created file node */ + @Deprecated public static Node copyFile(Node folderNode, File file) { try (InputStream in = new FileInputStream(file)) { return copyStreamAsFile(folderNode, file.getName(), in); @@ -1576,6 +1625,7 @@ public class JcrUtils { } binary = contentNode.getSession().getValueFactory().createBinary(in); contentNode.setProperty(Property.JCR_DATA, binary); + updateLastModified(contentNode); return fileNode; } catch (RepositoryException e) { throw new JcrException("Cannot create file node " + fileName + " under " + folderNode, e); @@ -1589,6 +1639,41 @@ public class JcrUtils { return fileNode.getNode(Node.JCR_CONTENT).getProperty(Property.JCR_DATA).getBinary().getStream(); } + /** + * Set the properties of {@link NodeType#MIX_MIMETYPE} on the content of this + * file node. + */ + public static void setFileMimeType(Node fileNode, String mimeType, String encoding) throws RepositoryException { + Node contentNode = fileNode.getNode(Node.JCR_CONTENT); + if (mimeType != null) + contentNode.setProperty(Property.JCR_MIMETYPE, mimeType); + if (encoding != null) + contentNode.setProperty(Property.JCR_ENCODING, encoding); + // TODO remove properties if args are null? + } + + public static void copyFilesToFs(Node baseNode, Path targetDir, boolean recursive) { + try { + Files.createDirectories(targetDir); + for (NodeIterator nit = baseNode.getNodes(); nit.hasNext();) { + Node node = nit.nextNode(); + if (node.isNodeType(NodeType.NT_FILE)) { + Path filePath = targetDir.resolve(node.getName()); + try (OutputStream out = Files.newOutputStream(filePath); InputStream in = getFileAsStream(node)) { + IOUtils.copy(in, out); + } + } else if (recursive && node.isNodeType(NodeType.NT_FOLDER)) { + Path dirPath = targetDir.resolve(node.getName()); + copyFilesToFs(node, dirPath, true); + } + } + } catch (RepositoryException e) { + throw new JcrException("Cannot copy " + baseNode + " to " + targetDir, e); + } catch (IOException e) { + throw new RuntimeException("Cannot copy " + baseNode + " to " + targetDir, e); + } + } + /** * Computes the checksum of an nt:file. *