Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 175   Methods: 9
NCLOC: 119   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ObjectGraphHandler.java 43.8% 76.1% 88.9% 70.4%
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.impl;
 9   
 10    import org.apache.commons.logging.Log;
 11    import org.apache.commons.logging.LogFactory;
 12    import org.jboss.aop.Advised;
 13    import org.jboss.aop.InstanceAdvisor;
 14    import org.jboss.aop.advice.Interceptor;
 15    import org.jboss.aop.proxy.ClassProxy;
 16    import org.jboss.cache.Cache;
 17    import org.jboss.cache.CacheException;
 18    import org.jboss.cache.CacheSPI;
 19    import org.jboss.cache.Fqn;
 20    import org.jboss.cache.pojo.PojoCacheException;
 21    import org.jboss.cache.pojo.collection.CollectionInterceptorUtil;
 22    import org.jboss.cache.pojo.interceptors.dynamic.BaseInterceptor;
 23    import org.jboss.cache.pojo.util.AopUtil;
 24   
 25    /**
 26    * Handle the object graph management.
 27    *
 28    * @author Ben Wang
 29    * Date: Aug 4, 2005
 30    * @version $Id: ObjectGraphHandler.java,v 1.7 2007/06/28 00:56:06 jgreene Exp $
 31    */
 32    class ObjectGraphHandler
 33    {
 34    private PojoCacheImpl cache;
 35    private InternalHelper internal_;
 36    private final static Log log = LogFactory.getLog(ObjectGraphHandler.class);
 37   
 38  499 public ObjectGraphHandler(PojoCacheImpl cache, InternalHelper internal)
 39    {
 40  499 this.cache = cache;
 41  499 internal_ = internal;
 42    }
 43   
 44  0 Object get(Fqn fqn, Class clazz, PojoInstance pojoInstance) throws CacheException
 45    {
 46    // Note this is actually the aliasFqn, not the real fqn!
 47  0 Object obj;
 48   
 49  0 obj = cache.getObject(fqn);
 50  0 if (obj == null)
 51  0 throw new PojoCacheException("ObjectGraphHandler.get(): null object from internal ref node." +
 52    " Internal ref node: " + fqn);
 53   
 54  0 return obj; // No need to set the instance under fqn. It is located in refFqn anyway.
 55    }
 56   
 57  192 void put(Fqn fqn, Object obj, String field) throws CacheException
 58    {
 59  192 CachedType type = cache.getCachedType(obj.getClass());
 60   
 61  192 InstanceAdvisor advisor = null;
 62  192 Interceptor interceptor = null;
 63   
 64  192 if (obj instanceof Advised)
 65    {
 66  161 advisor = ((Advised) obj)._getInstanceAdvisor();
 67  161 if (advisor == null)
 68  0 throw new PojoCacheException("put(): InstanceAdvisor is null for: " + obj);
 69    // Step Check for cross references
 70  161 interceptor = AopUtil.findCacheInterceptor(advisor);
 71    }
 72    else
 73    {
 74  31 advisor = ((ClassProxy) obj)._getInstanceAdvisor();
 75  31 if (advisor == null)
 76  0 throw new PojoCacheException("put(): InstanceAdvisor is null for: " + obj);
 77  31 interceptor = CollectionInterceptorUtil.getInterceptor((ClassProxy) obj);
 78    }
 79   
 80  192 Fqn originalFqn = null;
 81   
 82    // ah, found something. So this will be multiple referenced.
 83  192 originalFqn = ((BaseInterceptor) interceptor).getFqn();
 84   
 85    // This will increment the ref count, reset, and add ref fqn in the current fqn node.
 86  192 setupRefCounting(fqn, originalFqn);
 87    // Store a PojoReference in the external fqn node
 88  192 PojoReference pojoReference = new PojoReference();
 89  192 pojoReference.setFqn(originalFqn);
 90  192 pojoReference.setPojoClass(type.getType());
 91  192 internal_.putPojoReference(fqn, pojoReference, field);
 92    }
 93   
 94  6316 boolean isMultipleReferenced(Fqn internalFqn)
 95    {
 96    // Note this is actually the aliasFqn, not the real fqn!
 97  6316 PojoInstance pojoInstance = null;
 98  6316 try
 99    {
 100  6316 pojoInstance = internal_.getPojoInstance(internalFqn);
 101    }
 102    catch (CacheException e)
 103    {
 104  0 throw new PojoCacheException("Exception in isMultipleReferenced", e);
 105    }
 106    // check if this is a refernce
 107  6316 return InternalHelper.isMultipleReferenced(pojoInstance);
 108   
 109    }
 110   
 111  38 void remove(Fqn referencingFqn, Fqn internalFqn, Object pojo)
 112    throws CacheException
 113    {
 114  38 if (log.isDebugEnabled())
 115    {
 116  0 log.debug("remove(): removing object fqn: " + referencingFqn
 117    + " Will just de-reference it.");
 118    }
 119  38 removeFromReference(referencingFqn, internalFqn);
 120    }
 121   
 122    /**
 123    * Remove the object from the the reference fqn, meaning just decrement the ref counter.
 124    */
 125  38 private void removeFromReference(Fqn referencingFqn, Fqn originalFqn) throws CacheException
 126    {
 127  38 synchronized (referencingFqn)
 128    { // we lock the internal fqn here so no one else has access.
 129    // Decrement ref counting on the internal node
 130  38 if (decrementRefCount(referencingFqn, originalFqn) == PojoInstance.INITIAL_COUNTER_VALUE)
 131    {
 132    // No one is referring it so it is safe to remove
 133    // TODO we should make sure the parent nodes are also removed they are empty as well.
 134  0 cache.detach(referencingFqn);
 135    }
 136    }
 137    }
 138   
 139    /**
 140    * 1. increment reference counter
 141    * 2. put in refFqn so we can get it.
 142    *
 143    * @param fqn The original fqn node
 144    * @param refFqn The new internal fqn node
 145    */
 146  192 private void setupRefCounting(Fqn fqn, Fqn refFqn) throws CacheException
 147    {
 148  192 synchronized (refFqn)
 149    { // we lock the ref fqn here so no one else has access.
 150    // increment the reference counting
 151  192 incrementRefCount(refFqn, fqn);
 152    // set the internal fqn in fqn so we can reference it.
 153  192 if (log.isTraceEnabled())
 154    {
 155  0 log.trace("setupRefCounting(): current fqn: " + fqn + " set to point to: " + refFqn);
 156    }
 157    }
 158    }
 159   
 160  192 private int incrementRefCount(Fqn originalFqn, Fqn referencingFqn) throws CacheException
 161    {
 162  192 return internal_.incrementRefCount(originalFqn, referencingFqn);
 163    }
 164   
 165  38 private int decrementRefCount(Fqn referencingFqn, Fqn originalFqn) throws CacheException
 166    {
 167  38 int count = 0;
 168  ? if ((count = internal_.decrementRefCount(originalFqn, referencingFqn)) == (PojoInstance.INITIAL_COUNTER_VALUE + 1))
 169    {
 170  34 internal_.removeIndirectFqn(originalFqn.toString());
 171    }
 172   
 173  38 return count;
 174    }
 175    }