jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r719577 - in /jackrabbit/trunk/jackrabbit-jcr2spi/src: main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java test/java/org/apache/jackrabbit/jcr2spi/lock/AbstractLockTest.java
Date Fri, 21 Nov 2008 13:27:19 GMT
Author: angela
Date: Fri Nov 21 05:27:19 2008
New Revision: 719577

URL: http://svn.apache.org/viewvc?rev=719577&view=rev
Log:
JCR-1868: Inconsistent state when removing mix:lockable from a locked Node

Modified:
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/lock/AbstractLockTest.java

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java?rev=719577&r1=719576&r2=719577&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java
(original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java
Fri Nov 21 05:27:19 2008
@@ -653,11 +653,7 @@
         // removed, if any references are left to this node.
         NodeTypeImpl mixin = session.getNodeTypeManager().getNodeType(ntName);
         if (mixin.isNodeType(NameConstants.MIX_REFERENCEABLE)) {
-            // build effective node type of remaining mixin's & primary type
-            Name[] allRemaining = (Name[]) mixinValue.toArray(new Name[mixinValue.size()
+ 1]);
-            allRemaining[mixinValue.size()] = primaryTypeName;
-            EffectiveNodeType entRemaining = session.getEffectiveNodeTypeProvider().getEffectiveNodeType(allRemaining);
-
+            EffectiveNodeType entRemaining = getRemainingENT(mixinValue);
             if (!entRemaining.includesNodeType(NameConstants.MIX_REFERENCEABLE)) {
                 PropertyIterator iter = getReferences();
                 if (iter.hasNext()) {
@@ -666,6 +662,17 @@
             }
         }
 
+        /*
+         * mix:lockable: the mixin cannot be removed if the node is currently
+         * locked even if the editing session is the lock holder.
+         */
+        if (mixin.isNodeType((NameConstants.MIX_LOCKABLE))) {
+            EffectiveNodeType entRemaining = getRemainingENT(mixinValue);
+            if (!entRemaining.includesNodeType(NameConstants.MIX_LOCKABLE) && isLocked())
{
+                throw new ConstraintViolationException(mixinName + " can not be removed:
the node is locked.");
+            }
+        }
+
         // delegate to operation
         Name[] mixins = (Name[]) mixinValue.toArray(new Name[mixinValue.size()]);
         Operation op = SetMixin.create(getNodeState(), mixins);
@@ -709,6 +716,21 @@
     }
 
     /**
+     * Build the effective node type of remaining mixin's & primary type
+     *
+     * @param remainingMixins
+     * @return effective node type
+     * @throws ConstraintViolationException
+     * @throws NoSuchNodeTypeException
+     */
+    private EffectiveNodeType getRemainingENT(List remainingMixins)
+            throws ConstraintViolationException, NoSuchNodeTypeException {
+        Name[] allRemaining = (Name[]) remainingMixins.toArray(new Name[remainingMixins.size()
+ 1]);
+        allRemaining[remainingMixins.size()] = primaryTypeName;
+        return session.getEffectiveNodeTypeProvider().getEffectiveNodeType(allRemaining);
+    }
+
+    /**
      * @see Node#canAddMixin(String)
      */
     public boolean canAddMixin(String mixinName) throws RepositoryException {

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/lock/AbstractLockTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/lock/AbstractLockTest.java?rev=719577&r1=719576&r2=719577&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/lock/AbstractLockTest.java
(original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/lock/AbstractLockTest.java
Fri Nov 21 05:27:19 2008
@@ -25,8 +25,11 @@
 import javax.jcr.RepositoryException;
 import javax.jcr.Node;
 import javax.jcr.Repository;
+import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.lock.Lock;
 import javax.jcr.lock.LockException;
+import java.util.List;
+import java.util.Arrays;
 
 /**
  * <code>AbstractLockTest</code>...
@@ -342,4 +345,39 @@
         n.remove();
         otherSession.save();
     }
+
+    public void testRemoveMixLockableFromLockedNode() throws RepositoryException {
+        try {
+            lockedNode.removeMixin(mixLockable);
+            lockedNode.save();
+
+            // the mixin got removed -> the lock should implicitely be released
+            // as well in order not to have inconsistencies
+            String msg = "Lock should have been released.";
+            assertFalse(msg, lock.isLive());
+            assertFalse(msg, lockedNode.isLocked());
+            List tokens = Arrays.asList(superuser.getLockTokens());
+            assertFalse(msg, tokens.contains(lock.getLockToken()));
+
+            assertFalse(msg, lockedNode.hasProperty(jcrLockOwner));
+            assertFalse(msg, lockedNode.hasProperty(jcrlockIsDeep));
+
+        } catch (ConstraintViolationException e) {
+            // cannot remove the mixin -> ok
+            // consequently the node must still be locked, the lock still live...
+            String msg = "Lock must still be live.";
+            assertTrue(msg, lock.isLive());
+            assertTrue(msg, lockedNode.isLocked());
+            List tokens = Arrays.asList(superuser.getLockTokens());
+            assertTrue(tokens.contains(lock.getLockToken()));
+            assertTrue(msg, lockedNode.hasProperty(jcrLockOwner));
+            assertTrue(msg, lockedNode.hasProperty(jcrlockIsDeep));
+        } finally {
+            // ev. re-add the mixin in order to be able to unlock the node
+            if (lockedNode.isLocked() && !lockedNode.isNodeType(mixLockable)) {
+                lockedNode.addMixin(mixLockable);
+                lockedNode.save();
+            }
+        }
+    }
 }
\ No newline at end of file



Mime
View raw message