Ropardo Sowftware development company

Experience software development with ROPARDO S.R.L.

RSS Feed
RSS Feed
  • Home
  • About ROPARDO S.R.L
  • Our websites

Getting the Lock Token for an item in Jackrabbit

I’ve seen this problem around from the first versions of Apache Jackrabbit. The problem is straightforward and just. If you perform a WebDAV Lock command on an item in Jackrabbit the resulting lock token is available only in that command’s session. In other words, if you do not save the lock token that is provided as the result of the WebDAV Lock command then you cannot retrieve it in any way later and the item remains locked.

I’m not sure what the JCR specifications are (probably it is meant do be like this) but there are lots of practical examples where you need to be able to retrieve that token even if you did not save it. Of course, if a different user tries to get it, he/she should not be allowed, but I’m talking about the case when the same user that locks the file, tries to get the lock token.

For example, if you open a file from MS Word through WebDAV. In this case MS Word asks you for your username/password, opens the file and locks it. Upon closing MS Word, it releases that lock. But in the case that it is terminated inappropriately (end task, crash etc) the file remains locked and it would be normal that the same user to be able to use another WebDAV tool (or execute commands “manually”) in order to find that lock token and unlock the file.

All the examples rely on this idea. You lock a file form one application and then you try to unlock it (or refresh the lock) from another app which cannot be supplied with the lock token (that is supposed you saved from the first lock command). In each case we assume that the same user needs this. If it is another then is normal not to be allowed to do it.

There is a solution !
… but it is a bit complicated to implement.

The main problem relies in the org.apache.jackrabbit.core.lock.LockImpl class. Its getLockToken method looks like this:

public String getLockToken() {
if (!info.isSessionScoped() && info.isLockHolder(node.getSession())) {
return info.getLockToken();
} else {
return null;
}
}

It is obvious that the token is provided only if it is in the same session.
That if line is actually wired because it asks that the lock token NOT to be session scoped but its locking session to be the same as the current session (node.getSession() is the current session)

I did not manage to create a session scoped lock until now, the sessionScope attribute is always false no matter what parameters I use in the LockInfo object of the WebDAV LockMethod. Furthermore, by locking an item with MS Word (and I think that any application that know how to handle WebDAV does the same), the sessionScope attribute is always false. So the problem is obvious in that code.

In order to fix this, the code must be modified as follows:
public String getLockToken() {
if(info.isSessionScoped())
return null;
if (info.isLockHolder(node.getSession()) || info.getLockOwner().equals(node.getSession().getUserID())) {
return info.getLockToken();
} else {
return null;
}
}

The first if is to preserve the original behavior about the sessionScope attribute (whatever that may be).
The second if fixes the problem.

The easiest way to replace the code is to take the org.apache.jackrabbit.core.lock.LockImpl.java file from Jackrabbit source distribution, modify it, compile it and replace it into the jar file.

But the problem is still not fixed ! Because there you will get another one now.
If you fix this then the lock token and the lock owner should be present in the lockdiscovery property of an item when
peforming a PropFind command. I started Jackrabbit in debug mode and saw that an ActiveLock object is set as a child node of the lockdiscovery property and should be present on the client side but it is not ! It is null !!

So after wasting a few hours with this I decided modify Jackrabbit to return the lock token and lock owner as separate item properties. So this is what you should do:

You need to overwrite the org.apache.jackrabbit.webdav.server.AbstractWebdavServlet.doPropFind() method:

protected void doPropFind(WebdavRequest request, WebdavResponse response,
DavResource resource) throws IOException, DavException {
if (!resource.exists()) {
response.sendError(DavServletResponse.SC_NOT_FOUND);
return;
}

int depth = request.getDepth(DEPTH_INFINITY);
DavPropertyNameSet requestProperties = request.getPropFindProperties();
int propfindType = request.getPropFindType();
/* Copy from original code above */

/* Hack to set the lock token and owner as separate properties */
ActiveLock aLock = resource.getLock(Type.WRITE, Scope.EXCLUSIVE);

if ((aLock != null) && (aLock.getOwner() != null)) {
properties.add(new DefaultDavProperty("lockowner", aLock.getOwner(), DavConstants.NAMESPACE));
}
if ((aLock != null) && (aLock.getToken() != null)) {
properties.add(new DefaultDavProperty("locktoken", aLock.getToken(), DavConstants.NAMESPACE));
}

/* The rest of the original code */
MultiStatus mstatus = new MultiStatus();
mstatus.addResourceProperties(resource, requestProperties, propfindType, depth);
response.sendMultiStatus(mstatus);
}

The first property is the lock owner which should be visible for any user. You can remove it if you don’t like.
The second property is the lock token. This will be not null only if the PropFind command is issued by the same user that locked the file. See the second code sample. (The modified LockImpl class). So if it is another user then the property is not set.

All you have to do now is put this code into Jackrabbit. How do you actually overwrite the AbstractWebdavServlet class ? Well you actually need to overwrite the org.apache.jackrabbit.j2ee.SimpleWebdavServlet class that you find in the classes folder of Jackrabbit. This is a subclass of AbstractWebdavServlet and is specified in the the Jackrabbit’s web.xml file. So you overwrite this class (SimpleWebdavServlet) and you specify replace it in the web.xml as the servlet class of the WebDAV servlet (look it up in the web.xml and you will find it).

This is all you have to do. Now start Jackrabbit and you will see that you when you execute a PropPatch command your returning item will have 2 new properties that contain the lock token and lock owner (in case you are the same user that performed the lock).
Of course if an item is not locked then these properties will not be present.

And don’t worry about overwriting and replacing that webdav class. It doesn’t modify Jackrabbit behavior in any other way. (Just what is written in this blog).

Live long and prosper !

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
Get Shareaholic
Tags: Jackrabbit Lock command Lock owner Lock token

 Posted in: Java, Software Development
March 31, 2010 | Alexandru Georgescu | No Comments

Leave a Reply

 


  • « Previous post
  • Next post »
  • Recent Posts

    • Installing PyGraphviz on Windows
    • Convert python object to XML representation
    • Liferay Portlet Development
    • Norway Road Show 2011 private meeting invitation
    • Oracle OpenWorld 2011
  • Ropardo is Hiring

  • Subscribe

    • Add to Google Reader or Homepage Add to netvibes TopOfBlogs
  • Recent Comments

    • Rajkumar Pomaji on Bluetooth PC Remote Control
    • Stelian Morariu on GWT 2.1 – Uploading a file using the RPC mechanism
    • Sergio on GWT 2.1 – Uploading a file using the RPC mechanism
    • Artem on Liferay: Deployment will start in a few seconds… and how to realy start
    • rkd80 on GWT 2.1 – Uploading a file using the RPC mechanism
  • Archives

    • November 2011 (1)
    • September 2011 (4)
    • July 2011 (3)
    • June 2011 (2)
    • May 2011 (4)
    • April 2011 (4)
    • March 2011 (3)
    • February 2011 (2)
    • January 2011 (2)
    • December 2010 (1)
    • November 2010 (4)
    • October 2010 (4)
    • August 2010 (3)
    • July 2010 (3)
    • June 2010 (6)
    • May 2010 (8)
    • April 2010 (7)
    • March 2010 (9)
    • February 2010 (6)
    • January 2010 (5)
    • December 2009 (7)
    • November 2009 (9)
    • October 2009 (10)
    • September 2009 (14)
    • August 2009 (10)
    • July 2009 (1)
    • June 2009 (1)
    • May 2009 (1)
    • April 2009 (1)
    • March 2009 (1)
    • October 2008 (3)
    • October 2007 (3)
    • July 2007 (4)
    • June 2007 (1)
    • May 2007 (3)
  • Meta

    • Log in
    • Entries RSS
    • Comments RSS
    • WordPress.org
  • Categories

    • News (15)
    • Ropardo Team (8)
    • Ropardo Products (6)
      • File Tracking Client (4)
      • iManagement (2)
    • Software Development (83)
      • Microsoft.NET (22)
      • Java (40)
      • Oracle (8)
      • Power Builder (3)
      • Liferay (5)
      • Lotus Notes (9)
      • xWiki (4)
    • System Adminstration (13)
      • Linux (10)
      • Windows (3)
    • Programming (1)
    • Uncategorized (3)
    • Databases (10)
      • MSSQL (5)
      • PostgreeSQL (3)
    • Microsoft.NET (1)
    • Web Development (28)
      • ASP/ASPX (3)
      • Content Management Systems (1)
      • HTML/CSS (5)
      • Javascrip/AJAX (8)
      • PHP (7)
    • Oracle E Business Suite (6)
  • Tags

    .NET ajax blog C# certification client CMS control css database Debugging django Domino Eclipse extension file tracking filter fun gentoo google Hibernate how to html image iManagement import Java javascript jQuery liferay Linux Lotus Notes lotus script Oracle Oracle BI Publisher 11g PHP portal PostgreSQL powerbuilder Python SQL Telerik velocity xml Xwiki

© 2010 ROPARDO s.r.l..

Powered by WordPress. Styled by Ropardo