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 WorkspaceImpl ...
*/
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 Workspace with the specified
* name. 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 Session and its
* Workspace.
*
- * @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 true if the token was successfully added to the set.
*/
boolean lockTokenAdded(String lockToken) {
synchronized (lockTokens) {
@@ -201,7 +201,7 @@
/**
*
* @param lockToken
- * @return
+ * @return true 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;
+
+/**
+ * WorkspaceTest...
+ */
+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 null 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 ActiveLock object with type '{@link Type#WRITE write}'
@@ -47,21 +44,10 @@
* @param lock
*/
public JcrActiveLock(Lock lock) {
- this (lock, lock.isSessionScoped());
- }
-
- /**
- * Create a new ActiveLock 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.").
+ *
LockManager 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 isDeep is true
+ * @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 true 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 false
+ * @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 Session 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;
/**
* LockManagerImpl...
* 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 Session 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 SessionInfo 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 true 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 NodeId 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 lock 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 true if the calling session is lock
+ * owner; false 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 null otherwise.
+ * Returns the lock token for this lock or null if the token
+ * should not be exposed to the API user.
*
* @return lock token or null
* @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 true if the SessionInfo used to
+ * retrieve this LockInfo is the lock holder and thus enabled
+ * to refresh or release the lock.
+ *
+ * @return true if the SessionInfo used to
+ * retrieve this LockInfo is the lock holder.
+ * @see javax.jcr.lock.Lock#isLockOwningSession()
+ * @since JCR 2.0
+ */
+ public boolean isLockOwner();
/**
* Returns the NodeId 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 Node 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 LockInfo 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 @@
node.
+ * 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
- * node or if node 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 LockInfo from the given parameters.
+ *
+ * @param lock the JCR lock.
+ * @param idFactory the id factory.
+ * @param resolver the name and path resolver.
+ * @return a new LockInfo
+ * @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);
}