### Eclipse Workspace Patch 1.0 #P jackrabbit-core Index: src/test/java/org/apache/jackrabbit/core/XATest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/XATest.java (revision 819491) +++ src/test/java/org/apache/jackrabbit/core/XATest.java (working copy) @@ -1736,7 +1736,72 @@ superuser.logout(); otherSuperuser.logout(); } + + /** + * Test add lock token and remove node in in a transaction + * (see JCR-2332) + * @throws Exception + */ + public void testAddLockTokenRemoveNode() throws Exception { + // create new node and lock it + UserTransaction utx = new UserTransactionImpl(superuser); + utx.begin(); + // add node that is both lockable and referenceable, save + Node rootNode = superuser.getRootNode(); + Node n = rootNode.addNode(nodeName1); + n.addMixin(mixLockable); + n.addMixin(mixReferenceable); + rootNode.save(); + + String uuid = n.getUUID(); + + // lock this new node + Lock lock = n.lock(true, false); + String lockToken = lock.getLockToken(); + + // assert: session must get a non-null lock token + assertNotNull("session must get a non-null lock token", lockToken); + + // assert: session must hold lock token + assertTrue("session must hold lock token", containsLockToken(superuser, lockToken)); + + superuser.removeLockToken(lockToken); + assertNull("session must get a null lock token", lock.getLockToken()); + + // commit + utx.commit(); + + // refresh Lock Info + lock = n.getLock(); + + assertNull("session must get a null lock token", lock.getLockToken()); + + Session other = getHelper().getSuperuserSession(); + // start new Transaction and try to add lock token unlock the node and then remove it + utx = new UserTransactionImpl(other); + utx.begin(); + + Node otherNode = other.getNodeByUUID(uuid); + assertTrue("Node not locked", otherNode.isLocked()); + // add lock token + other.addLockToken(lockToken); + + // refresh Lock Info + lock = otherNode.getLock(); + + // assert: session must hold lock token + assertTrue("session must hold lock token", containsLockToken(other, lock.getLockToken())); + + otherNode.unlock(); + + assertFalse("Node is locked", otherNode.isLocked()); + + otherNode.remove(); + other.save(); + utx.commit(); + } + /** * Test setting the same property multiple times. Exposes an issue where * the same property instance got reused in subsequent transactions Index: src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java (revision 815651) +++ src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java (working copy) @@ -19,6 +19,7 @@ import org.apache.jackrabbit.core.TransactionException; import org.apache.jackrabbit.core.NodeImpl; import org.apache.jackrabbit.core.SessionImpl; +import org.apache.jackrabbit.core.XAWorkspace; import org.apache.jackrabbit.core.id.NodeId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -472,7 +473,11 @@ */ public void update() throws LockException, RepositoryException { if (isUnlock) { - lockMgr.internalUnlock(node); + // Only if we have a valid ItemState try to unlock + // JCR-2332 + if (((XAWorkspace)((SessionImpl)node.getSession()).getWorkspace()).getItemStateManager().hasItemState(node.getId())) { + lockMgr.internalUnlock(node); + } } else { LockInfo internalLock = lockMgr.internalLock( node, isDeep(), isSessionScoped(),