You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by re...@apache.org on 2025/11/24 19:16:44 UTC

(jackrabbit-filevault) branch JCRVLT-828 created (now bd1d30c4)

This is an automated email from the ASF dual-hosted git repository.

reschke pushed a change to branch JCRVLT-828
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git


      at bd1d30c4 Fix handling of target node UUID for IdConflictPolicy.LEGACY

This branch includes the following new commits:

     new bd1d30c4 Fix handling of target node UUID for IdConflictPolicy.LEGACY

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(jackrabbit-filevault) 01/01: Fix handling of target node UUID for IdConflictPolicy.LEGACY

Posted by re...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

reschke pushed a commit to branch JCRVLT-828
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git

commit bd1d30c4d8822002d9061d2292c75777f13acc10
Author: Julian Reschke <re...@apache.org>
AuthorDate: Mon Nov 24 20:16:24 2025 +0100

    Fix handling of target node UUID for IdConflictPolicy.LEGACY
---
 .../ReferenceableIdentifiersImportIT.java          | 36 +++++++++++++++++++++-
 .../vault/fs/impl/io/DocViewImporter.java          | 25 ++++++++++++---
 2 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/vault-core-it/vault-core-integration-tests/src/main/java/org/apache/jackrabbit/vault/packaging/integration/ReferenceableIdentifiersImportIT.java b/vault-core-it/vault-core-integration-tests/src/main/java/org/apache/jackrabbit/vault/packaging/integration/ReferenceableIdentifiersImportIT.java
index 7694e504..aaa99abe 100644
--- a/vault-core-it/vault-core-integration-tests/src/main/java/org/apache/jackrabbit/vault/packaging/integration/ReferenceableIdentifiersImportIT.java
+++ b/vault-core-it/vault-core-integration-tests/src/main/java/org/apache/jackrabbit/vault/packaging/integration/ReferenceableIdentifiersImportIT.java
@@ -697,4 +697,38 @@ public class ReferenceableIdentifiersImportIT extends IntegrationTestBase {
         options.setIdConflictPolicy(policy);
         extractVaultPackage("/test-packages/referenceable-dup.zip", options);
     }
-}
\ No newline at end of file
+
+    @Test
+    public void testUuidPreservedWithLegacyPolicy() throws Exception {
+        // 1. Install package with UUID from package
+        extractVaultPackageStrict("/test-packages/referenceable.zip");
+        Node node = admin.getNode("/tmp/referenceable");
+        String originalUuid = node.getIdentifier();
+        assertEquals(UUID_REFERENCEABLE, originalUuid);
+
+        // 2. Change the UUID manually (simulating an existing node with different UUID)
+        // This simulates the scenario where node exists with UUID1, package has UUID2
+        node.remove();
+        admin.save();
+        node = JcrUtils.getOrCreateByPath("/tmp/referenceable", null, JcrConstants.NT_UNSTRUCTURED, admin, true);
+        node.addMixin(JcrConstants.MIX_VERSIONABLE);
+        node.setProperty(PROPERTY_NAME, PROPERTY_VALUE); // Keep same property
+        admin.save();
+        String currentUuid = node.getIdentifier();
+        assertNotEquals("Node should have different UUID than package", UUID_REFERENCEABLE, currentUuid);
+
+        // 3. Re-import with LEGACY policy and UPDATE_PROPERTIES mode
+        // Expected: UUID should be preserved (not replaced with package UUID)
+        // Bug: UUID gets replaced unconditionally at line 996
+        ImportOptions opts = getDefaultOptions();
+        opts.setIdConflictPolicy(IdConflictPolicy.LEGACY);
+        opts.setImportMode(ImportMode.REPLACE);
+        extractVaultPackage("/test-packages/referenceable.zip", opts);
+
+        // 4. Verify UUID is preserved (not replaced)
+        node = admin.getNode("/tmp/referenceable");
+        String finalUuid = node.getIdentifier();
+        assertEquals("UUID should be preserved with LEGACY policy", currentUuid, finalUuid);
+        assertNotEquals("UUID should NOT be replaced with package UUID", UUID_REFERENCEABLE, finalUuid);
+    }
+}
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewImporter.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewImporter.java
index bdab1ffb..212a73f3 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewImporter.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewImporter.java
@@ -906,8 +906,8 @@ public class DocViewImporter implements DocViewParserHandler {
                             } else {
                                 log.warn("To-be imported node and existing conflicting node have different parents. Will create new identifier for the former. ({})",
                                         newNodePath);
-                                preprocessedProperties.removeIf(p -> p.getName().equals(NameConstants.JCR_UUID) 
-                                        || p.getName().equals(NameConstants.JCR_BASEVERSION) 
+                                preprocessedProperties.removeIf(p -> p.getName().equals(NameConstants.JCR_UUID)
+                                        || p.getName().equals(NameConstants.JCR_BASEVERSION)
                                         || p.getName().equals(NameConstants.JCR_PREDECESSORS)
                                         || p.getName().equals(NameConstants.JCR_SUCCESSORS)
                                         || p.getName().equals(NameConstants.JCR_VERSIONHISTORY));
@@ -915,7 +915,11 @@ public class DocViewImporter implements DocViewParserHandler {
                         }
                     }
                 } catch (ItemNotFoundException e) {
-                    // ignore
+                    // no node with same ID present, but target node exists
+                    if (existingNode != null && idConflictPolicy == IdConflictPolicy.LEGACY && existingNode.isNodeType(JcrConstants.MIX_REFERENCEABLE)) {
+                        log.debug("IdConflictPolicy.LEGACY - removing Identifier " + identifier.get() + " from imported package at: " + docViewNode.getName());
+                        preprocessedProperties.removeIf(p -> p.getName().equals(NameConstants.JCR_UUID));
+                    }
                 }
             }
         }
@@ -1039,6 +1043,9 @@ public class DocViewImporter implements DocViewParserHandler {
                         newMixins.add(mixin);
                     }
                 }
+
+                boolean wasReferenceable = node.isNodeType(JcrConstants.MIX_REFERENCEABLE);
+
                 // remove mixins not in package (only for mode = replace)
                 if (importMode == ImportMode.REPLACE) {
                     for (NodeType mix : node.getMixinNodeTypes()) {
@@ -1049,12 +1056,20 @@ public class DocViewImporter implements DocViewParserHandler {
                                     || acHandling == AccessControlHandling.CLEAR
                                     || acHandling == AccessControlHandling.OVERWRITE) {
                                 vs.ensureCheckedOut();
-                                node.removeMixin(name);
+
+                                // can't remove a mixin which would remove the UUID in LEGACY Mode
+                                if (idConflictPolicy == idConflictPolicy.LEGACY && wasReferenceable && mix.isNodeType(JcrConstants.MIX_REFERENCEABLE)) {
+                                    log.debug("idConflictPolicy.LEGACY: not removing mixin " + mix.getName() + ", so that UUID can be preserved.");
+                                } else {
+                                    node.removeMixin(name);
+                                }
+
                                 updatedNode = node;
                             }
                         }
                     }
                 }
+
                 // add remaining mixins (for all import modes)
                 for (String mixin : newMixins) {
                     vs.ensureCheckedOut();
@@ -1080,7 +1095,7 @@ public class DocViewImporter implements DocViewParserHandler {
             }
             EffectiveNodeType effectiveNodeType = EffectiveNodeType.ofNode(node);
             Collection<DocViewProperty2> unprotectedProperties = removeProtectedProperties(ni.getProperties(), effectiveNodeType, node.getPath(), PROTECTED_PROPERTIES_CONSIDERED_FOR_UPDATED_NODES);
-            
+
             // add/modify properties contained in package
             if (setProperties(node, ni,unprotectedProperties, importMode == ImportMode.REPLACE|| importMode == ImportMode.UPDATE || importMode == ImportMode.UPDATE_PROPERTIES, vs)) {
                 updatedNode = node;