jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r753244 - in /jackrabbit/trunk: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/ jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/ jackrabbit-core/src/tes...
Date Fri, 13 Mar 2009 13:37:46 GMT
Author: angela
Date: Fri Mar 13 13:37:44 2009
New Revision: 753244

URL: http://svn.apache.org/viewvc?rev=753244&view=rev
Log:
JCR-1590 JSR 283: Locking

- getSecondsRemaining is negative if lock is expired or released
- getLockToken always returns null if lock is sessionscoped

JCR-2004 Update SPI locking to match JCR 2.0

- extend spi/LockInfo.java
- add JCR 2.0 variant of RepositoryService#lock that takes timeoutHint and ownerHint
- adjust jcr2spi
- adjust spi implementation(s)

Added:
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/WorkspaceTest.java   (with props)
Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/AbstractLockInfo.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/SessionLockManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XALockManager.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/TestAll.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/lock/AbstractLockTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/lock/LockManagerTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/lock/SessionScopedLockTest.java
    jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/DefaultItemCollection.java
    jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/lock/JcrActiveLock.java
    jackrabbit/trunk/jackrabbit-jcr2spi/pom.xml
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/NodeImpl.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceImpl.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/DefaultLockManager.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManager.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManagerImpl.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockOperation.java
    jackrabbit/trunk/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/lock/AbstractLockTest.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/LockInfoImpl.java
    jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/LockInfo.java
    jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java
    jackrabbit/trunk/jackrabbit-spi2jcr/pom.xml
    jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/LockInfoImpl.java
    jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/RepositoryServiceImpl.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java Fri Mar 13 13:37:44 2009
@@ -4408,7 +4408,7 @@
             RepositoryException {
         // check state of this instance
         sanityCheck();
-        LockManager lockMgr = ((WorkspaceImpl) session.getWorkspace()).get283LockManager();
+        LockManager lockMgr = ((WorkspaceImpl) session.getWorkspace()).getLockManager();
         return lockMgr.lock(getPath(), isDeep, isSessionScoped, Long.MAX_VALUE, null);
     }
 
@@ -4420,7 +4420,7 @@
             AccessDeniedException, RepositoryException {
         // check state of this instance
         sanityCheck();
-        LockManager lockMgr = ((WorkspaceImpl) session.getWorkspace()).get283LockManager();
+        LockManager lockMgr = ((WorkspaceImpl) session.getWorkspace()).getLockManager();
         return lockMgr.getLock(getPath());
     }
 
@@ -4433,7 +4433,7 @@
             RepositoryException {
         // check state of this instance
         sanityCheck();
-        LockManager lockMgr = ((WorkspaceImpl) session.getWorkspace()).get283LockManager();
+        LockManager lockMgr = ((WorkspaceImpl) session.getWorkspace()).getLockManager();
         lockMgr.unlock(getPath());
     }
 
@@ -4443,7 +4443,7 @@
     public boolean holdsLock() throws RepositoryException {
         // check state of this instance
         sanityCheck();
-        LockManager lockMgr = ((WorkspaceImpl) session.getWorkspace()).get283LockManager();
+        LockManager lockMgr = ((WorkspaceImpl) session.getWorkspace()).getLockManager();
         return lockMgr.holdsLock(getPath());
     }
 
@@ -4453,7 +4453,7 @@
     public boolean isLocked() throws RepositoryException {
         // check state of this instance
         sanityCheck();
-        LockManager lockMgr = ((WorkspaceImpl) session.getWorkspace()).get283LockManager();
+        LockManager lockMgr = ((WorkspaceImpl) session.getWorkspace()).getLockManager();
         return lockMgr.isLocked(getPath());
     }
 

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java Fri Mar 13 13:37:44 2009
@@ -1252,7 +1252,7 @@
      */
     public void addLockToken(String lt) {
         try {
-            wsp.get283LockManager().addLockToken(lt);
+            wsp.getLockManager().addLockToken(lt);
         } catch (RepositoryException e) {
             log.debug("Error while adding lock token.");
         }
@@ -1263,7 +1263,7 @@
      */
     public String[] getLockTokens() {
         try {
-            return wsp.get283LockManager().getLockTokens();
+            return wsp.getLockManager().getLockTokens();
         } catch (RepositoryException e) {
             log.debug("Error while accessing lock tokens.");
             return new String[0];
@@ -1275,7 +1275,7 @@
      */
     public void removeLockToken(String lt) {
         try {
-            wsp.get283LockManager().removeLockToken(lt);
+            wsp.getLockManager().removeLockToken(lt);
         } catch (RepositoryException e) {
             log.debug("Error while removing lock token.");
         }
@@ -1286,7 +1286,7 @@
      * @return lock manager for this session
      */
     public LockManager getLockManager() throws RepositoryException {
-        return wsp.getLockManager();
+        return wsp.getInternalLockManager();
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java Fri Mar 13 13:37:44 2009
@@ -18,6 +18,7 @@
 
 import org.apache.jackrabbit.api.JackrabbitWorkspace;
 import org.apache.jackrabbit.api.jsr283.observation.EventJournal;
+import org.apache.jackrabbit.api.jsr283.version.VersionManager;
 import org.apache.jackrabbit.core.config.WorkspaceConfig;
 import org.apache.jackrabbit.core.lock.LockManager;
 import org.apache.jackrabbit.core.lock.SessionLockManager;
@@ -73,7 +74,8 @@
  * A <code>WorkspaceImpl</code> ...
  */
 public class WorkspaceImpl extends AbstractWorkspace
-        implements JackrabbitWorkspace, EventStateCollectionFactory {
+        implements JackrabbitWorkspace, org.apache.jackrabbit.api.jsr283.Workspace,
+        EventStateCollectionFactory {
 
     private static Logger log = LoggerFactory.getLogger(WorkspaceImpl.class);
 
@@ -282,18 +284,22 @@
      * @see org.apache.jackrabbit.api.jsr283.Workspace#getLockManager()
      * @see org.apache.jackrabbit.api.jsr283.lock.LockManager
      */
-    // TODO: rename to 'getLockManager'.
-    // TODO  in order not to break compatilibiy with the 1.x releases
-    // TODO  the 283 method has been tmp. renamed since it conflicts with an
-    // TODO  existing public method, exposing the internal lock manager.
-    public org.apache.jackrabbit.api.jsr283.lock.LockManager get283LockManager() throws UnsupportedRepositoryOperationException, RepositoryException {
+    public org.apache.jackrabbit.api.jsr283.lock.LockManager getLockManager() throws UnsupportedRepositoryOperationException, RepositoryException {
         if (jcr283LockManager == null) {
             jcr283LockManager = new SessionLockManager(session, session.getLockManager());
         }
         return jcr283LockManager;
     }
 
+    /**
+     * @see org.apache.jackrabbit.api.jsr283.Workspace#getVersionManager()
+     */
+    public VersionManager getVersionManager() throws UnsupportedRepositoryOperationException, RepositoryException {
+        throw new UnsupportedRepositoryOperationException("not yet implemented");
+    }
+
     //-------------------------------< JackrabbitWorkspace/new JSR 283 method >
+
     /**
      * Creates a new <code>Workspace</code> with the specified
      * <code>name</code>. The new workspace is empty, meaning it contains only
@@ -520,7 +526,7 @@
      * @return lock manager for this workspace
      * @throws RepositoryException if an error occurs
      */
-    public synchronized LockManager getLockManager() throws RepositoryException {
+    public synchronized org.apache.jackrabbit.core.lock.LockManager getInternalLockManager() throws RepositoryException {
 
         // check state of this instance
         sanityCheck();
@@ -744,7 +750,7 @@
         boolean succeeded = false;
 
         try {
-            NodeId id = ops.move(srcPath, destPath);
+            ops.move(srcPath, destPath);
             ops.update();
             succeeded = true;
         } finally {

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java Fri Mar 13 13:37:44 2009
@@ -180,7 +180,7 @@
      */
     public LockManager getLockManager() throws RepositoryException {
         if (lockMgr == null) {
-            LockManagerImpl lockMgr = (LockManagerImpl) wsp.getLockManager();
+            LockManagerImpl lockMgr = (LockManagerImpl) wsp.getInternalLockManager();
             this.lockMgr = new XALockManager(lockMgr);
         }
         return lockMgr;

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/AbstractLockInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/AbstractLockInfo.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/AbstractLockInfo.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/AbstractLockInfo.java Fri Mar 13 13:37:44 2009
@@ -27,6 +27,15 @@
 public abstract class AbstractLockInfo {
 
     /**
+     * Constant for the undefined or infinite timeout.
+     */
+    static final long TIMEOUT_INFINITE = Long.MAX_VALUE;
+    /**
+     * Constant for the expired timeout.
+     */
+    static final long TIMEOUT_EXPIRED = -1;
+
+    /**
      * Lock token
      */
     protected final LockToken lockToken;
@@ -66,7 +75,7 @@
      */
     public AbstractLockInfo(LockToken lockToken, boolean sessionScoped, boolean deep,
                     String lockOwner) {
-        this(lockToken, sessionScoped, deep, lockOwner, Long.MAX_VALUE);
+        this(lockToken, sessionScoped, deep, lockOwner, TIMEOUT_INFINITE);
     }
 
     /**
@@ -172,7 +181,7 @@
     public long getSecondsRemaining() {
         // TODO: TOBEFIXED for 2.0
         // TODO  - add support for timeout specified by the API user -> LockManager#lock
-        return Long.MAX_VALUE;
+        return isLive() ? TIMEOUT_INFINITE : TIMEOUT_EXPIRED;
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java Fri Mar 13 13:37:44 2009
@@ -78,14 +78,9 @@
      * {@inheritDoc}
      */
     public String getLockToken() {
-        // TODO: TOBEFIXED for 2.0
-        // TODO  - token must not be exposed for session-scoped locks (-> adjust tests and derived projects first)
-        // TODO  - openScoped tokens *may* be exposed even if session is not lock holder
-        /*
         if (info.isSessionScoped()) {
             return null;
         }
-        */
         try {
             return info.getLockToken(node.getSession());
         } catch (RepositoryException e) {

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java Fri Mar 13 13:37:44 2009
@@ -47,6 +47,7 @@
 import org.apache.jackrabbit.spi.commons.conversion.MalformedPathException;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.apache.jackrabbit.spi.commons.name.PathMap;
+import org.apache.jackrabbit.api.jsr283.Workspace;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -275,8 +276,8 @@
     }
 
     static SessionLockManager getSessionLockManager(SessionImpl session) throws RepositoryException {
-        WorkspaceImpl wsp = (WorkspaceImpl) session.getWorkspace();
-        return (SessionLockManager) wsp.get283LockManager();
+        Workspace wsp = (Workspace) session.getWorkspace();
+        return (SessionLockManager) wsp.getLockManager();
     }
 
     /**
@@ -463,7 +464,7 @@
      */
     public Lock lock(NodeImpl node, boolean isDeep, boolean isSessionScoped)
             throws LockException, RepositoryException {
-        return lock(node, isDeep, isSessionScoped, Long.MAX_VALUE, null);
+        return lock(node, isDeep, isSessionScoped, AbstractLockInfo.TIMEOUT_INFINITE, null);
     }
 
     public Lock lock(NodeImpl node, boolean isDeep, boolean isSessionScoped, long timoutHint, String ownerInfo)
@@ -1134,7 +1135,7 @@
          */
         public LockInfo(LockToken lockToken, boolean sessionScoped,
                         boolean deep, String lockOwner) {
-            this(lockToken, sessionScoped, deep, lockOwner, Long.MAX_VALUE);
+            this(lockToken, sessionScoped, deep, lockOwner, TIMEOUT_INFINITE);
         }
 
         /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/SessionLockManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/SessionLockManager.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/SessionLockManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/SessionLockManager.java Fri Mar 13 13:37:44 2009
@@ -41,7 +41,7 @@
  * is associated with a single <code>Session</code> and its
  * <code>Workspace</code>.
  *
- * @see javax.jcr.Workspace#getLockManager()
+ * @see org.apache.jackrabbit.api.jsr283.Workspace#getLockManager()
  */
 public class SessionLockManager implements org.apache.jackrabbit.api.jsr283.lock.LockManager {
 
@@ -190,7 +190,7 @@
     /**
      *
      * @param lockToken
-     * @return
+     * @return <code>true</code> if the token was successfully added to the set.
      */
     boolean lockTokenAdded(String lockToken) {
         synchronized (lockTokens) {
@@ -201,7 +201,7 @@
     /**
      * 
      * @param lockToken
-     * @return
+     * @return <code>true</code> if the token was successfully removed from the set.
      */
     boolean lockTokenRemoved(String lockToken) {
         synchronized (lockTokens) {

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java Fri Mar 13 13:37:44 2009
@@ -107,7 +107,7 @@
      */
     public AbstractLockInfo lock(NodeImpl node, boolean isDeep, boolean isSessionScoped)
             throws LockException, RepositoryException {
-        return lock(node, isDeep, isSessionScoped, Long.MAX_VALUE, null);
+        return lock(node, isDeep, isSessionScoped, AbstractLockInfo.TIMEOUT_INFINITE, null);
     }
 
     /**
@@ -392,7 +392,7 @@
         public LockInfo(NodeImpl node, LockToken lockToken,
                         boolean sessionScoped, boolean deep, String lockOwner) {
 
-            this(node, lockToken, sessionScoped, deep, lockOwner, Long.MAX_VALUE);
+            this(node, lockToken, sessionScoped, deep, lockOwner, TIMEOUT_INFINITE);
         }
 
         /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XALockManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XALockManager.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XALockManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XALockManager.java Fri Mar 13 13:37:44 2009
@@ -65,7 +65,7 @@
      */
     public Lock lock(NodeImpl node, boolean isDeep, boolean isSessionScoped)
             throws LockException, RepositoryException {
-        return lock(node, isDeep, isSessionScoped, Long.MAX_VALUE, null);
+        return lock(node, isDeep, isSessionScoped, AbstractLockInfo.TIMEOUT_INFINITE, null);
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/TestAll.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/TestAll.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/TestAll.java Fri Mar 13 13:37:44 2009
@@ -30,6 +30,7 @@
     public static Test suite() {
         TestSuite suite = new TestSuite("org.apache.jackrabbit.api.jsr283 tests");
 
+        suite.addTestSuite(WorkspaceTest.class);
         suite.addTestSuite(SessionRemoveItemTest.class);
 
         return suite;

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/WorkspaceTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/WorkspaceTest.java?rev=753244&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/WorkspaceTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/WorkspaceTest.java Fri Mar 13 13:37:44 2009
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.api.jsr283;
+
+import org.apache.jackrabbit.test.AbstractJCRTest;
+import org.apache.jackrabbit.test.NotExecutableException;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+
+/**
+ * <code>WorkspaceTest</code>...
+ */
+public class WorkspaceTest extends AbstractJCRTest {
+
+    private Workspace workspace;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        javax.jcr.Workspace wsp = superuser.getWorkspace();
+        if (wsp instanceof Workspace) {
+            workspace = (Workspace) wsp;
+        } else {
+            throw new NotExecutableException("JCR 2.0 Workspace expected.");
+        }
+    }
+
+    /**
+     * Tests {@link org.apache.jackrabbit.api.jsr283.Workspace#getLockManager()}.
+     * 
+     * @throws RepositoryException
+     */
+    public void testGetLockManager() throws RepositoryException {
+        if (isSupported(Repository.OPTION_LOCKING_SUPPORTED)) {
+            assertNotNull(workspace.getLockManager());
+        } else {
+            try {
+                workspace.getLockManager();
+                fail("UnsupportedRepositoryOperationException expected. Locking is not supported.");
+            } catch (UnsupportedRepositoryOperationException e) {
+                // success.
+            }
+        }
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/WorkspaceTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/WorkspaceTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/lock/AbstractLockTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/lock/AbstractLockTest.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/lock/AbstractLockTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/lock/AbstractLockTest.java Fri Mar 13 13:37:44 2009
@@ -21,12 +21,16 @@
 import org.apache.jackrabbit.test.AbstractJCRTest;
 import org.apache.jackrabbit.test.RepositoryStub;
 import org.apache.jackrabbit.test.NotExecutableException;
+import org.apache.jackrabbit.test.JUnitTest;
+import org.apache.jackrabbit.test.api.observation.EventResult;
 import org.apache.jackrabbit.core.WorkspaceImpl;
 
 import javax.jcr.Node;
 import javax.jcr.Session;
 import javax.jcr.RepositoryException;
 import javax.jcr.Repository;
+import javax.jcr.observation.ObservationManager;
+import javax.jcr.observation.Event;
 import javax.jcr.lock.LockException;
 import javax.jcr.nodetype.ConstraintViolationException;
 
@@ -59,7 +63,7 @@
 
     protected void tearDown() throws Exception {
         // release the lock created during setup
-        if (lockMgr != null && lockedNode != null) {
+        if (lockMgr != null && lockedNode != null && lockMgr.isLocked(lockedNode.getPath())) {
             try {
                 lockMgr.unlock(lockedNode.getPath());
             } catch (RepositoryException e) {
@@ -95,7 +99,7 @@
 
     private static LockManager getLockManager(Session session) throws RepositoryException {
         // TODO: rm cast and adjust call as soon as 283 is released
-        return ((WorkspaceImpl) session.getWorkspace()).get283LockManager();
+        return ((WorkspaceImpl) session.getWorkspace()).getLockManager();
     }
 
     /**
@@ -178,11 +182,61 @@
     /**
      * Test {@link org.apache.jackrabbit.api.jsr283.lock.Lock#getSecondsRemaining()} 
      */
-    public void testGetSecondsRemaining() {
-        assertTrue("Seconds remaining must be a positive long or 0.", lock.getSecondsRemaining() >= 0);
+    public void testGetSecondsRemaining() throws RepositoryException {
+        if (lock.isLive()) {
+            assertTrue("Seconds remaining must be a positive long.", lock.getSecondsRemaining() > 0);            
+        } else {
+            assertTrue("Seconds remaining must be a negative long.", lock.getSecondsRemaining() < 0);
+        }
+    }
+
+    /**
+     * Test {@link org.apache.jackrabbit.api.jsr283.lock.Lock#getSecondsRemaining()}
+     */
+    public void testGetSecondsRemainingAfterUnlock() throws RepositoryException {
+        lockMgr.unlock(lockedNode.getPath());
+        assertTrue("Lock has been released: seconds remaining must be a negative long.", lock.getSecondsRemaining() < 0);
     }
 
     /**
+     * Test expiration of the lock
+     */
+    public void testLockExpiration() throws RepositoryException, NotExecutableException {
+        lockedNode.unlock();
+
+        ObservationManager obsMgr = superuser.getWorkspace().getObservationManager();
+        EventResult listener = new EventResult(((JUnitTest) this).log);
+        try {
+            obsMgr.addEventListener(listener, Event.PROPERTY_REMOVED, lockedNode.getPath(), false, new String[0], new String[0], false);
+
+            boolean lockPropRemoved = false;            
+            long hint = 1;
+            lock = lockMgr.lock(lockedNode.getPath(), isDeep(), isSessionScoped(), hint, null);
+            // only test if timeout hint was respected.
+            if (lock.getSecondsRemaining() <= 1) {
+                Event[] evts = listener.getEvents(2000);
+                for (int i = 0; i < evts.length; i++) {
+                    if (evts[i].getType() == Event.PROPERTY_REMOVED &&
+                            evts[i].getPath().endsWith(jcrLockOwner)) {
+                        lockPropRemoved = true;
+                        // lock property has been removed -> make sure lock has
+                        // been released and lock.getSecondsRemaining behaves properly.
+                        assertTrue("A released lock must return a negative number of seconds", lock.getSecondsRemaining() < 0);
+                        assertFalse("If the timeout hint is respected the lock must be automatically released.", lock.isLive());
+                        assertFalse("If the timeout hint is respected the lock must be automatically released.", lockedNode.isLocked());
+                    }
+                }
+                if (!lockPropRemoved) {
+                    fail("If the timeout hint is respected the lock must be automatically released.");
+                }
+            } else {
+                throw new NotExecutableException("timeout hint was ignored.");
+            }
+        } finally {
+            obsMgr.removeEventListener(listener);
+        }
+    }
+    /**
      * Test {@link LockManager#unlock(String)} for a session that is not
      * lock owner.
      * 

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/lock/LockManagerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/lock/LockManagerTest.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/lock/LockManagerTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/lock/LockManagerTest.java Fri Mar 13 13:37:44 2009
@@ -72,7 +72,7 @@
 
    private static LockManager getLockManager(Session session) throws RepositoryException {
         // TODO: rm cast and adjust call as soon as 283 is released
-        return ((WorkspaceImpl) session.getWorkspace()).get283LockManager();
+        return ((WorkspaceImpl) session.getWorkspace()).getLockManager();
     }
 
     private static boolean containsLockToken(LockManager lMgr, String token) throws RepositoryException {

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/lock/SessionScopedLockTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/lock/SessionScopedLockTest.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/lock/SessionScopedLockTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/lock/SessionScopedLockTest.java Fri Mar 13 13:37:44 2009
@@ -36,9 +36,7 @@
      * {@link org.apache.jackrabbit.api.jsr283.lock.Lock#getLockToken()} must
      * always return <code>null</code> for session scoped locks.
      */
-    /*
     public void testGetLockToken() {
         assertNull("A session scoped lock may never expose the token.", lock.getLockToken());
     }
-    */
 }
\ No newline at end of file

Modified: jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/DefaultItemCollection.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/DefaultItemCollection.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/DefaultItemCollection.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/DefaultItemCollection.java Fri Mar 13 13:37:44 2009
@@ -611,10 +611,10 @@
             try {
                 boolean sessionScoped = EXCLUSIVE_SESSION.equals(reqLockInfo.getScope());
                 Lock jcrLock = ((Node)item).lock(reqLockInfo.isDeep(), sessionScoped);
-                // add reference to DAVSession for this lock
-                getSession().addReference(jcrLock.getLockToken());
-                return new JcrActiveLock(jcrLock, sessionScoped);
-
+                ActiveLock lock = new JcrActiveLock(jcrLock);
+                 // add reference to DAVSession for this lock
+                getSession().addReference(lock.getToken());
+                return lock;
             } catch (RepositoryException e) {
                 // UnsupportedRepositoryOperationException should not occur...
                 throw new JcrDavException(e);
@@ -653,7 +653,7 @@
             try {
                 Lock jcrLock = ((Node) item).getLock();
                 jcrLock.refresh();
-                return new JcrActiveLock(jcrLock, EXCLUSIVE_SESSION.equals(lock.getScope()));
+                return new JcrActiveLock(jcrLock);
             } catch (RepositoryException e) {
                 /*
                   NOTE: LockException is only thrown by Lock.refresh()

Modified: jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/lock/JcrActiveLock.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/lock/JcrActiveLock.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/lock/JcrActiveLock.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/lock/JcrActiveLock.java Fri Mar 13 13:37:44 2009
@@ -16,7 +16,6 @@
  */
 package org.apache.jackrabbit.webdav.jcr.lock;
 
-import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.webdav.DavConstants;
 import org.apache.jackrabbit.webdav.jcr.ItemResourceConstants;
 import org.apache.jackrabbit.webdav.lock.AbstractActiveLock;
@@ -26,7 +25,6 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 import javax.jcr.lock.Lock;
 
@@ -38,7 +36,6 @@
     private static Logger log = LoggerFactory.getLogger(JcrActiveLock.class);
 
     private final Lock lock;
-    private final boolean sessionScoped;
 
     /**
      * Create a new <code>ActiveLock</code> object with type '{@link Type#WRITE write}'
@@ -47,21 +44,10 @@
      * @param lock
      */
     public JcrActiveLock(Lock lock) {
-        this (lock, lock.isSessionScoped());
-    }
-
-    /**
-     * Create a new <code>ActiveLock</code> object with type '{@link Type#WRITE write}'
-     * and scope '{@link Scope#EXCLUSIVE exclusive}'.
-     *
-     * @param lock
-     */
-    public JcrActiveLock(Lock lock, boolean sessionScoped) {
         if (lock == null) {
             throw new IllegalArgumentException("Can not create a ActiveLock with a 'null' argument.");
         }
         this.lock = lock;
-        this.sessionScoped = sessionScoped;
     }
 
     /**
@@ -98,11 +84,30 @@
      * UUID [Extension] ; The UUID production is the string representation of a
      * UUID, as defined in [ISO-11578]. Note that white space (LWS) is not allowed
      * between elements of this production.</cite>").
+     * <p/>
+     * In case of session-scoped JCR 2.0 locks, the token is never exposed even
+     * if the current session is lock holder. In order to cope with DAV specific
+     * requirements and the fulfill the requirement stated above, the node's
+     * identifier is subsequently exposed as DAV-token.
      *
      * @see ActiveLock#getToken()
      */
     public String getToken() {
-        return lock.getLockToken();
+        String token = lock.getLockToken();
+        if (token == null && lock.isSessionScoped()
+                && lock instanceof org.apache.jackrabbit.api.jsr283.lock.Lock
+                && ((org.apache.jackrabbit.api.jsr283.lock.Lock)lock).isLockOwningSession()) {
+            // special handling for session scoped locks that are owned by the
+            // current session but never expose their token with jsr 283.
+            try {
+                token = ((org.apache.jackrabbit.api.jsr283.Node)lock.getNode()).getIdentifier();
+            } catch (RepositoryException e) {
+                // should never get here
+                log.warn("Unexpected error while retrieving node identifier for building a DAV specific lock token.",e.getMessage());
+            }
+        }
+        // default behaviour: just return the token exposed by the lock.
+        return token;
     }
 
     /**
@@ -143,17 +148,7 @@
      * @see ActiveLock#isDeep()
      */
     public boolean isDeep() {
-        boolean isDeep = true;
-        Node n = lock.getNode();
-        try {
-            // find out about deepness. if node does not hold the lock its deep anyway
-            if (n.holdsLock() && n.hasProperty(JcrConstants.JCR_LOCKISDEEP)) {
-                isDeep = n.getProperty(JcrConstants.JCR_LOCKISDEEP).getBoolean();
-            }
-        } catch (RepositoryException e) {
-            // ignore and keep default depth settings
-        }
-        return isDeep;
+        return lock.isDeep();
     }
 
     /**
@@ -180,6 +175,6 @@
      * @see ActiveLock#getScope()
      */
     public Scope getScope() {
-        return (sessionScoped) ? ItemResourceConstants.EXCLUSIVE_SESSION : Scope.EXCLUSIVE;
+        return (lock.isSessionScoped()) ? ItemResourceConstants.EXCLUSIVE_SESSION : Scope.EXCLUSIVE;
     }
 }
\ No newline at end of file

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/pom.xml?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/pom.xml (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/pom.xml Fri Mar 13 13:37:44 2009
@@ -88,6 +88,13 @@
       <artifactId>jackrabbit-jcr-commons</artifactId>
       <version>1.6-SNAPSHOT</version>
     </dependency>
+    <!-- tmp dependency to jackrabbit-api until jsr 283 is released -->
+    <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>jackrabbit-api</artifactId>
+      <version>1.6-SNAPSHOT</version>
+    </dependency>
+    <!-- end of tmp dependency -->
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>

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=753244&r1=753243&r2=753244&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 Mar 13 13:37:44 2009
@@ -1090,10 +1090,14 @@
      * @see Node#lock(boolean, boolean)
      */
     public Lock lock(boolean isDeep, boolean isSessionScoped) throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, InvalidItemStateException, RepositoryException {
+        return lock(isDeep, isSessionScoped, Long.MAX_VALUE, null);
+    }
+
+    public Lock lock(boolean isDeep, boolean isSessionScoped, long timeoutHint, String ownerHint) throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, InvalidItemStateException, RepositoryException {
         checkIsLockable();
         checkHasPendingChanges();
 
-        return session.getLockManager().lock(getNodeState(), isDeep, isSessionScoped);
+        return session.getLockManager().lock(getNodeState(), isDeep, isSessionScoped, timeoutHint, ownerHint);
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceImpl.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceImpl.java Fri Mar 13 13:37:44 2009
@@ -493,7 +493,7 @@
      * @return a new <code>LockManager</code> instance.
      */
     protected LockManager createLockManager(WorkspaceManager wspManager, ItemManager itemManager) {
-        LockManager lMgr = new LockManagerImpl(wspManager, itemManager, session.getCacheBehaviour());
+        LockManager lMgr = new LockManagerImpl(wspManager, itemManager, session.getCacheBehaviour(), getPathResolver());
         session.addListener((LockManagerImpl) lMgr);
         return lMgr;
     }

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/WorkspaceManager.java Fri Mar 13 13:37:44 2009
@@ -946,7 +946,7 @@
          * @see OperationVisitor#visit(LockOperation)
          */
         public void visit(LockOperation operation) throws AccessDeniedException, InvalidItemStateException, UnsupportedRepositoryOperationException, LockException, RepositoryException {
-            LockInfo lInfo = service.lock(sessionInfo, operation.getNodeId(), operation.isDeep(), operation.isSessionScoped());
+            LockInfo lInfo = service.lock(sessionInfo, operation.getNodeId(), operation.isDeep(), operation.isSessionScoped(), operation.getTimeoutHint(), operation.getOwnerHint());
             operation.setLockInfo(lInfo);
         }
 

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/DefaultLockManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/DefaultLockManager.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/DefaultLockManager.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/DefaultLockManager.java Fri Mar 13 13:37:44 2009
@@ -36,6 +36,10 @@
         throw new UnsupportedRepositoryOperationException("Locking ist not supported by this repository.");
     }
 
+    public Lock lock(NodeState nodeState, boolean isDeep, boolean isSessionScoped, long timeoutHint, String ownerHint) throws LockException, RepositoryException {
+        throw new UnsupportedRepositoryOperationException("Locking ist not supported by this repository.");
+    }
+
     public void unlock(NodeState nodeState) throws LockException, RepositoryException {
         throw new UnsupportedRepositoryOperationException("Locking ist not supported by this repository.");
     }

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManager.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManager.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManager.java Fri Mar 13 13:37:44 2009
@@ -44,6 +44,24 @@
         throws LockException, RepositoryException;
 
     /**
+     * Lock a node. Checks whether the node is not locked and then
+     * returns a lock object for this node.
+     *
+     * @param nodeState
+     * @param isDeep whether the lock applies to this node only
+     * @param isSessionScoped whether the lock is session scoped
+     * @param timeoutHint optional timeout hint.
+     * @param ownerHint optional String defining the lock owner info to be
+     * displayed.
+     * @return lock object
+     * @throws LockException if this node already is locked, or some descendant
+     *         node is locked and <code>isDeep</code> is <code>true</code>
+     * @see javax.jcr.Node#lock
+     */
+    Lock lock(NodeState nodeState, boolean isDeep, boolean isSessionScoped, long timeoutHint, String ownerHint)
+        throws LockException, RepositoryException;
+
+    /**
      * Removes the lock on a node.
      *
      * @param nodeState
@@ -74,6 +92,7 @@
      * @return <code>true</code> if this node is locked either as a result
      * of a lock held by this node or by a deep lock on a node above this
      * node; otherwise returns <code>false</code>
+     * @throws RepositoryException If an error occurs.
      * @see javax.jcr.Node#isLocked
      */
     boolean isLocked(NodeState nodeState) throws RepositoryException;
@@ -93,7 +112,8 @@
 
     /**
      *
-     * @return
+     * @return The lock tokens associated with the <code>Session</code> this
+     * lock manager has been created for.
      */
     public String[] getLockTokens();
 

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManagerImpl.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManagerImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/lock/LockManagerImpl.java Fri Mar 13 13:37:44 2009
@@ -19,6 +19,7 @@
 import org.apache.jackrabbit.jcr2spi.ItemManager;
 import org.apache.jackrabbit.jcr2spi.SessionListener;
 import org.apache.jackrabbit.jcr2spi.WorkspaceManager;
+import org.apache.jackrabbit.jcr2spi.NodeImpl;
 import org.apache.jackrabbit.jcr2spi.config.CacheBehaviour;
 import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
 import org.apache.jackrabbit.jcr2spi.operation.LockOperation;
@@ -33,6 +34,7 @@
 import org.apache.jackrabbit.spi.LockInfo;
 import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
+import org.apache.jackrabbit.spi.commons.conversion.PathResolver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -46,15 +48,19 @@
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Date;
 
 /**
  * <code>LockManagerImpl</code>...
  * TODO: TOBEFIXED. Lock objects obtained through this mgr are not informed if another session is or becomes lock-holder and removes the lock again.
  */
-public class LockManagerImpl implements LockManager, SessionListener {
+public class LockManagerImpl implements LockManager, org.apache.jackrabbit.api.jsr283.lock.LockManager, SessionListener {
 
     private static Logger log = LoggerFactory.getLogger(LockManagerImpl.class);
 
+    private static final long TIMEOUT_EXPIRED = -1;
+    private static final long TIMEOUT_INFINITE = Long.MAX_VALUE;
+
     /**
      * WorkspaceManager used to apply and release locks as well as to retrieve
      * Lock information for a given NodeState.
@@ -63,6 +69,7 @@
     private final WorkspaceManager wspManager;
     private final ItemManager itemManager;
     private final CacheBehaviour cacheBehaviour;
+    private final PathResolver resolver;
 
     /**
      * Map holding all locks that where created by this <code>Session</code> upon
@@ -74,19 +81,69 @@
     private final Map lockMap;
 
     public LockManagerImpl(WorkspaceManager wspManager, ItemManager itemManager,
-                           CacheBehaviour cacheBehaviour) {
+                           CacheBehaviour cacheBehaviour, PathResolver pathResolver) {
         this.wspManager = wspManager;
         this.itemManager = itemManager;
         this.cacheBehaviour = cacheBehaviour;
+        this.resolver = pathResolver;
         // use hard references in order to make sure, that entries refering
         // to locks created by the current session are not removed.
         lockMap = new HashMap();
     }
 
+    //--------------------------------------------------------< LockManager >---
+    /**
+     * @see org.apache.jackrabbit.api.jsr283.lock.LockManager#getLock(String)
+     */
+    public org.apache.jackrabbit.api.jsr283.lock.Lock getLock(String absPath) throws LockException, RepositoryException {
+        Node n = itemManager.getNode(resolver.getQPath(absPath));
+        return (org.apache.jackrabbit.api.jsr283.lock.Lock) n.getLock();
+    }
+
+    /**
+     * @see org.apache.jackrabbit.api.jsr283.lock.LockManager#isLocked(String)
+     */
+    public boolean isLocked(String absPath) throws RepositoryException {
+        Node n = itemManager.getNode(resolver.getQPath(absPath));
+        return n.isLocked();
+    }
+
+    /**
+     * @see org.apache.jackrabbit.api.jsr283.lock.LockManager#holdsLock(String)
+     */
+    public boolean holdsLock(String absPath) throws RepositoryException {
+        Node n = itemManager.getNode(resolver.getQPath(absPath));
+        return n.holdsLock();
+    }
+
+    /**
+     * @see org.apache.jackrabbit.api.jsr283.lock.LockManager#lock(String, boolean, boolean, long, String)
+     */
+    public org.apache.jackrabbit.api.jsr283.lock.Lock lock(String absPath, boolean isDeep, boolean isSessionScoped, long timeoutHint, String ownerInfo) throws RepositoryException {
+        Node n = itemManager.getNode(resolver.getQPath(absPath));
+        return (org.apache.jackrabbit.api.jsr283.lock.Lock) ((NodeImpl) n).lock(isDeep, isSessionScoped, timeoutHint, ownerInfo);
+    }
+
+    /**
+     * @see org.apache.jackrabbit.api.jsr283.lock.LockManager#unlock(String) 
+     */
+    public void unlock(String absPath) throws LockException, RepositoryException {
+        Node n = itemManager.getNode(resolver.getQPath(absPath));
+        n.unlock();
+    }
+
+    //---------------------< org.apache.jackrabbit.jcr2spi.lock.LockManager >---
     /**
      * @see LockManager#lock(NodeState,boolean,boolean)
      */
     public Lock lock(NodeState nodeState, boolean isDeep, boolean isSessionScoped) throws LockException, RepositoryException {
+        return lock(nodeState, isDeep, isSessionScoped, Long.MAX_VALUE, null);
+    }
+
+    /**
+     * @see LockManager#lock(NodeState,boolean,boolean,long,String)
+     */
+    public Lock lock(NodeState nodeState, boolean isDeep, boolean isSessionScoped, long timeoutHint, String ownerHint) throws RepositoryException {
         // retrieve node first
         Node lhNode;
         // NOTE: Node must be retrieved from the given NodeState and not from
@@ -99,7 +156,7 @@
         }
 
         // execute the operation
-        LockOperation op = LockOperation.create(nodeState, isDeep, isSessionScoped);
+        LockOperation op = LockOperation.create(nodeState, isDeep, isSessionScoped, timeoutHint, ownerHint);
         wspManager.execute(op);
 
         Lock lock = new LockImpl(new LockState(nodeState, op.getLockInfo()), lhNode);
@@ -169,12 +226,13 @@
         }
 
         LockImpl l = getLockImpl(nodeState, true);
-        if (l != null && l.getLockToken() == null) {
+        if (l != null && !l.isLockOwningSession()) {
             // lock is present and token is null -> session is not lock-holder.
             throw new LockException("Node with id '" + nodeState + "' is locked.");
         } // else: state is not locked at all || session is lock-holder
     }
 
+    //--------< LockManager, org.apache.jackrabbit.jcr2spi.lock.LockManager >---
     /**
      * Returns the lock tokens present on the <code>SessionInfo</code> this
      * manager has been created with.
@@ -245,7 +303,7 @@
         for (int i = 0; i < lhStates.length; i++) {
             NodeState nState = lhStates[i];
             LockImpl l = (LockImpl) lockMap.get(nState);
-            if (l.isSessionScoped() && l.getLockToken() != null) {
+            if (l.isSessionScoped() && l.isLockOwningSession()) {
                 try {
                     unlock(nState);
                 } catch (RepositoryException e) {
@@ -325,7 +383,7 @@
         } else {
             NodeEntry lockedEntry = wspManager.getHierarchyManager().getNodeEntry(lockNodeId);
             try {
-                lockHoldingState = ((NodeEntry) lockedEntry).getNodeState();
+                lockHoldingState = lockedEntry.getNodeState();
             } catch (RepositoryException e) {
                 log.warn("Cannot build LockState");
                 throw new RepositoryException("Cannot build LockState", e);
@@ -382,7 +440,7 @@
                 lState = buildLockState(lockHoldingState);
             }
         } else {
-            // need correct information about lock status -> retrieve lockInfo
+            // need precise information about lock status -> retrieve lockInfo
             // from the persistent layer.
             lState = buildLockState(nState);
         }
@@ -393,7 +451,7 @@
             // may fail if the session does not have permission to see this node.
             LockImpl lock = getLockFromMap(lState.lockHoldingState);
             if (lock != null) {
-                lock.lockState.lockInfo = lState.lockInfo;
+                lock.lockState.setLockInfo(lState.lockInfo);
             } else {
                 Item lockHoldingNode = itemManager.getItem(lState.lockHoldingState.getHierarchyEntry());
                 lock = new LockImpl(lState, (Node)lockHoldingNode);
@@ -459,10 +517,11 @@
 
         private LockInfo lockInfo;
         private boolean isLive = true;
+        private long expiration = TIMEOUT_INFINITE;
 
         private LockState(NodeState lockHoldingState, LockInfo lockInfo) {
             this.lockHoldingState = lockHoldingState;
-            this.lockInfo = lockInfo;
+            setLockInfo(lockInfo);
         }
 
         private void refresh() throws RepositoryException {
@@ -507,6 +566,52 @@
             }
         }
 
+        private void setLockInfo(LockInfo lockInfo) {
+            this.lockInfo = lockInfo;
+            long seconds = lockInfo.getSecondsRemaining();
+            if (seconds <= TIMEOUT_EXPIRED) {
+                expiration = TIMEOUT_EXPIRED;
+                isLive = false;
+            } else if (seconds < TIMEOUT_INFINITE) {
+                // calculate timeout
+                expiration = new Date().getTime()/1000 + lockInfo.getSecondsRemaining();
+            } else {
+                expiration = TIMEOUT_INFINITE;
+            }
+        }
+
+        /**
+         * @return <code>true</code> if the lock is still alive.
+         */
+        private boolean isLive() {
+            if (isLive) {
+                isLive = getSecondsRemaining() > 0;
+            }
+            return isLive;
+        }
+
+        /**
+         * @return the number of seconds until the lock's timeout is reached,
+         * {@link Long#MAX_VALUE} if timeout is infinite or undefined and
+         * a negative value if timeout has already been reached or the lock
+         * has been otherwise released.
+         */
+        private long getSecondsRemaining() {
+            if (!isLive) {
+                return TIMEOUT_EXPIRED;
+            } else if (expiration == TIMEOUT_INFINITE) {
+                return expiration;
+            } else {
+                long seconds = expiration - new Date().getTime()/1000;
+                if (seconds <= 0) {
+                    isLive = false;
+                    return TIMEOUT_EXPIRED;
+                } else {
+                    return seconds;
+                }
+            }
+        }
+
         /**
          * Release this lock by removing from the lock map and unregistering
          * it from event listening
@@ -524,9 +629,9 @@
          * unlocking, it is released an its status is reset accordingly.
          */
         private void unlocked() {
-            if (isLive) {
-                isLive = false;
+            if (isLive()) {
                 release();
+                isLive = false;
             }
         }
 
@@ -573,7 +678,7 @@
          * @see ItemStateLifeCycleListener#statusChanged(ItemState, int)
          */
         public void statusChanged(ItemState state, int previousStatus) {
-            if (!isLive) {
+            if (!isLive()) {
                 // since we only monitor the removal of the lock (by means
                 // of deletion of the jcr:lockIsDeep property, we are not interested
                 // if the lock is not active any more.
@@ -597,7 +702,7 @@
     /**
      * Inner class implementing the {@link Lock} interface.
      */
-    private class LockImpl implements Lock, LockTokenListener {
+    private class LockImpl implements org.apache.jackrabbit.api.jsr283.lock.Lock, LockTokenListener {
 
         private final LockState lockState;
         private final Node node;
@@ -618,7 +723,7 @@
             if (cacheBehaviour == CacheBehaviour.OBSERVATION) {
                 lockMap.put(lockState.lockHoldingState, this);
                 lockState.startListening();
-            } else if (isHoldBySession()) {
+            } else if (lockState.lockInfo.isLockOwner()) {
                 lockMap.put(lockState.lockHoldingState, this);
                 lockState.startListening();
                 // open-scoped locks: the map entry and the lock information
@@ -658,6 +763,12 @@
          * @see Lock#getLockToken()
          */
         public String getLockToken() {
+            // shortcut for jsr 283 session scoped locks: they never expose
+            // the lock token to the API users.
+            if (isSessionScoped()) {
+                return null;
+            }
+
             updateLockInfo();
             return getLockInfo().getLockToken();
         }
@@ -667,7 +778,7 @@
          */
         public boolean isLive() throws RepositoryException {
             updateLockInfo();
-            return lockState.isLive;
+            return lockState.isLive();
         }
 
         /**
@@ -685,7 +796,7 @@
                 throw new LockException("Lock is not alive any more.");
             }
 
-            if (getLockToken() == null) {
+            if (!isLockOwningSession()) {
                 // shortcut, since lock is always updated if the session became
                 // lock-holder of a foreign lock.
                 throw new LockException("Session does not hold lock.");
@@ -694,6 +805,21 @@
             }
         }
 
+        /**
+         * @see org.apache.jackrabbit.api.jsr283.lock.Lock#getSecondsRemaining()
+         */
+        public long getSecondsRemaining() throws RepositoryException {
+            updateLockInfo();
+            return lockState.getSecondsRemaining();
+        }
+
+        /**
+         * @see org.apache.jackrabbit.api.jsr283.lock.Lock#isLockOwningSession()
+         */
+        public boolean isLockOwningSession(){
+            return lockState.lockInfo.isLockOwner();
+        }
+
         //----------------------------------------------< LockTokenListener >---
         /**
          * A lock token as been added to the current Session. If this Lock
@@ -706,8 +832,10 @@
          * @see LockTokenListener#lockTokenAdded(String)
          */
         public void lockTokenAdded(String lockToken) throws RepositoryException {
-            if (getLockToken() == null) {
-                // could be that this affects this lock and session became
+            if (!isSessionScoped() && !isLockOwningSession()) {
+                // unless this lock is session-scoped (token is never transfered)
+                // and the session isn't the owner yet (token already present),
+                // it could be that this affects this lock and session became
                 // lock holder -> releoad info to assert.
                 lockState.reloadLockInfo();
             }
@@ -721,7 +849,8 @@
          */
         public void lockTokenRemoved(String lockToken) throws RepositoryException {
             // reload lock info, if session gave away its lock-holder status
-            // for this lock.
+            // for this lock. this will never be true for session-scoped locks
+            // that are not exposed (thus cannot be removed).
             if (lockToken.equals(getLockToken())) {
                 lockState.reloadLockInfo();
             }
@@ -749,12 +878,6 @@
                 }
             } // else: nothing to do.
         }
-        /**
-         * @return true if this lock is hold by this session. false otherwise.
-         */
-        private boolean isHoldBySession() {
-            return lockState.lockInfo.getLockToken() != null;
-        }
     }
 
     //--------------------------------------------------< LockTokenListener >---

Modified: jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockOperation.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockOperation.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/LockOperation.java Fri Mar 13 13:37:44 2009
@@ -36,13 +36,18 @@
     private final NodeState nodeState;
     private final boolean isDeep;
     private final boolean isSessionScoped;
+    private final long timeoutHint;
+    private final String ownerHint;
 
     private LockInfo lockInfo = null;
 
-    private LockOperation(NodeState nodeState, boolean isDeep, boolean isSessionScoped) {
+    private LockOperation(NodeState nodeState, boolean isDeep, boolean isSessionScoped,
+                          long timeoutHint, String ownerHint) {
         this.nodeState = nodeState;
         this.isDeep = isDeep;
         this.isSessionScoped = isSessionScoped;
+        this.timeoutHint = timeoutHint;
+        this.ownerHint = ownerHint;
 
         // NOTE: affected-states only needed for transient modifications
     }
@@ -81,6 +86,14 @@
         return isSessionScoped;
     }
 
+    public long getTimeoutHint() {
+        return timeoutHint;
+    }
+
+    public String getOwnerHint() {
+        return ownerHint;
+    }
+
     public void setLockInfo(LockInfo lockInfo) {
         if (lockInfo == null) {
             throw new IllegalArgumentException("IdIterator must not be null.");
@@ -105,7 +118,11 @@
      * @return
      */
     public static LockOperation create(NodeState nodeState, boolean isDeep, boolean isSessionScoped) {
-        LockOperation lck = new LockOperation(nodeState, isDeep, isSessionScoped);
+        return create(nodeState, isDeep, isSessionScoped, Long.MAX_VALUE, null);
+    }
+
+    public static LockOperation create(NodeState nodeState, boolean isDeep, boolean isSessionScoped, long timeoutHint, String ownerHint) {
+        LockOperation lck = new LockOperation(nodeState, isDeep, isSessionScoped, timeoutHint, ownerHint);
         return lck;
     }
 }
\ No newline at end of file

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=753244&r1=753243&r2=753244&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 Mar 13 13:37:44 2009
@@ -229,6 +229,7 @@
             assertTrue("Child node locked after save", childNode.isLocked());
 
         } finally {
+            session.refresh(false);
             childNode.unlock();
         }
     }
@@ -363,4 +364,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/LockInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/LockInfoImpl.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/LockInfoImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/LockInfoImpl.java Fri Mar 13 13:37:44 2009
@@ -48,6 +48,16 @@
     private final boolean isSessionScoped;
 
     /**
+     * Number of seconds until the lock time outs.
+     */
+    private final long secondsRemaining;
+
+    /**
+     * Flag indicating if the session is lock owner or not.
+     */
+    private final boolean isLockOwner;
+
+    /**
      * The <code>NodeId</code> of the locked node.
      */
     private final NodeId nodeId;
@@ -63,10 +73,31 @@
      */
     public LockInfoImpl(String lockToken, String lockOwner, boolean isDeep,
                         boolean isSessionScoped, NodeId nodeId) {
+        this(lockToken, lockOwner, isDeep, isSessionScoped, Long.MAX_VALUE, lockToken != null, nodeId);
+    }
+
+    /**
+     * Creates a new lock info for the given <code>lock</code> info.
+     *
+     * @param lockToken the lock token
+     * @param lockOwner the lock owner
+     * @param isDeep whether this lock is deep or not
+     * @param isSessionScoped whether this lock is session scoped or not
+     * @param secondsRemaining Number of seconds until the lock timeout is reached.
+     * @param isLockOwner <code>true</code> if the calling session is lock
+     * owner; <code>false</code> otherwise.
+     * @param nodeId the node id of the locked node.
+     * @since JCR 2.0
+     */
+    public LockInfoImpl(String lockToken, String lockOwner, boolean isDeep,
+                        boolean isSessionScoped, long secondsRemaining,
+                        boolean isLockOwner, NodeId nodeId) {
         this.lockToken = lockToken;
         this.lockOwner = lockOwner;
         this.isDeep = isDeep;
         this.isSessionScoped = isSessionScoped;
+        this.secondsRemaining = secondsRemaining;
+        this.isLockOwner = isLockOwner;
         this.nodeId = nodeId;
     }
 
@@ -101,7 +132,21 @@
     /**
      * {@inheritDoc}
      */
+    public long getSecondsRemaining() {
+        return secondsRemaining;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isLockOwner() {
+        return isLockOwner;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public NodeId getNodeId() {
         return nodeId;
     }
-}
+}
\ No newline at end of file

Modified: jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/LockInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/LockInfo.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/LockInfo.java (original)
+++ jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/LockInfo.java Fri Mar 13 13:37:44 2009
@@ -26,8 +26,8 @@
 public interface LockInfo {
 
     /**
-     * Returns the lock token for this lock if it is hold by the requesting
-     * session or <code>null</code> otherwise.
+     * Returns the lock token for this lock or <code>null</code> if the token
+     * should not be exposed to the API user.
      *
      * @return lock token or <code>null</code>
      * @see javax.jcr.lock.Lock#getLockToken()
@@ -35,7 +35,8 @@
     public String getLockToken();
 
     /**
-     * Returns the user ID of the user who owns this lock.
+     * Returns the user ID of the user who owns this lock or some user defined
+     * information about the lock owner.
      *
      * @return user ID of the user who owns this lock.
      * @see javax.jcr.lock.Lock#getLockOwner()
@@ -57,6 +58,28 @@
      * @see javax.jcr.lock.Lock#isSessionScoped()
      */
     public boolean isSessionScoped();
+ 
+    /**
+     * Returns the seconds remaining until the lock times out or
+     * ({@link Long#MAX_VALUE} if the timeout is unknown or infinite).
+     *
+     * @return number of seconds until the lock times out.
+     * @see javax.jcr.lock.Lock#getSecondsRemaining()
+     * @since JCR 2.0
+     */
+    public long getSecondsRemaining();
+
+    /**
+     * Returns <code>true</code> if the <code>SessionInfo</code> used to
+     * retrieve this <code>LockInfo</code> is the lock holder and thus enabled
+     * to refresh or release the lock.
+     *
+     * @return <code>true</code> if the <code>SessionInfo</code> used to
+     * retrieve this <code>LockInfo</code> is the lock holder.
+     * @see javax.jcr.lock.Lock#isLockOwningSession()
+     * @since JCR 2.0
+     */
+    public boolean isLockOwner();
 
     /**
      * Returns the <code>NodeId</code> of the lock-holding Node.

Modified: jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java (original)
+++ jackrabbit/trunk/jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java Fri Mar 13 13:37:44 2009
@@ -511,6 +511,30 @@
     public LockInfo lock(SessionInfo sessionInfo, NodeId nodeId, boolean deep, boolean sessionScoped) throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, RepositoryException;
 
     /**
+     * Create a lock on the <code>Node</code> identified by the given id.
+     *
+     * @param sessionInfo
+     * @param nodeId
+     * @param deep
+     * @param sessionScoped
+     * @param timeoutHint long indicating the desired lock timeout in seconds.
+     * The implementation is free to ignore the hint.
+     * @param ownerHint String indicating the desired lockOwner info. The
+     * implementation is free to ignore the hint.
+     * @return The <code>LockInfo</code> associated with the new lock
+     * that has been created.
+     * @throws javax.jcr.UnsupportedRepositoryOperationException If this SPI
+     * implementation does not support locking at all.
+     * @throws javax.jcr.lock.LockException If the Node identified by the given
+     * id cannot be locked due to an existing lock or due to missing mixin type.
+     * @throws javax.jcr.AccessDeniedException
+     * @throws javax.jcr.RepositoryException If another error occurs.
+     * @see javax.jcr.lock.LockManager#lock(String, boolean, boolean, long, String)
+     * @since JCR 2.0
+     */
+    public LockInfo lock(SessionInfo sessionInfo, NodeId nodeId, boolean deep, boolean sessionScoped, long timeoutHint, String ownerHint) throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, RepositoryException;
+
+    /**
      * Explicit refresh of an existing lock. Existing locks should be refreshed
      * implicitely with all read and write methods listed here.
      *

Modified: jackrabbit/trunk/jackrabbit-spi2jcr/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2jcr/pom.xml?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi2jcr/pom.xml (original)
+++ jackrabbit/trunk/jackrabbit-spi2jcr/pom.xml Fri Mar 13 13:37:44 2009
@@ -116,6 +116,13 @@
       <artifactId>jackrabbit-jcr-commons</artifactId>
       <version>1.6-SNAPSHOT</version>
     </dependency>
+    <!-- tmp dependency to jackrabbit-api until jsr 283 is released -->
+    <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>jackrabbit-api</artifactId>
+      <version>1.6-SNAPSHOT</version>
+    </dependency>
+    <!-- end of tmp dependency -->
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>

Modified: jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/LockInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/LockInfoImpl.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/LockInfoImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/LockInfoImpl.java Fri Mar 13 13:37:44 2009
@@ -17,6 +17,7 @@
 package org.apache.jackrabbit.spi2jcr;
 
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
+import org.apache.jackrabbit.spi.LockInfo;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.lock.Lock;
@@ -28,21 +29,49 @@
 class LockInfoImpl extends org.apache.jackrabbit.spi.commons.LockInfoImpl {
 
     /**
-     * Creates a new lock info for the given locked <code>node</code>.
+     * Creates a new lock info for the given JCR lock object.
      *
-     * @param lock       the lock.
-     * @param idFactory  the id factory.
-     * @param resolver
-     * @throws RepositoryException if an error occurs while reading from
-     *                             <code>node</code> or if <code>node</code> is
-     *                             not locked.
+     * @param lock the lock.
+     * @param idFactory the id factory.
+     * @param resolver the name and path resolver.
+     * @throws RepositoryException if an error occurs while the node from the
+     * given lock or while creating the node id.
      */
-    public LockInfoImpl(Lock lock,
-                        IdFactoryImpl idFactory,
-                        NamePathResolver resolver)
-            throws RepositoryException {
+    private LockInfoImpl(Lock lock, IdFactoryImpl idFactory,
+                         NamePathResolver resolver) throws RepositoryException {
         super(lock.getLockToken(), lock.getLockOwner(),
                 lock.isDeep(), lock.isSessionScoped(),
                 idFactory.createNodeId(lock.getNode(), resolver));
     }
-}
+
+    /**
+     * Creates a new lock info for the given JCR lock object.
+     * 
+     * @param lock the JCR lock.
+     * @param idFactory the id factory.
+     * @param resolver the name and path resolver.
+     * @throws RepositoryException If an error occurs while creating the info.
+     * @since JCR 2.0
+     */
+    private LockInfoImpl(org.apache.jackrabbit.api.jsr283.lock.Lock lock,
+                         IdFactoryImpl idFactory, NamePathResolver resolver) throws RepositoryException {
+        super(lock.getLockToken(), lock.getLockOwner(), lock.isDeep(), lock.isSessionScoped(), lock.getSecondsRemaining(), lock.isLockOwningSession(), idFactory.createNodeId(lock.getNode(), resolver));
+    }
+
+    /**
+     * Create a new <code>LockInfo</code> from the given parameters.
+     * 
+     * @param lock the JCR lock.
+     * @param idFactory the id factory.
+     * @param resolver the name and path resolver.
+     * @return a new <code>LockInfo</code>
+     * @throws RepositoryException If an error occurs while creating the info.
+     */
+    public static LockInfo createLockInfo(Lock lock, IdFactoryImpl idFactory, NamePathResolver resolver) throws RepositoryException {
+        if (lock instanceof org.apache.jackrabbit.api.jsr283.lock.Lock) {
+            return new LockInfoImpl((org.apache.jackrabbit.api.jsr283.lock.Lock) lock, idFactory, resolver);
+        } else {
+            return new LockInfoImpl(lock, idFactory, resolver);
+        }
+    }
+}
\ No newline at end of file

Modified: jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/RepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/RepositoryServiceImpl.java?rev=753244&r1=753243&r2=753244&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/RepositoryServiceImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/RepositoryServiceImpl.java Fri Mar 13 13:37:44 2009
@@ -545,7 +545,7 @@
         SessionInfoImpl sInfo = getSessionInfoImpl(sessionInfo);
         try {
             Lock lock = getNode(nodeId, sInfo).getLock();
-            return new LockInfoImpl(lock, idFactory, sInfo.getNamePathResolver());
+            return LockInfoImpl.createLockInfo(lock, idFactory, sInfo.getNamePathResolver());
         } catch (LockException e) {
             // no lock present on this node.
             return null;
@@ -565,7 +565,28 @@
             public Object run() throws RepositoryException {
                 Node n = getNode(nodeId, sInfo);
                 Lock lock = n.lock(deep, sessionScoped);
-                return new LockInfoImpl(lock, idFactory, sInfo.getNamePathResolver());
+                return LockInfoImpl.createLockInfo(lock, idFactory, sInfo.getNamePathResolver());
+            }
+        }, sInfo);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public LockInfo lock(SessionInfo sessionInfo, final NodeId nodeId, final boolean deep, final boolean sessionScoped, final long timeoutHint, final String ownerHint) throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, RepositoryException {
+        final SessionInfoImpl sInfo = getSessionInfoImpl(sessionInfo);
+        return (LockInfo) executeWithLocalEvents(new Callable() {
+            public Object run() throws RepositoryException {
+                Node n = getNode(nodeId, sInfo);
+                Lock lock;
+                // TODO: remove check once jsr283 is released
+                if (sInfo.getSession() instanceof org.apache.jackrabbit.api.jsr283.Session) {
+                    org.apache.jackrabbit.api.jsr283.lock.LockManager lMgr = (((org.apache.jackrabbit.api.jsr283.Workspace) sInfo.getSession().getWorkspace()).getLockManager());
+                    lock = lMgr.lock(n.getPath(), deep, sessionScoped, timeoutHint, ownerHint);
+                } else {
+                    lock = n.lock(deep, sessionScoped);
+                }
+                return LockInfoImpl.createLockInfo(lock, idFactory, sInfo.getNamePathResolver());
             }
         }, sInfo);
     }



Mime
View raw message