Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 112   Methods: 3
NCLOC: 81   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
PojoTxLockInterceptor.java 58.3% 71.4% 100% 69.8%
coverage coverage
 1    /*
 2    * JBoss, Home of Professional Open Source
 3    *
 4    * Distributable under LGPL license.
 5    * See terms of license at gnu.org.
 6    */
 7   
 8    package org.jboss.cache.pojo.interceptors;
 9   
 10    import org.jboss.aop.joinpoint.Invocation;
 11    import org.jboss.aop.joinpoint.MethodInvocation;
 12    import org.jboss.cache.Cache;
 13    import org.jboss.cache.CacheException;
 14    import org.jboss.cache.CacheSPI;
 15    import org.jboss.cache.Fqn;
 16    import org.jboss.cache.lock.UpgradeException;
 17    import org.jboss.cache.pojo.PojoCacheException;
 18    import org.jboss.cache.pojo.impl.InternalConstant;
 19   
 20    /**
 21    * Interceptor that handles the parent node lock associated with transaction.
 22    *
 23    * @author Ben Wang
 24    * @version $Id: PojoTxLockInterceptor.java,v 1.4 2007/06/28 00:56:06 jgreene Exp $
 25    */
 26    public class PojoTxLockInterceptor extends AbstractInterceptor
 27    {
 28    public static final String LOCK_KEY = InternalConstant.POJOCACHE_KEY_PREFIX + "LOCK";
 29    // retry times for lockPojo just in case there is upgrade exception during concurrent access.
 30    private final int RETRY = 5;
 31   
 32  25119 public Object invoke(Invocation in) throws Throwable
 33    {
 34  25119 MethodInvocation invocation = (MethodInvocation) in;
 35  25119 try
 36    {
 37  25119 handleLock(invocation);
 38  25118 return invocation.invokeNext(); // proceed to next advice or actual call
 39    }
 40    finally
 41    {
 42    // handleUnLock(invocation);
 43    }
 44    }
 45   
 46  25119 private void handleLock(MethodInvocation invocation) throws Throwable
 47    {
 48  25119 Fqn id = (Fqn) invocation.getArguments()[0];
 49  25119 Cache<Object, Object> cache = getCache(invocation);
 50    // Object owner = cache.getLockOwner();
 51  25119 Object owner = null;
 52  25118 if (!lockPojo(owner, id, cache))
 53    {
 54  0 throw new PojoCacheException("PojoCache.removeObject(): Can't obtain the pojo lock under id: " + id);
 55    }
 56    }
 57   
 58  25119 private boolean lockPojo(Object owner, Fqn id, Cache<Object, Object> cache) throws CacheException
 59    {
 60  25119 if (log.isDebugEnabled())
 61    {
 62  0 log.debug("lockPojo(): id:" + id + " Owner: " + owner);
 63    }
 64   
 65  25119 boolean isNeeded = true;
 66  25119 int retry = 0;
 67    // If this is an internal id and also it has three levels, we are saying this is
 68    // Collection, and we need to lock the parent as well.
 69    // TODO Still a bit ad hoc.
 70  25119 Fqn realId = id;
 71  25119 if (id.isChildOrEquals(InternalConstant.JBOSS_INTERNAL) && id.size() > 2)
 72    {
 73  20740 realId = id.getParent();
 74  20740 if (log.isDebugEnabled())
 75    {
 76  0 log.debug("lockPojo(): will lock parent id instead:" + realId);
 77    }
 78    }
 79   
 80  25119 while (isNeeded)
 81    {
 82  25119 try
 83    {
 84  25119 cache.put(realId, LOCK_KEY, "LOCK");
 85  25118 isNeeded = false;
 86    }
 87    catch (UpgradeException upe)
 88    {
 89  0 log.warn("lockPojo(): can't upgrade the lock during lockPojo. Will re-try. id: " + realId
 90    + " retry times: " + retry);
 91    // TODO is this really ok to comment out??
 92    // cache.get(realId).release(owner);
 93  0 if (retry++ > RETRY)
 94    {
 95  0 return false;
 96    }
 97    // try to sleep a little as well.
 98  0 try
 99    {
 100  0 Thread.sleep(10);
 101    }
 102    catch (InterruptedException e)
 103    {
 104    ;
 105    }
 106    }
 107    }
 108   
 109  25118 return true;
 110    }
 111   
 112    }