Return-Path: X-Original-To: apmail-jackrabbit-users-archive@minotaur.apache.org Delivered-To: apmail-jackrabbit-users-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 335E548A5 for ; Fri, 13 May 2011 13:14:53 +0000 (UTC) Received: (qmail 24387 invoked by uid 500); 13 May 2011 13:14:52 -0000 Delivered-To: apmail-jackrabbit-users-archive@jackrabbit.apache.org Received: (qmail 24363 invoked by uid 500); 13 May 2011 13:14:52 -0000 Mailing-List: contact users-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: users@jackrabbit.apache.org Delivered-To: mailing list users@jackrabbit.apache.org Received: (qmail 24355 invoked by uid 99); 13 May 2011 13:14:52 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 13 May 2011 13:14:52 +0000 X-ASF-Spam-Status: No, hits=1.3 required=5.0 tests=FREEMAIL_FROM,RCVD_IN_BL_SPAMCOP_NET,RCVD_IN_DNSWL_LOW,RFC_ABUSE_POST,SPF_PASS,T_FRT_BELOW2,T_FRT_STOCK2,T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of stefan.guggisberg@gmail.com designates 209.85.160.42 as permitted sender) Received: from [209.85.160.42] (HELO mail-pw0-f42.google.com) (209.85.160.42) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 13 May 2011 13:14:47 +0000 Received: by pwj3 with SMTP id 3so2097504pwj.1 for ; Fri, 13 May 2011 06:14:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:in-reply-to:references:date :message-id:subject:from:to:content-type:content-transfer-encoding; bh=LoDhge0GVp0sID9DQPQe7dToUBv6g9ZU7yO9vDvwM38=; b=hnOm7LTXMxU/6zDtUUz8tl7GDKKhvAs4Uq4e0Jg3a60dKy6nMmqpH2nohLyrqfTc4O V7e5/VJz1H/5SWm7mkbwfkj+N7XcNO0vFjBRHmOgAlQ8lJWRfwykwXjoy0TAY9Fbzbw7 +j2o7zZdjlhvwbud2/ZJqhTd0a4ssKuXKgLt0= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; b=sq4+dL9FeGaGgKqYpaVnxtsSeBpfLZguPnELBbkfnmLvey3L58kXdVS4L4ltoMVc61 0mZV459Lz7pSmBRnSX1WKMW3qbsgddfGQM6kP6lARb6DFis1JfEjQNM82uLhsJ31GnIe DMDY17UjbxoM8GNIMlgUXH8ZZ08uPGNTDHI+Y= MIME-Version: 1.0 Received: by 10.68.40.170 with SMTP id y10mr2312249pbk.29.1305292467150; Fri, 13 May 2011 06:14:27 -0700 (PDT) Received: by 10.68.47.170 with HTTP; Fri, 13 May 2011 06:14:26 -0700 (PDT) In-Reply-To: References: <7307001820329863934@unknownmsgid> Date: Fri, 13 May 2011 15:14:26 +0200 Message-ID: Subject: Re: Lock stealing From: Stefan Guggisberg To: users@jackrabbit.apache.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable 2011/5/13 Fabi=E1n Mandelbaum : > Hello Stefan, > > how will your proposal work with long-lived (a.k.a. not session-scoped) t= okens? > > 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 :-) absolutely ;) if you need to be able to 'break' somebody else's lock you could e.g. override the following method: o.a.jackrabbit.core..lock.checkUnlock(LockInfo info, Session session) that way you can implement some sort of lock administrator session which is able to unlock any open-scoped lock. note that you'd have to subclass RepositoryImpl as well. cheers stefan > > On Fri, May 13, 2011 at 9:24 AM, Stefan Guggisberg > wrote: >> On Fri, May 13, 2011 at 8:43 AM, Kamil Nezval w= rote: >>> Hi, >>> >>> I'm trying to implement a "stealing" of a node's lock - one user will b= e >>> 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 sessi= on >>> using LockManager.addLockToken() method: >>> >>> "If the implementation does not support simultaneous lock ownership thi= s >>> method will >>> transfer ownership of the lock corresponding to the specified lockToken= to >>> the >>> current session, otherwise the current session will become an additiona= l >>> owner of >>> that lock." >>> >>> So I've tried something like this: >>> >>> String nodePath =3D node.getPath(); >>> LockManager lockManager =3D jcrSession.getWorkspace().getLockManager(); >>> Lock nodeLock =3D lockManager.getLock(nodePath); >>> String lockToken =3D 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/Lock= Manager.html#addLockToken(java.lang.String) >> >>> see the code bellow >>> (LockManagerImpl.java): >>> >>> =A0 =A0 =A0 =A0public void addLockToken(SessionImpl session, String lt)= throws >>> LockException, RepositoryException { >>> =A0 =A0 =A0 =A0try { >>> =A0 =A0 =A0 =A0 =A0 =A0NodeId id =3D LockInfo.parseLockToken(lt); >>> >>> =A0 =A0 =A0 =A0 =A0 =A0NodeImpl node =3D (NodeImpl) >>> sysSession.getItemManager().getItem(id); >>> =A0 =A0 =A0 =A0 =A0 =A0Path path =3D node.getPrimaryPath(); >>> =A0 =A0 =A0 =A0 =A0 =A0PathMap.Element element =3D lockMap.ma= p(path, true); >>> =A0 =A0 =A0 =A0 =A0 =A0if (element !=3D null) { >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0LockInfo info =3D element.get(); >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (info !=3D null) { >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (info.isLockHolder(session)) = { >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0// nothing to do >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} else if (info.getLockHolder() = =3D=3D null) { >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0info.setLockHolder(sessi= on); >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (info instanceof Inte= rnalLockInfo) { >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0session.addListe= ner((InternalLockInfo) info); >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} else { >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0String msg =3D "Cannot a= dd lock token: lock already >>> held by other session."; >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0log.warn(msg); >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0info.throwLockException(= msg, session); >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} >>> =A0 =A0 =A0 =A0 =A0 =A0} >>> =A0 =A0 =A0 =A0 =A0 =A0// inform SessionLockManager >>> =A0 =A0 =A0 =A0 =A0 =A0getSessionLockManager(session).lockTokenAdded(lt= ); >>> =A0 =A0 =A0 =A0} catch (IllegalArgumentException e) { >>> =A0 =A0 =A0 =A0 =A0 =A0String msg =3D "Bad lock token: " + e.getMessage= (); >>> =A0 =A0 =A0 =A0 =A0 =A0log.warn(msg); >>> =A0 =A0 =A0 =A0 =A0 =A0throw new LockException(msg); >>> =A0 =A0 =A0 =A0} >>> =A0 =A0} >>> >>> And it is also not possible to get a lock token if the current user is = not >>> the lock holder (LockImpl.java): >>> >>> =A0 =A0public String getLockToken() { >>> =A0 =A0 =A0 =A0if (!info.isSessionScoped() && info.isLockHolder(node.ge= tSession())) >>> { >>> =A0 =A0 =A0 =A0 =A0 =A0return info.getLockToken(); >>> =A0 =A0 =A0 =A0} else { >>> =A0 =A0 =A0 =A0 =A0 =A0return null; >>> =A0 =A0 =A0 =A0} >>> =A0 =A0} >>> >>> So my question is whether it is somehow possible to implement a >>> "lock-stealing" as described above. >>> >>> Thanks in advance. >>> >>> Regards >>> >>> Kamil >>> >>> >>> >> > > > > -- > Fabi=E1n Mandelbaum > IS Engineer >