Index: vault-sync/src/main/java/org/apache/jackrabbit/vault/sync/impl/TreeSync.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/vault-sync/src/main/java/org/apache/jackrabbit/vault/sync/impl/TreeSync.java b/vault-sync/src/main/java/org/apache/jackrabbit/vault/sync/impl/TreeSync.java --- a/vault-sync/src/main/java/org/apache/jackrabbit/vault/sync/impl/TreeSync.java (revision 415a858cc5816f58b8010172360a69703e58b953) +++ b/vault-sync/src/main/java/org/apache/jackrabbit/vault/sync/impl/TreeSync.java (date 1649261154881) @@ -77,6 +77,8 @@ private final WorkspaceFilter wspFilter; + private boolean allowMixinNodes = false; + // currently hard coded private final String[] FULL_COVERAGE_NTS = { "rep:AccessControl", @@ -103,6 +105,10 @@ this.preserveFileDate = preserveFileDate; } + public void setAllowMixinNodesFiles(boolean allowMixinNodes) { + this.allowMixinNodes = allowMixinNodes; + } + public SyncResult sync(Node node, File dir) throws RepositoryException, IOException { SyncResult result = new SyncResult(); sync(result, node, dir); @@ -144,14 +150,18 @@ if (node == null) { return Type.MISSING; } else if (node.isNodeType(NodeType.NT_FILE)) { - if (node.getMixinNodeTypes().length == 0) { - // only ok, if pure nt:file - Node content = node.getNode(Node.JCR_CONTENT); - if (content.isNodeType(NodeType.NT_RESOURCE) && content.getMixinNodeTypes().length == 0) { - return Type.FILE; - } - } - return Type.UNSUPPORTED; + if (allowMixinNodes) { // Force to sync mixin nodes, use carefully + return Type.FILE; + } else { + if (node.getMixinNodeTypes().length == 0) { + // only ok, if pure nt:file + Node content = node.getNode(Node.JCR_CONTENT); + if (content.isNodeType(NodeType.NT_RESOURCE) && content.getMixinNodeTypes().length == 0) { + return Type.FILE; + } + } + return Type.UNSUPPORTED; + } } for (String nt: FULL_COVERAGE_NTS) { try { @@ -377,21 +387,28 @@ } private void writeFile(SyncResult res, Entry e) throws IOException, RepositoryException { - String action = e.file.exists() ? "U" : "A"; + File entryFile = e.file; + String action = entryFile.exists() ? "U" : "A"; Binary bin = null; InputStream in = null; OutputStream out = null; try { - bin = e.node.getProperty("jcr:content/jcr:data").getBinary(); - in = bin.getStream(); - out = FileUtils.openOutputStream(e.file); - IOUtils.copy(in, out); - if (preserveFileDate) { - Calendar lastModified = e.node.getProperty("jcr:content/jcr:lastModified").getDate(); - e.file.setLastModified(lastModified.getTimeInMillis()); - } - syncLog.log("%s file://%s", action, e.file.getAbsolutePath()); - res.addEntry(e.getJcrPath(), e.getFsPath(), SyncResult.Operation.UPDATE_FS); + long entryNodeLastModifiedDate = getEntryLastModified(e); + + if (entryFile.lastModified() != entryNodeLastModifiedDate) { + bin = e.node.getProperty("jcr:content/jcr:data").getBinary(); + in = bin.getStream(); + out = FileUtils.openOutputStream(entryFile); + IOUtils.copy(in, out); + + if (preserveFileDate && entryNodeLastModifiedDate != 0) { + Calendar lastModified = e.node.getProperty("jcr:content/jcr:lastModified").getDate(); + entryFile.setLastModified(lastModified.getTimeInMillis()); + } + + syncLog.log("%s file://%s", action, entryFile.getAbsolutePath()); + res.addEntry(e.getJcrPath(), e.getFsPath(), SyncResult.Operation.UPDATE_FS); + } } finally { IOUtils.closeQuietly(in); IOUtils.closeQuietly(out); @@ -401,6 +418,16 @@ } } + private long getEntryLastModified(Entry e) throws RepositoryException { + Property entryLastModifiedProperty = e.node.getProperty("jcr:content/jcr:lastModified"); + + if (entryLastModifiedProperty != null && entryLastModifiedProperty.getDate() != null) { + return entryLastModifiedProperty.getDate().getTimeInMillis(); + } + + return 0; + } + private void writeNtFile(SyncResult res, Entry e) throws RepositoryException, IOException { Node ntFile = e.node; Node content;