On Fri, May 13, 2011 at 8:43 AM, Kamil Nezval <[email protected]> wrote:
> Hi,
>
> I'm trying to implement a "stealing" of a node's lock - one user will be
> able to unlock the nodes locked by other users.
i prefer the term "transferring lock ownership"...
> According to the JCR 2.0
> specification it should be possible to assign a lock to a current session
> using LockManager.addLockToken() method:
>
> "If the implementation does not support simultaneous lock ownership this
> method will
> transfer ownership of the lock corresponding to the specified lockToken to
> the
> current session, otherwise the current session will become an additional
> owner of
> that lock."
>
> So I've tried something like this:
>
> String nodePath = node.getPath();
> LockManager lockManager = jcrSession.getWorkspace().getLockManager();
> Lock nodeLock = lockManager.getLock(nodePath);
> String lockToken = nodeLock.getLockToken();
> lockManager.addLockToken(lockToken);
> lockManager.unlock(nodePath);
> lockManager.lock(nodePath, false, false, 1000, jcrSession.getUserID());
>
> But it doesn't work ("Cannot add lock token: lock already held by other
> session." exception). I've looked into a source code and it looks like the
> implementation doesn't follow the specification at all,
the implementation is spec-compliant. the javadoc [1] clearly states
that a LockException is thrown
"if the specified lock token is already held by another Session and
the implementation does not support simultaneous ownership of
open-scoped locks."
before adding the token to the new session you have to remove the token
from the other session.
cheers
stefan
[1]
http://www.day.com/maven/jsr170/javadocs/jcr-2.0/javax/jcr/lock/LockManager.html#addLockToken(java.lang.String)
> see the code bellow
> (LockManagerImpl.java):
>
> public void addLockToken(SessionImpl session, String lt) throws
> LockException, RepositoryException {
> try {
> NodeId id = LockInfo.parseLockToken(lt);
>
> NodeImpl node = (NodeImpl)
> sysSession.getItemManager().getItem(id);
> Path path = node.getPrimaryPath();
> PathMap.Element<LockInfo> element = lockMap.map(path, true);
> if (element != null) {
> LockInfo info = element.get();
> if (info != null) {
> if (info.isLockHolder(session)) {
> // nothing to do
> } else if (info.getLockHolder() == null) {
> info.setLockHolder(session);
> if (info instanceof InternalLockInfo) {
> session.addListener((InternalLockInfo) info);
> }
> } else {
> String msg = "Cannot add lock token: lock already
> held by other session.";
> log.warn(msg);
> info.throwLockException(msg, session);
> }
> }
> }
> // inform SessionLockManager
> getSessionLockManager(session).lockTokenAdded(lt);
> } catch (IllegalArgumentException e) {
> String msg = "Bad lock token: " + e.getMessage();
> log.warn(msg);
> throw new LockException(msg);
> }
> }
>
> And it is also not possible to get a lock token if the current user is not
> the lock holder (LockImpl.java):
>
> public String getLockToken() {
> if (!info.isSessionScoped() && info.isLockHolder(node.getSession()))
> {
> return info.getLockToken();
> } else {
> return null;
> }
> }
>
> So my question is whether it is somehow possible to implement a
> "lock-stealing" as described above.
>
> Thanks in advance.
>
> Regards
>
> Kamil
>
>
>