[jboss-cvs] JBossCache/src/org/jboss/cache/pojo/interceptors/dynamic ...

Ben Wang bwang at jboss.com
Sat Jan 13 10:55:05 EST 2007


  User: bwang   
  Date: 07/01/13 10:55:05

  Added:       src/org/jboss/cache/pojo/interceptors/dynamic       
                        CachedSetInterceptor.java
                        CachedListInterceptor.java
                        ReentrancyStopperInterceptor.java
                        CachedMapInterceptor.java
                        AbstractCollectionInterceptor.java
                        CacheFieldInterceptor.java BaseInterceptor.java
  Log:
  JBCACHE-922 Merged src-50 and tests-50 into src and tests, respectively.
  
  Revision  Changes    Path
  1.1      date: 2007/01/13 15:55:05;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/dynamic/CachedSetInterceptor.java
  
  Index: CachedSetInterceptor.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.pojo.interceptors.dynamic;
  
  import org.jboss.cache.Fqn;
  import org.jboss.cache.pojo.impl.PojoCacheImpl;
  import org.jboss.cache.pojo.collection.CollectionInterceptorUtil;
  import org.jboss.cache.pojo.collection.CachedSetImpl;
  import org.jboss.aop.advice.Interceptor;
  
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.Set;
  
  /**
   * Set interceptor that delegates underlying impl.
   *
   * @author Ben Wang
   */
  @SuppressWarnings({"CanBeFinal"})
  public class CachedSetInterceptor extends AbstractCollectionInterceptor
  {
  //   protected static final Log log_=LogFactory.getLog(CachedSetInterceptor.class);
  
     private Map methodMap_;
     private static final Map managedMethods_ =
             CollectionInterceptorUtil.getManagedMethods(Set.class);
     private Set cacheImpl_;
     private Set current_;
     private Set inMemImpl_;
  
     public CachedSetInterceptor(PojoCacheImpl cache, Fqn fqn, Class clazz, Set obj)
     {
        this.fqn_ = fqn;
        methodMap_ = CollectionInterceptorUtil.getMethodMap(clazz);
        cacheImpl_ = new CachedSetImpl(cache, this);
        inMemImpl_ = obj;
        current_ = cacheImpl_;
     }
  
     public CachedSetInterceptor() {}
  
     public Object clone()
     {
        CachedSetInterceptor interceptor = new CachedSetInterceptor();
        interceptor.setFqn(getFqn());
        interceptor.setAopInstance(getAopInstance());
        interceptor.setCurrentCopy(getCurrentCopy());
        interceptor.setInMemoryCopy(getInMemoryCopy());
        interceptor.setCacheCopy(getCacheCopy());
        return interceptor;
     }
  
     public void setInterceptor(Interceptor intcptr)
     {
        CachedSetInterceptor interceptor = (CachedSetInterceptor)intcptr;
        setFqn(interceptor.getFqn());
        setAopInstance(interceptor.getAopInstance());
        setCurrentCopy(interceptor.getCurrentCopy());
        setInMemoryCopy(interceptor.getInMemoryCopy());
        setCacheCopy(interceptor.getCacheCopy());
     }
  
     public Object getCurrentCopy()
     {
        return current_;
     }
  
     void setInMemoryCopy(Object obj)
     {
        inMemImpl_ = (Set)obj;
     }
  
     Object getInMemoryCopy()
     {
        return inMemImpl_;
     }
  
     void setCacheCopy(Object obj)
     {
        cacheImpl_ = (Set)obj;
     }
  
     Object getCacheCopy()
     {
        return cacheImpl_;
     }
  
     void setCurrentCopy(Object obj)
     {
        current_ = (Set)obj;
     }
  
     /**
      * When we want to associate this proxy with the cache again. We will need to translate the in-memory
      * content to the cache store first.
      */
     public void attach(Fqn fqn, boolean copyToCache)
     {
        super.attach(fqn, copyToCache);
  
        if (copyToCache)
           toCache();
  
        current_ = cacheImpl_;
     }
  
     private void toCache()
     {
        if (inMemImpl_ == null)
           throw new IllegalStateException("CachedSetInterceptor.toCache(). inMemImpl is null.");
  
        for (Iterator it = inMemImpl_.iterator(); it.hasNext();)
        {
           Object obj = it.next();
           it.remove();
           cacheImpl_.add(obj);
        }
  
        inMemImpl_ = null;   // we are done with this.
     }
  
     /**
      * When we want to separate this proxy from the cache. We will destroy the cache content and copy them to
      * the in-memory copy.
      */
     public void detach(boolean removeFromCache)
     {
        super.detach(removeFromCache);
  
        toMemory(removeFromCache);
  
        current_ = inMemImpl_;
     }
  
     private void toMemory(boolean removeFromCache)
     {
        if (inMemImpl_ == null)
        {
           inMemImpl_ = new HashSet();
        }
  
        // TODO. This needs optimization.
        inMemImpl_.clear();
        for (Iterator it = cacheImpl_.iterator(); it.hasNext();)
        {
           Object obj = it.next();
           if (removeFromCache)
              it.remove();
           inMemImpl_.add(obj);
        }
     }
  
  
     public String getName()
     {
        return "CachedSetInterceptor";
     }
  
     public Object invoke(org.jboss.aop.joinpoint.Invocation invocation) throws Throwable
     {
        if (current_ == null)
           throw new IllegalStateException("CachedSetInterceptor.invoke(). current_ is null.");
  
        return CollectionInterceptorUtil.invoke(invocation,
                current_,
                methodMap_,
                managedMethods_);
     }
  }
  
  
  
  1.1      date: 2007/01/13 15:55:05;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/dynamic/CachedListInterceptor.java
  
  Index: CachedListInterceptor.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.pojo.interceptors.dynamic;
  
  import org.jboss.cache.Fqn;
  import org.jboss.cache.pojo.impl.PojoCacheImpl;
  import org.jboss.cache.pojo.collection.CollectionInterceptorUtil;
  import org.jboss.cache.pojo.collection.CachedListImpl;
  import org.jboss.aop.advice.Interceptor;
  
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Map;
  
  /**
   * List ineterceptor that delegates to underlying implementation.
   *
   * @author Ben Wang
   */
  
  @SuppressWarnings({"CanBeFinal"})
  public class CachedListInterceptor extends AbstractCollectionInterceptor
  {
  
  //   protected static final Log log_ = LogFactory.getLog(CachedListInterceptor.class);
     private static final Map managedMethods_ =
             CollectionInterceptorUtil.getManagedMethods(List.class);
  
     private Map methodMap_;
     // This is the copy in cache store when it is attached.
     private List cacheImpl_;
     // This is the copy in-memory when the state is detached.
     private List inMemImpl_;
     // Whichever is used now.
     private List current_;
  
     public CachedListInterceptor(PojoCacheImpl cache, Fqn fqn, Class clazz, List obj)
     {
        this.fqn_ = fqn;
        methodMap_ = CollectionInterceptorUtil.getMethodMap(clazz);
        cacheImpl_ = new CachedListImpl(cache, this);
        inMemImpl_ = obj;   // lazy initialization here.
        current_ = cacheImpl_;
     }
  
     public CachedListInterceptor() {}
  
     public Object clone()
     {
        CachedListInterceptor interceptor = new CachedListInterceptor();
        interceptor.setFqn(getFqn());
        interceptor.setAopInstance(getAopInstance());
        interceptor.setCurrentCopy(getCurrentCopy());
        interceptor.setInMemoryCopy(getInMemoryCopy());
        interceptor.setCacheCopy(getCacheCopy());
        return interceptor;
     }
  
     public void setInterceptor(Interceptor intcptr)
     {
        CachedListInterceptor interceptor = (CachedListInterceptor)intcptr;
        setFqn(interceptor.getFqn());
        setAopInstance(interceptor.getAopInstance());
        setCurrentCopy(interceptor.getCurrentCopy());
        setInMemoryCopy(interceptor.getInMemoryCopy());
        setCacheCopy(interceptor.getCacheCopy());
     }
  
     /**
      * When we want to associate this proxy with the cache again. We will need to translate the in-memory
      * content to the cache store first.
      */
     public void attach(Fqn fqn, boolean copyToCache)
     {
        super.attach(fqn, copyToCache);
  
        if (copyToCache)
           toCache();
        current_ = cacheImpl_;
     }
  
     private void toCache()
     {
        if (inMemImpl_ == null)
           throw new IllegalStateException("CachedListInterceptor.toCache(). inMemImpl is null.");
  
        // TODO This may not be optimal
        List tmpList = new ArrayList();
        for (int i = inMemImpl_.size(); i > 0; i--)
        {
           Object obj = inMemImpl_.remove(i - 1);
           tmpList.add(obj);
        }
  
        int size = tmpList.size();
        for (int i = 0; i < tmpList.size(); i++)
        {
           cacheImpl_.add(tmpList.get(size - i - 1));
        }
  
        inMemImpl_ = null;   // we are done with this.
     }
  
     /**
      * When we want to separate this proxy from the cache. We will destroy the cache content and copy them to
      * the in-memory copy.
      */
     public void detach(boolean removeFromCache)
     {
        super.detach(removeFromCache);
        toMemory(removeFromCache);
        current_ = inMemImpl_;
     }
  
     public Object getCurrentCopy()
     {
        return current_;
     }
  
     void setInMemoryCopy(Object obj)
     {
        inMemImpl_ = (List)obj;
     }
  
     Object getInMemoryCopy()
     {
        return inMemImpl_;
     }
  
     Object getCacheCopy()
     {
        return cacheImpl_;
     }
  
     void setCacheCopy(Object obj)
     {
        cacheImpl_ = (List)obj;
     }
  
     void setCurrentCopy(Object obj)
     {
        current_ = (List)obj;
     }
  
     private void toMemory(boolean removeFromCache)
     {
        if (inMemImpl_ == null)
        {
           inMemImpl_ = new ArrayList();
        }
  
        // Optimization since remove from the beginning is very expensive.
        List tmpList = new ArrayList();
        for (int i = cacheImpl_.size(); i > 0; i--)
        {
           int j = i - 1;
           Object obj = null;
           if (removeFromCache)
           {
              obj = cacheImpl_.remove(j);
           } else
           {
              obj = cacheImpl_.get(j);
           }
  
           tmpList.add(obj);
        }
  
        int size = tmpList.size();
        inMemImpl_.clear();
        for (int i = 0; i < tmpList.size(); i++)
        {
           inMemImpl_.add(tmpList.get(size - i - 1));
        }
     }
  
     public String getName()
     {
        return "CachedListInterceptor";
     }
  
     public Object invoke(org.jboss.aop.joinpoint.Invocation invocation) throws Throwable
     {
        if (current_ == null)
           throw new IllegalStateException("CachedListInterceptor.invoke(). current_ is null.");
  
        return CollectionInterceptorUtil.invoke(invocation,
                current_,
                methodMap_,
                managedMethods_);
     }
  }
  
  
  
  1.1      date: 2007/01/13 15:55:05;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/dynamic/ReentrancyStopperInterceptor.java
  
  Index: ReentrancyStopperInterceptor.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.cache.pojo.interceptors.dynamic;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.jboss.aop.joinpoint.Invocation;
  import org.jboss.aop.joinpoint.FieldInvocation;
  import org.jboss.aop.advice.Interceptor;
  
  import java.lang.reflect.Field;
  
  /**
   * Main dynamic interceptor to intercept for field replication.
   *
   * @author Ben Wang
   */
  
  public class ReentrancyStopperInterceptor implements Interceptor
  {
     private final Log log_ = LogFactory.getLog(ReentrancyStopperInterceptor.class);
     private ThreadLocal<Boolean> done;
  
     public ReentrancyStopperInterceptor()
     {
        done = new ThreadLocal();
        done.set(false);
     }
  
     public String getName()
     {
        return ReentrancyStopperInterceptor.class.getName();
     }
  
     public Object invoke(Invocation invocation) throws Throwable
     {
        boolean wasDone = done.get();
  
        try
        {
           if (!wasDone)
           {
              done.set(true);
              return invocation.invokeNext();
           } else
           {
              //Needs adding, and will invoke target joinpoint skipping the rest of the chain
              if(log_.isDebugEnabled())
              {
                 Field field = ((FieldInvocation)invocation).getField();
                 log_.debug("Detect recursive interception. Will call the target directly: " +field.getName());
              }
              return invocation.invokeTarget();
           }
        }
        finally
        {
           if (!wasDone)
           {
              done.set(false);
           }
        }
     }
  }
  
  
  
  1.1      date: 2007/01/13 15:55:05;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/dynamic/CachedMapInterceptor.java
  
  Index: CachedMapInterceptor.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.pojo.interceptors.dynamic;
  
  import org.jboss.cache.Fqn;
  import org.jboss.cache.pojo.impl.PojoCacheImpl;
  import org.jboss.cache.pojo.collection.CollectionInterceptorUtil;
  import org.jboss.cache.pojo.collection.CachedMapImpl;
  import org.jboss.aop.advice.Interceptor;
  
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  
  /**
   * Map interceptor that delegates to the underlying impl.
   *
   * @author Ben Wang
   */
  @SuppressWarnings({"CanBeFinal"})
  public class CachedMapInterceptor extends AbstractCollectionInterceptor
  {
  
  //   protected static final Log log_ = LogFactory.getLog(CachedMapInterceptor.class);
     private static final Map managedMethods_ =
             CollectionInterceptorUtil.getManagedMethods(Map.class);
     private Map methodMap_;
     private Map cacheImpl_;
     private Map inMemImpl_;
     private Map current_;
  
     public CachedMapInterceptor(PojoCacheImpl cache, Fqn fqn, Class clazz, Map obj)
     {
        this.fqn_ = fqn;
        methodMap_ = CollectionInterceptorUtil.getMethodMap(clazz);
        cacheImpl_ = new CachedMapImpl(cache, this);
        inMemImpl_ = obj;
        current_ = cacheImpl_;
     }
  
     CachedMapInterceptor() {}
  
     public Object clone()
     {
        CachedMapInterceptor interceptor = new CachedMapInterceptor();
        interceptor.setFqn(getFqn());
        interceptor.setAopInstance(getAopInstance());
        interceptor.setCurrentCopy(getCurrentCopy());
        interceptor.setInMemoryCopy(getInMemoryCopy());
        interceptor.setCacheCopy(getCacheCopy());
        return interceptor;
     }
  
     public void setInterceptor(Interceptor intcptr)
     {
        CachedMapInterceptor interceptor = (CachedMapInterceptor)intcptr;
        setFqn(interceptor.getFqn());
        setAopInstance(interceptor.getAopInstance());
        setCurrentCopy(interceptor.getCurrentCopy());
        setInMemoryCopy(interceptor.getInMemoryCopy());
        setCacheCopy(interceptor.getCacheCopy());
     }
  
     public Object getCurrentCopy()
     {
        return current_;
     }
  
     void setInMemoryCopy(Object obj)
     {
        inMemImpl_ = (Map)obj;
     }
  
     Object getInMemoryCopy()
     {
        return inMemImpl_;
     }
  
     void setCacheCopy(Object obj)
     {
        cacheImpl_ = (Map)obj;
     }
  
     Object getCacheCopy()
     {
        return cacheImpl_;
     }
  
     void setCurrentCopy(Object obj)
     {
        current_ = (Map)obj;
     }
  
     /**
      * When we want to associate this proxy with the cache again. We will need to translate the in-memory
      * content to the cache store first.
      */
     public void attach(Fqn fqn, boolean copyToCache)
     {
        super.attach(fqn, copyToCache);
  
        if (copyToCache)
           toCache();
  
        current_ = cacheImpl_;
     }
  
     private void toCache()
     {
        if (inMemImpl_ == null)
           throw new IllegalStateException("CachedMapInterceptor.toCache(). inMemImpl is null.");
  
        for (Object key : inMemImpl_.keySet())
        {
           Object val = inMemImpl_.get(key);
           cacheImpl_.put(key, val);
        }
  
        inMemImpl_.clear();
        inMemImpl_ = null;   // we are done with this.
     }
  
     /**
      * When we want to separate this proxy from the cache. We will destroy the cache content and copy them to
      * the in-memory copy.
      */
     public void detach(boolean removeFromCache)
     {
        super.detach(removeFromCache);
  
        toMemory(removeFromCache);
  
        current_ = inMemImpl_;
     }
  
     private void toMemory(boolean removeFromCache)
     {
        if (inMemImpl_ == null)
        {
           inMemImpl_ = new HashMap();
        }
  
        Iterator it = cacheImpl_.keySet().iterator();
        inMemImpl_.clear();
        while (it.hasNext())
        {
           Object key = it.next();
           Object val = null;
           if (removeFromCache)
           {
              val = cacheImpl_.remove(key);
           } else
           {
              val = cacheImpl_.get(key);
           }
           inMemImpl_.put(key, val);
        }
     }
  
     public String getName()
     {
        return "CachedMapInterceptor";
     }
  
     public Object invoke(org.jboss.aop.joinpoint.Invocation invocation) throws Throwable
     {
        if (current_ == null)
           throw new IllegalStateException("CachedMapInterceptor.invoke(). current_ is null.");
  
        return CollectionInterceptorUtil.invoke(invocation,
                current_,
                methodMap_,
                managedMethods_);
     }
  
  }
  
  
  
  1.1      date: 2007/01/13 15:55:05;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/dynamic/AbstractCollectionInterceptor.java
  
  Index: AbstractCollectionInterceptor.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.cache.pojo.interceptors.dynamic;
  
  import org.jboss.cache.Fqn;
  import org.jboss.cache.pojo.PojoInstance;
  
  /**
   * Abstract base class for collection interceptor.
   *
   * @author Ben Wang
   * @version $Id: AbstractCollectionInterceptor.java,v 1.1 2007/01/13 15:55:05 bwang Exp $
   */
  @SuppressWarnings({"CanBeFinal"})
  public abstract class AbstractCollectionInterceptor implements BaseInterceptor
  {
     Fqn fqn_;
     private boolean attached_ = true;
     private PojoInstance pojoInstance_;
  
     @SuppressWarnings({"CanBeFinal"})
     public Fqn getFqn()
     {
        return fqn_;
     }
  
     @SuppressWarnings({"CanBeFinal"})
     public void setFqn(Fqn fqn)
     {
        this.fqn_ = fqn;
     }
  
     @SuppressWarnings({"CanBeFinal"})
     public PojoInstance getAopInstance()
     {
        return pojoInstance_;
     }
  
     public void setAopInstance(PojoInstance pojoInstance)
     {
        this.pojoInstance_ = pojoInstance;
     }
  
     /**
      * Attaching the Collection to PojoCache.
      */
     public void attach(Fqn fqn, boolean copyToCache)
     {
        // This is a hook to allow re-attching the Collection without specifying the fqn.
        if (fqn != null)
        {
           setFqn(fqn);
        }
        attached_ = true;
        // Reattach anything in-memory to cache
     }
  
     public void detach(boolean removeFromCache)
     {
        attached_ = false;
        // Detach by tranferring the cache content to in-memory copy
     }
  
     public boolean isAttached()
     {
        return attached_;
     }
  
     abstract void setInMemoryCopy(Object obj);
     abstract Object getInMemoryCopy();
     abstract void setCacheCopy(Object obj);
     abstract Object getCacheCopy();
     abstract void setCurrentCopy(Object obj);
     public abstract Object getCurrentCopy();
  }
  
  
  
  1.1      date: 2007/01/13 15:55:05;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/dynamic/CacheFieldInterceptor.java
  
  Index: CacheFieldInterceptor.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.pojo.interceptors.dynamic;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.jboss.aop.Advised;
  import org.jboss.aop.Advisor;
  import org.jboss.aop.InstanceAdvisor;
  import org.jboss.aop.advice.Interceptor;
  import org.jboss.aop.joinpoint.FieldInvocation;
  import org.jboss.aop.joinpoint.FieldReadInvocation;
  import org.jboss.aop.joinpoint.FieldWriteInvocation;
  import org.jboss.aop.joinpoint.Invocation;
  import org.jboss.aop.joinpoint.MethodInvocation;
  import org.jboss.cache.CacheSPI;
  import org.jboss.cache.Fqn;
  import org.jboss.cache.pojo.CachedType;
  import org.jboss.cache.pojo.PojoCacheAlreadyDetachedException;
  import org.jboss.cache.pojo.PojoInstance;
  import org.jboss.cache.pojo.PojoUtil;
  import org.jboss.cache.pojo.PojoCacheException;
  import org.jboss.cache.pojo.impl.PojoCacheImpl;
  import org.jboss.cache.pojo.memory.FieldPersistentReference;
  import org.jboss.cache.pojo.util.AopUtil;
  import org.jboss.cache.pojo.util.CacheApiUtil;
  
  import java.lang.reflect.Field;
  import java.util.Iterator;
  
  /**
   * Main dynamic interceptor to intercept for field replication.
   *
   * @author Ben Wang
   */
  
  public class CacheFieldInterceptor implements BaseInterceptor
  {
     private final Log log_ = LogFactory.getLog(CacheFieldInterceptor.class);
     private CacheSPI cache_;
     private PojoCacheImpl pCache_;
     private CachedType type_;
     private Fqn fqn_;
     private String name_;
     private PojoInstance pojoInstance_;
     private PojoUtil util_;
  
     public CacheFieldInterceptor(PojoCacheImpl pCache, Fqn fqn, CachedType type)
     {
        this.pCache_ = pCache;
        cache_ = (CacheSPI) this.pCache_.getCache();
        this.fqn_ = fqn;
        this.type_ = type;
        util_ = new PojoUtil();
     }
  
     public CacheFieldInterceptor()
     {
     }
  
     public PojoInstance getAopInstance()
     {
        return pojoInstance_;
     }
  
     public Object clone()
     {
        CacheFieldInterceptor interceptor = new CacheFieldInterceptor();
        interceptor.setFqn(getFqn());
        interceptor.setAopInstance(getAopInstance());
        return interceptor;
     }
  
     public void setInterceptor(Interceptor intcptr)
     {
        CacheFieldInterceptor interceptor = (CacheFieldInterceptor) intcptr;
        setFqn(interceptor.getFqn());
        setAopInstance(interceptor.getAopInstance());
     }
  
     public void setAopInstance(PojoInstance pojoInstance)
     {
        this.pojoInstance_ = pojoInstance;
     }
  
     public String getName()
     {
        if (name_ == null)
        {
           this.name_ = "CacheFieldInterceptor on [" + fqn_ + "]";
        }
        return name_;
     }
  
     public Object invoke(Invocation invocation) throws Throwable
     {
        // Kind of ad hoc now. MethodInvocation should not invoke this.
        if (invocation instanceof MethodInvocation)
           return invocation.invokeNext();
  
        // Check if CLASS_INTERNAL exists. If not, that means we are done. We need to remove ourself.
        // Note that if speed is important, we will need to perform the detach step pro-actively,
        // that is, use a listener to listen for the removeObject event.
  //      if (isPojoDetached(invocation))
  //      {
  //         return invocation.invokeNext();  // invoke the in-memory pojo directly
  //      }
  
        if (invocation instanceof FieldWriteInvocation)
        {
           FieldInvocation fieldInvocation =
                   (FieldInvocation) invocation;
  
           Advisor advisor = fieldInvocation.getAdvisor();
           Field field = fieldInvocation.getField();
           if (log_.isTraceEnabled())
           {
              log_.trace("invoke(): field write interception for fqn: " + fqn_ + " and field: " + field);
           }
  
           // Only if this field is replicatable. static, transient and final are not.
           CachedType fieldType = pCache_.getCachedType(field.getType());
           CachedType parentType = pCache_.getCachedType(field.getDeclaringClass());
           Object value = ((FieldWriteInvocation) fieldInvocation).getValue();
           if (!isNonReplicatable(field, advisor, parentType))
           {
              if (fieldType.isImmediate() || hasSerializableAnnotation(field, advisor, parentType))
              {
                 cache_.put(fqn_, field.getName(), value);
              }
              else
              {
                 //cache_.putObject(((Fqn)fqn_.clone()).add(field.getLastElementAsString()), value);
                 pCache_.attach(new Fqn(fqn_, field.getName()), value);
              }
           }
  
           Object obj = fieldInvocation.getTargetObject();
           util_.inMemorySubstitution(obj, field, value);
        }
        else if (invocation instanceof FieldReadInvocation)
        {
           FieldInvocation fieldInvocation =
                   (FieldInvocation) invocation;
           Field field = fieldInvocation.getField();
           Advisor advisor = fieldInvocation.getAdvisor();
  
           // Only if this field is replicatable
           CachedType fieldType = pCache_.getCachedType(field.getType());
           CachedType parentType = pCache_.getCachedType(field.getDeclaringClass());
           if (!isNonReplicatable(field, advisor, parentType))
           {
              Object result;
              if (fieldType.isImmediate() || hasSerializableAnnotation(field, advisor, parentType))
              {
                 result = cache_.get(fqn_, field.getName());
              }
              else
              {
                 //result = cache_.getObject(((Fqn)fqn_.clone()).add(field.getLastElementAsString()));
                 result = pCache_.getObject(new Fqn(fqn_, field.getName()));
              }
  
              // if result is null, we need to make sure the in-memory reference is null
              // as well. If it is not, then we know this one is null because it has
              // been evicted. Will need to reconstruct it
              if (result != null)
                 return result;
              else
              {
                 Object value = invocation.getTargetObject();
                 if (value == null || field.get(value) == null)   // if both are null, we know this is null as well.
                    return null;
  
                 isPojoDetached(invocation);
              }
           }
        }
  
        return invocation.invokeNext();
  
     }
  
     /**
      * See if this field is non-replicatable such as @Transient or transient modifier.
      */
     private static boolean isNonReplicatable(Field field, Advisor advisor, CachedType type)
     {
        if (CachedType.hasAnnotation(field.getDeclaringClass(), advisor, type))
        {
           if (CachedType.hasTransientAnnotation(field, advisor)) return true;
        }
  
        if (CachedType.isPrimitiveNonReplicatable(field)) return true;
  
        return false;
     }
  
     private static boolean hasSerializableAnnotation(Field field, Advisor advisor, CachedType type)
     {
        if (CachedType.hasAnnotation(field.getDeclaringClass(), advisor, type))
        {
           if (CachedType.hasSerializableAnnotation(field, advisor)) return true;
        }
  
        return false;
     }
  
     /**
      * Check if the pojo is detached already. If it is and we still have the cache_ interceptor on
      * this pojo, we will go ahead and remove it since it should not be there in the first place.
      *
      * @param invocation
      */
     private boolean isPojoDetached(Invocation invocation)
     {
        boolean detached = false;
  
        if (!CacheApiUtil.exists(cache_, fqn_, PojoInstance.KEY))
        {
           detached = true;
           Object obj = invocation.getTargetObject();
           if (!(obj instanceof Advised))
              throw new PojoCacheException("Interception on non-advised pojo " + obj.toString());
  
           InstanceAdvisor advisor = ((Advised) obj)._getInstanceAdvisor();
           CacheFieldInterceptor interceptor = (CacheFieldInterceptor) AopUtil.findCacheInterceptor(advisor);
           if (interceptor != null)
           {
              advisor.removeInterceptor(interceptor.getName());
              throw new PojoCacheAlreadyDetachedException("pojo: " + obj.getClass() +
                      " has possibly been detached remotely. Internal id: " + interceptor.getFqn());
           }
        }
  
        return detached;
     }
  
     protected void checkCacheConsistency() throws Exception
     {
        if (this != cache_.get(fqn_, PojoInstance.KEY))
        {
           throw new PojoCacheException("Cache inconsistency: Outdated PojoInstance");
        }
     }
  
     public void beforeSerialization(Object target) throws Exception
     {
  
        // fill objects
        for (Iterator i = type_.getFields().iterator(); i.hasNext();)
        {
           Field field = (Field) (((FieldPersistentReference) i.next())).get();
           CachedType fieldType = pCache_.getCachedType(field.getType());
           Object value = null;
           if (fieldType.isImmediate())
           {
              value = cache_.get(fqn_, field.getName());
           }
           else
           {
              //		value = removeObject(fqn_+CacheImpl.SEPARATOR+field.getLastElementAsString());
              //value = cache_.getObject(((Fqn)fqn_.clone()).add(field.getLastElementAsString()));
              value = pCache_.getObject(new Fqn(fqn_, field.getName()));
           }
           //	    System.out.println("Setting field " + field.getLastElementAsString() + "[" + field.getDeclaringClass() + "] of "+ target.getClass() + " to " + value);
           field.set(target, value);
        }
     }
  
     boolean isChildOf(Fqn parentFqn)
     {
        return fqn_.isChildOf(parentFqn);
     }
  
  //   void setFqn(Fqn fqn_)
  //   {
  //      this.fqn_ = fqn_;
  //   }
  
     public Fqn getFqn()
     {
        return fqn_;
     }
  
     public void setFqn(Fqn fqn)
     {
        this.fqn_ = fqn;
     }
  
  }
  
  
  
  1.1      date: 2007/01/13 15:55:05;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/dynamic/BaseInterceptor.java
  
  Index: BaseInterceptor.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.pojo.interceptors.dynamic;
  
  import org.jboss.cache.Fqn;
  import org.jboss.cache.pojo.PojoInstance;
  import org.jboss.aop.advice.Interceptor;
  
  
  /**
   * Base cache interceptor
   *
   * @author Ben Wang
   */
  
  public interface BaseInterceptor
          extends Interceptor, Cloneable
  {
     /**
      * Get the original fqn that is associated with this interceptor (or advisor).
      */
     Fqn getFqn();
  
     void setFqn(Fqn fqn);
  
     PojoInstance getAopInstance();
  
     void setAopInstance(PojoInstance pojoInstance);
  
     void setInterceptor(Interceptor interceptor);
  }
  
  
  



More information about the jboss-cvs-commits mailing list