jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r1518049 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ oak-jcr/ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/lock/ oak-jcr/src/main/...
Date Wed, 28 Aug 2013 01:34:29 GMT
Author: jukka
Date: Wed Aug 28 01:34:28 2013
New Revision: 1518049

URL: http://svn.apache.org/r1518049
Log:
OAK-150: Basic JCR LockManager support

Improved tracking of session and open scoped locks and lock tokens
Better interaction between versioning and locking (it's possible to checkin a locked node,
not checkout)
Trimmed list of known TCK issues

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionConstants.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionEditor.java
    jackrabbit/oak/trunk/oak-jcr/pom.xml
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionContext.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/lock/LockImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/lock/LockManagerImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/version/VersionManagerImpl.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionConstants.java?rev=1518049&r1=1518048&r2=1518049&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionConstants.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionConstants.java
Wed Aug 28 01:34:28 2013
@@ -19,9 +19,12 @@ package org.apache.jackrabbit.oak.plugin
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Set;
 
 import org.apache.jackrabbit.JcrConstants;
 
+import com.google.common.collect.ImmutableSet;
+
 /**
  * VersionConstants... TODO
  */
@@ -128,6 +131,10 @@ public interface VersionConstants extend
             JCR_VERSIONHISTORY
     ));
 
+    Set<String> LOCK_PROPERTY_NAMES = ImmutableSet.of(
+            JCR_LOCKISDEEP,
+            JCR_LOCKOWNER);
+
     Collection<String> VERSION_NODE_NAMES = Collections.unmodifiableList(Arrays.asList(
             JCR_ACTIVITIES,
             JCR_CONFIGURATIONS,

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionEditor.java?rev=1518049&r1=1518048&r2=1518049&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionEditor.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionEditor.java
Wed Aug 28 01:34:28 2013
@@ -144,7 +144,7 @@ class VersionEditor implements Editor {
     public void propertyDeleted(PropertyState before)
             throws CommitFailedException {
         if (wasReadOnly) {
-            if (!isVersionProperty(before)) {
+            if (!isVersionProperty(before) && !isLockProperty(before)) {
                 throwCheckedIn("Cannot delete property on checked in node");
             }
         }
@@ -188,6 +188,10 @@ class VersionEditor implements Editor {
                 .contains(state.getName());
     }
 
+    private boolean isLockProperty(PropertyState state) {
+        return VersionConstants.LOCK_PROPERTY_NAMES.contains(state.getName());
+    }
+
     /**
      * @return {@code true} if this node <b>was</b> checked in. That is,
      *         this method checks the base state for the jcr:isCheckedOut

Modified: jackrabbit/oak/trunk/oak-jcr/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/pom.xml?rev=1518049&r1=1518048&r2=1518049&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-jcr/pom.xml Wed Aug 28 01:34:28 2013
@@ -72,63 +72,28 @@
       org.apache.jackrabbit.test.api.SerializationTest#testLockExceptionWorkspace       
              <!-- OAK-127: no session scoped locking -->
       org.apache.jackrabbit.test.api.SerializationTest#testLockExceptionSession         
              <!-- OAK-127: no session scoped locking -->
 
-      org.apache.jackrabbit.test.api.lock.LockTest#testAddRemoveLockToken
-      org.apache.jackrabbit.test.api.lock.LockTest#testOpenScopedLocks
-      org.apache.jackrabbit.test.api.lock.LockTest#testLogout
       org.apache.jackrabbit.test.api.lock.LockTest#testNodeLocked
       org.apache.jackrabbit.test.api.lock.LockTest#testParentChildDeepLock
       org.apache.jackrabbit.test.api.lock.LockTest#testIsSessionScoped
       org.apache.jackrabbit.test.api.lock.LockTest#testLockTransfer
       org.apache.jackrabbit.test.api.lock.LockTest#testRefreshNotLive
+      org.apache.jackrabbit.test.api.lock.LockTest#testAddRemoveLockToken
       org.apache.jackrabbit.test.api.lock.LockTest#testCheckedIn
+      org.apache.jackrabbit.test.api.lock.LockTest#testOpenScopedLocks
       org.apache.jackrabbit.test.api.lock.LockTest#testCheckedInUnlock
-
-<!--
-      org.apache.jackrabbit.test.api.lock.LockTest#testGetNode
-      org.apache.jackrabbit.test.api.lock.LockTest#testGetLockOwnerProperty
-      org.apache.jackrabbit.test.api.lock.LockTest#testGetLockOwner
-      org.apache.jackrabbit.test.api.lock.LockTest#testShallowLock
-      org.apache.jackrabbit.test.api.lock.LockTest#testParentChildLock
-      org.apache.jackrabbit.test.api.lock.LockTest#testIsDeep
-      org.apache.jackrabbit.test.api.lock.LockTest#testRefresh
-      org.apache.jackrabbit.test.api.lock.LockTest#testGetLock
-      org.apache.jackrabbit.test.api.lock.LockTest#testMoveLocked
--->
+      org.apache.jackrabbit.test.api.lock.LockTest#testLogout
 
       org.apache.jackrabbit.test.api.lock.SetValueLockExceptionTest#testSetValueLockException
 
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testIsLockOwningSession
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testIsLockedChild
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testIsLockedNewChild
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testGetLockOnChild
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testGetLockOnNewChild
+      org.apache.jackrabbit.test.api.lock.DeepLockTest#testShallowLockAboveLockedChild
       org.apache.jackrabbit.test.api.lock.DeepLockTest#testParentChildDeepLock
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testGetNodeOnLockObtainedFromChild
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testGetNodeOnLockObtainedFromNewChild
       org.apache.jackrabbit.test.api.lock.DeepLockTest#testDeepLockAboveLockedChild
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testIsLive
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testIsDeep
+      org.apache.jackrabbit.test.api.lock.DeepLockTest#testRemoveLockedChild
       org.apache.jackrabbit.test.api.lock.DeepLockTest#testIsSessionScoped
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testNodeIsLocked
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testNodeHoldsLocked
       org.apache.jackrabbit.test.api.lock.DeepLockTest#testRefreshNotLive
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testRemoveMixLockableFromLockedNode
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testGetSecondsRemaining
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testGetSecondsRemainingAfterUnlock
+      org.apache.jackrabbit.test.api.lock.DeepLockTest#testIsLockOwningSession
       org.apache.jackrabbit.test.api.lock.DeepLockTest#testUnlockByOtherSession
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testRemoveLockedChild
-
-<!--
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testShallowLockAboveLockedChild
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testRefresh
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testLockHoldingNode
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testLockVisibility
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testLockExpiration
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testOwnerHint
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testUnlock
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testHoldsLockChild
-      org.apache.jackrabbit.test.api.lock.DeepLockTest#testHoldsLockNewChild
--->
+      org.apache.jackrabbit.test.api.lock.DeepLockTest#testGetSecondsRemainingAfterUnlock
 
       org.apache.jackrabbit.test.api.lock.LockManagerTest#testLockTransfer
       org.apache.jackrabbit.test.api.lock.LockManagerTest#testLockTransfer2
@@ -136,39 +101,25 @@
       org.apache.jackrabbit.test.api.lock.LockManagerTest#testRemoveLockToken
       org.apache.jackrabbit.test.api.lock.LockManagerTest#testRemoveLockToken2
       org.apache.jackrabbit.test.api.lock.LockManagerTest#testRemoveLockToken3
-      org.apache.jackrabbit.test.api.lock.LockManagerTest#testNullOwnerHint
-      org.apache.jackrabbit.test.api.lock.LockManagerTest#testAddLockToken
+      org.apache.jackrabbit.test.api.lock.LockManagerTest#testLockWithPendingChanges
       org.apache.jackrabbit.test.api.lock.LockManagerTest#testGetLockTokens
       org.apache.jackrabbit.test.api.lock.LockManagerTest#testRemoveLockTokenTwice
       org.apache.jackrabbit.test.api.lock.LockManagerTest#testAddLockTokenAgain
       org.apache.jackrabbit.test.api.lock.LockManagerTest#testAddLockTokenToAnotherSession
-      org.apache.jackrabbit.test.api.lock.LockManagerTest#testLockWithPendingChanges
-      org.apache.jackrabbit.test.api.lock.LockManagerTest#testLockNonLockable
-      org.apache.jackrabbit.test.api.lock.LockManagerTest#testAddInvalidLockToken       
              <!-- OAK-150 ... -->
 
-      org.apache.jackrabbit.test.api.lock.OpenScopedLockTest#testIsLive
       org.apache.jackrabbit.test.api.lock.OpenScopedLockTest#testGetLockToken
-      org.apache.jackrabbit.test.api.lock.OpenScopedLockTest#testIsLockOwningSession
       org.apache.jackrabbit.test.api.lock.OpenScopedLockTest#testRefreshNotLive
-      org.apache.jackrabbit.test.api.lock.OpenScopedLockTest#testNodeIsLocked
-      org.apache.jackrabbit.test.api.lock.OpenScopedLockTest#testNodeHoldsLocked
-      org.apache.jackrabbit.test.api.lock.OpenScopedLockTest#testGetSecondsRemaining
-      org.apache.jackrabbit.test.api.lock.OpenScopedLockTest#testGetSecondsRemainingAfterUnlock
+      org.apache.jackrabbit.test.api.lock.OpenScopedLockTest#testIsLockOwningSession
       org.apache.jackrabbit.test.api.lock.OpenScopedLockTest#testUnlockByOtherSession
-      org.apache.jackrabbit.test.api.lock.OpenScopedLockTest#testRemoveMixLockableFromLockedNode
+      org.apache.jackrabbit.test.api.lock.OpenScopedLockTest#testGetSecondsRemainingAfterUnlock
 
-      org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testImplicitUnlock
-      org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testImplicitUnlock2
-      org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testIsLockOwningSession
       org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testIsSessionScoped
       org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testRefreshNotLive
-      org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testNodeIsLocked
-      org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testNodeHoldsLocked
-      org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testGetSecondsRemaining
-      org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testGetSecondsRemainingAfterUnlock
+      org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testIsLockOwningSession
       org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testUnlockByOtherSession
-      org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testIsLive
-      org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testRemoveMixLockableFromLockedNode
 <!-- ... OAK-150 -->
+      org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testGetSecondsRemainingAfterUnlock
+      org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testImplicitUnlock
+      org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testImplicitUnlock2
 
       <!-- Lifecycle Mgt : not implemented -->
       org.apache.jackrabbit.test.api.LifecycleTest

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java?rev=1518049&r1=1518048&r2=1518049&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java
Wed Aug 28 01:34:28 2013
@@ -39,6 +39,7 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.Value;
 import javax.jcr.ValueFactory;
+import javax.jcr.lock.LockException;
 import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.nodetype.ItemDefinition;
 import javax.jcr.version.VersionManager;

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionContext.java?rev=1518049&r1=1518048&r2=1518049&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionContext.java
(original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionContext.java
Wed Aug 28 01:34:28 2013
@@ -17,10 +17,13 @@
 package org.apache.jackrabbit.oak.jcr;
 
 import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Sets.newHashSet;
+import static com.google.common.collect.Sets.newTreeSet;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
@@ -89,6 +92,12 @@ public class SessionContext implements N
     private PrivilegeManager privilegeManager;
     private ObservationManagerImpl observationManager;
 
+    /** Paths (tokens) of all open scoped locks held by this session. */
+    private final Set<String> openScopedLocks = newTreeSet();
+
+    /** Paths of all session scoped locks held by this session. */
+    private final Set<String> sessionScopedLocks = newHashSet();
+
     public SessionContext(
             @Nonnull RepositoryImpl repository, @Nonnull Whiteboard whiteboard,
             Map<String, Object> attributes, @Nonnull final SessionDelegate delegate)
{
@@ -244,6 +253,14 @@ public class SessionContext implements N
         return observationManager;
     }
 
+    public Set<String> getOpenScopedLocks() {
+        return openScopedLocks;
+    }
+
+    public Set<String> getSessionScopedLocks() {
+        return sessionScopedLocks;
+    }
+
     //-----------------------------------------------------< NamePathMapper >---
 
     @Override
@@ -335,6 +352,7 @@ public class SessionContext implements N
     //-----------------------------------------------------------< internal >---
 
     void dispose() {
+        getWorkspace().getLockManager().unlockAllSessionScopedLocks();
         if (observationManager != null) {
             observationManager.dispose();
         }

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java?rev=1518049&r1=1518048&r2=1518049&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/WorkspaceImpl.java
Wed Aug 28 01:34:28 2013
@@ -61,7 +61,7 @@ public class WorkspaceImpl implements Ja
     private final SessionContext sessionContext;
     private final SessionDelegate sessionDelegate;
     private final QueryManagerImpl queryManager;
-    private final LockManager lockManager;
+    private final LockManagerImpl lockManager;
     private final VersionManagerImpl versionManager;
     private final ReadWriteNodeTypeManager nodeTypeManager;
 
@@ -182,7 +182,7 @@ public class WorkspaceImpl implements Ja
     }
 
     @Override
-    public LockManager getLockManager() {
+    public LockManagerImpl getLockManager() {
         return lockManager;
     }
 

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/lock/LockImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/lock/LockImpl.java?rev=1518049&r1=1518048&r2=1518049&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/lock/LockImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/lock/LockImpl.java
Wed Aug 28 01:34:28 2013
@@ -89,7 +89,12 @@ public final class LockImpl implements L
         return safePerform(new NodeOperation<String>(delegate) {
             @Override
             public String perform() throws RepositoryException {
-                return node.getPath();
+                String token = node.getPath();
+                if (context.getOpenScopedLocks().contains(token)) {
+                    return token;
+                } else {
+                    return null;
+                }
             }
         });
     }
@@ -105,12 +110,25 @@ public final class LockImpl implements L
 
     @Override
     public boolean isSessionScoped() {
-        return false;
+        return safePerform(new NodeOperation<Boolean>(delegate) {
+            @Override
+            public Boolean perform() throws RepositoryException {
+                String path = node.getPath();
+                return context.getSessionScopedLocks().contains(path);
+            }
+        });
     }
 
     @Override
     public boolean isLockOwningSession() {
-        return true;
+        return safePerform(new NodeOperation<Boolean>(delegate) {
+            @Override
+            public Boolean perform() throws RepositoryException {
+                String path = node.getPath();
+                return context.getSessionScopedLocks().contains(path)
+                        || context.getOpenScopedLocks().contains(path);
+            }
+        });
     }
 
     @Override

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/lock/LockManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/lock/LockManagerImpl.java?rev=1518049&r1=1518048&r2=1518049&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/lock/LockManagerImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/lock/LockManagerImpl.java
Wed Aug 28 01:34:28 2013
@@ -16,8 +16,7 @@
  */
 package org.apache.jackrabbit.oak.jcr.lock;
 
-import static com.google.common.collect.Sets.newTreeSet;
-
+import java.util.Iterator;
 import java.util.Set;
 
 import javax.annotation.Nonnull;
@@ -33,6 +32,8 @@ import org.apache.jackrabbit.oak.jcr.Ses
 import org.apache.jackrabbit.oak.jcr.delegate.NodeDelegate;
 import org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate;
 import org.apache.jackrabbit.oak.jcr.operation.SessionOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Simple lock manager implementation that just keeps track of a set of lock
@@ -41,31 +42,63 @@ import org.apache.jackrabbit.oak.jcr.ope
  */
 public class LockManagerImpl implements LockManager {
 
+    /** Logger instance */
+    private static final Logger log =
+            LoggerFactory.getLogger(LockManagerImpl.class);
+
     private final SessionContext sessionContext;
 
     private final SessionDelegate delegate;
 
-    private final Set<String> tokens = newTreeSet();
-
     public LockManagerImpl(SessionContext sessionContext) {
         this.sessionContext = sessionContext;
         this.delegate = sessionContext.getSessionDelegate();
     }
 
     @Override @Nonnull
-    public synchronized String[] getLockTokens() {
-        return tokens.toArray(new String[tokens.size()]);
+    public String[] getLockTokens() throws RepositoryException {
+        return perform(new SessionOperation<String[]>() {
+            @Override @Nonnull
+            public String[] perform() {
+                Set<String> tokens = sessionContext.getOpenScopedLocks();
+                return tokens.toArray(new String[tokens.size()]);
+            }
+        });
     }
 
     @Override
-    public synchronized void addLockToken(String lockToken) {
-        tokens.add(lockToken);
+    public void addLockToken(final String lockToken)
+            throws RepositoryException {
+        try {
+            perform(new LockOperation<String>(sessionContext, lockToken) {
+                @Override
+                protected String perform(NodeDelegate node)
+                        throws LockException {
+                    if (node.holdsLock(false)) {
+                        String token = node.getPath();
+                        sessionContext.getOpenScopedLocks().add(token);
+                        return null;
+                    } else {
+                        throw new LockException(
+                                "Invalid lock token: " + lockToken);
+                    }
+                }
+            });
+        } catch (IllegalArgumentException e) { // TODO: better exception
+            throw new LockException("Invalid lock token: " + lockToken);
+        }
     }
 
     @Override
-    public synchronized void removeLockToken(String lockToken)
-            throws LockException {
-        if (!tokens.remove(lockToken)) {
+    public void removeLockToken(final String lockToken)
+            throws RepositoryException {
+        if (!perform(new SessionOperation<Boolean>() {
+            @Override @Nonnull
+            public Boolean perform() {
+                // TODO: name mapping?
+                return sessionContext.getOpenScopedLocks().remove(lockToken);
+            }
+        })) {
             throw new LockException(
                     "Lock token " + lockToken + " is not held by this session");
         }
@@ -109,9 +142,9 @@ public class LockManagerImpl implements 
 
     @Override @Nonnull
     public Lock lock(
-            String absPath, final boolean isDeep, boolean isSessionScoped,
+            String absPath, final boolean isDeep, final boolean isSessionScoped,
             long timeoutHint, String ownerInfo) throws RepositoryException {
-        NodeDelegate lock = perform(
+        return new LockImpl(sessionContext, perform(
                 new LockOperation<NodeDelegate>(sessionContext, absPath) {
                     @Override
                     protected NodeDelegate perform(NodeDelegate node)
@@ -121,14 +154,16 @@ public class LockManagerImpl implements 
                                     "Unable to lock a node with pending changes");
                         }
                         node.lock(isDeep);
+                        String path = node.getPath();
+                        if (isSessionScoped) {
+                            sessionContext.getSessionScopedLocks().add(path);
+                        } else {
+                            sessionContext.getOpenScopedLocks().add(path);
+                        }
                         session.refresh(true);
                         return node;
                     }
-                });
-        if (!isSessionScoped) {
-            addLockToken(absPath);
-        }
-        return new LockImpl(sessionContext, lock);
+                }));
     }
 
     @Override
@@ -137,13 +172,48 @@ public class LockManagerImpl implements 
             @Override
             protected Void perform(NodeDelegate node)
                     throws RepositoryException {
-                node.unlock();
-                session.refresh(true);
-                return null;
+                String path = node.getPath();
+                if (sessionContext.getSessionScopedLocks().contains(path)
+                        || sessionContext.getOpenScopedLocks().contains(path)) {
+                    node.unlock();
+                    sessionContext.getSessionScopedLocks().remove(path);
+                    sessionContext.getOpenScopedLocks().remove(path);
+                    session.refresh(true);
+                    return null;
+                } else {
+                    throw new LockException("Not an owner of the lock " + path);
+                }
             }
         });
     }
 
+    public void unlockAllSessionScopedLocks() {
+        try {
+            perform(new SessionOperation<Void>() {
+                @Override
+                public Void perform() throws RepositoryException {
+                    SessionDelegate delegate = sessionContext.getSessionDelegate();
+                    Iterator<String> iterator =
+                            sessionContext.getSessionScopedLocks().iterator();
+                    while (iterator.hasNext()) {
+                        NodeDelegate node = delegate.getNode(iterator.next());
+                        if (node != null) {
+                            try {
+                                node.unlock();
+                            } catch (RepositoryException e) {
+                                log.warn("Failed to clean up a session scoped lock", e);
+                            }
+                        }
+                        iterator.remove();
+                    }
+                    return null;
+                }
+            });
+        } catch (RepositoryException e) {
+            log.warn("Unexpected repository exception", e);
+        }
+    }
+
     private <T> T perform(SessionOperation<T> operation)
             throws RepositoryException {
         return delegate.perform(operation);

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/version/VersionManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/version/VersionManagerImpl.java?rev=1518049&r1=1518048&r2=1518049&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/version/VersionManagerImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/version/VersionManagerImpl.java
Wed Aug 28 01:34:28 2013
@@ -352,7 +352,6 @@ public class VersionManagerImpl implemen
                 if (nodeDelegate == null) {
                     throw new PathNotFoundException(absPath);
                 }
-                checkNotLocked(absPath);
                 return new VersionImpl(versionManagerDelegate.checkin(nodeDelegate), sessionContext);
             }
         });



Mime
View raw message