shodaaan commented on code in PR #1474:
URL: https://github.com/apache/jackrabbit-oak/pull/1474#discussion_r1642962427


##########
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionEditor.java:
##########
@@ -145,27 +146,71 @@ public void propertyChanged(PropertyState before, 
PropertyState after)
             return;
         }
         String propName = after.getName();
+
+        // Updates the checked-out / checked-in state of the currently 
processed node when
+        // the JCR_ISCHECKEDOUT property change is processed.
         if (propName.equals(JCR_ISCHECKEDOUT)) {
             if (wasCheckedIn()) {
                 vMgr.checkout(node);
             } else {
                 vMgr.checkin(node);
             }
         } else if (propName.equals(JCR_BASEVERSION)) {
-            String baseVersion = after.getValue(Type.REFERENCE);
-            if (baseVersion.startsWith(RESTORE_PREFIX)) {
-                baseVersion = baseVersion.substring(RESTORE_PREFIX.length());
-                node.setProperty(JCR_BASEVERSION, baseVersion, Type.REFERENCE);
+
+            // Completes the restore of a version from version history.
+            //
+            // When the JCR_BASEVERSION property is processed, a check is made 
for the current
+            // base version property.
+            // If a restore is currently in progress for the current base 
version (the check for
+            // this is that the current base version name has the format 
"restore-[UUID of the
+            // version to restore to]"), then the restore is completed for the 
current node
+            // to the version specified by the UUID.
+            //
+            // If a node that was moved or copied to the location of a deleted 
node is currently
+            // being processed (see OAK-8848 for context), the restore 
operation must NOT be
+            // performed when the JCR_BASEVERSION property change is processed 
for the node.
+            if (!nodeWasMovedOrCopied()) {
+
+                String baseVersion = after.getValue(Type.REFERENCE);
+                if (baseVersion.startsWith(RESTORE_PREFIX)) {
+                    baseVersion = 
baseVersion.substring(RESTORE_PREFIX.length());
+                    node.setProperty(JCR_BASEVERSION, baseVersion, 
Type.REFERENCE);
+                }
+
+                vMgr.restore(node, baseVersion, null);
             }
-            vMgr.restore(node, baseVersion, null);
         } else if (isVersionProperty(after)) {
-            throwProtected(after.getName());
+            // Checks if a version property is being changed and throws a 
CommitFailedException
+            // with the message "Constraint Violation Exception" if this is 
not allowed.
+            // JCR_ISCHECKEDOUT and JCR_BASEVERSION properties should be 
ignored, since changes
+            // to them are allowed for specific use cases (for example, 
completing the check-in
+            // / check-out for a node or completing a node restore).
+            //
+            // The only situation when the update of a version property is 
allowed is when this
+            // occurs as a result of the current node being moved over a 
previously deleted node
+            // - see OAK-8848 for context.
+            //
+            // OAK-8848: moving a versionable node in the same location as a 
node deleted in the
+            // same session should be allowed.
+            // This check works because the only way that moving a node in a 
location is allowed
+            // is if there is no existing (undeleted) node in that location.
+            // Property comparison should not fail for two jcr:versionHistory 
properties in this case.
+            if (!nodeWasMovedOrCopied()) {
+                throwProtected(after.getName());
+            }
         } else if (isReadOnly && getOPV(after) != 
OnParentVersionAction.IGNORE) {
             throwCheckedIn("Cannot change property " + after.getName()
                     + " on checked in node");
         }
     }
 
+    /**
+     * Returns true if and only if the given node was moved or copied from 
another location.
+     */
+    private boolean nodeWasMovedOrCopied() {

Review Comment:
   I just tested the copy instead of move case and it can not be done in one 
session, because WorkspaceDelegate.copy throws a javax.jcr.ItemExistsException. 
   Copy was not mentioned in the ticket requirement either, it was a wrong 
assumption on my part that copy will behave the same as move in this case.
   
   I will rename the check method to nodeWasMoved.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: oak-dev-unsubscr...@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to