jackrabbit-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Kamil Nezval" <kamil.nez...@xitee.com>
Subject Lock stealing
Date Fri, 13 May 2011 06:43:19 GMT
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. 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, 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



Mime
View raw message