Hello Stefan, how will your proposal work with long-lived (a.k.a. not session-scoped) tokens?
A common scenario in web applications is that the client issuing the lock request is not always able to save (cache, keep, whatever one wants to call it) the lock tokens, and thus would not be able to pass the token around like you suggest (it's not uncommon that a user closes the web browser tab or window that had the client application running onto, and away goes the lock tokens that client could have saved...). It's common for the web application backend to maintain a pool of JCR sessions, thus you cannot guarantee that you'll have access to the session that locked the item (thus the lock token is 'lost' somehow...) Hope to have been clear :-) On Fri, May 13, 2011 at 9:24 AM, Stefan Guggisberg <[email protected]> wrote: > 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 >> >> >> > -- Fabián Mandelbaum IS Engineer
