[jboss-cvs] JBossCache/old/src/org/jboss/cache/aop/collection ...

Ben Wang bwang at jboss.com
Tue Oct 31 03:01:15 EST 2006


  User: bwang   
  Date: 06/10/31 03:01:15

  Added:       old/src/org/jboss/cache/aop/collection         
                        AbstractCollectionInterceptor.java
                        CachedMapImpl.java CachedSetImpl.java
                        CachedSetInterceptor.java
                        CachedListInterceptor.java CachedListImpl.java
                        CachedMapInterceptor.java CachedListAbstract.java
                        CollectionInterceptorUtil.java
  Log:
  Deprecated files moved to old dir.
  
  Revision  Changes    Path
  1.1      date: 2006/10/31 08:01:15;  author: bwang;  state: Exp;JBossCache/old/src/org/jboss/cache/aop/collection/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.aop.collection;
  
  import org.jboss.cache.Fqn;
  import org.jboss.cache.aop.BaseInterceptor;
  import org.jboss.cache.aop.AOPInstance;
  
  /**
   * Abstract base class for collection interceptor.
   *
   * @author Ben Wang
   * @version $Id: AbstractCollectionInterceptor.java,v 1.1 2006/10/31 08:01:15 bwang Exp $
   */
  public abstract class AbstractCollectionInterceptor implements BaseInterceptor {
     protected Fqn fqn_;
     protected boolean attached_ = true;
     protected AOPInstance aopInstance_;
  
     public Fqn getFqn()
     {
        return fqn_;
     }
  
     public void setFqn(Fqn fqn)
     {
        this.fqn_ = fqn;
     }
  
     public AOPInstance getAopInstance() {
        return aopInstance_;
     }
  
     public void setAopInstance(AOPInstance aopInstance) {
        this.aopInstance_ = aopInstance;
     }
  
     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_;
     }
  }
  
  
  
  1.1      date: 2006/10/31 08:01:15;  author: bwang;  state: Exp;JBossCache/old/src/org/jboss/cache/aop/collection/CachedMapImpl.java
  
  Index: CachedMapImpl.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.aop.collection;
  
  import org.jboss.cache.CacheException;
  import org.jboss.cache.Fqn;
  import org.jboss.cache.DataNode;
  import org.jboss.cache.aop.PojoCache;
  import org.jboss.cache.aop.util.AopUtil;
  import org.jboss.cache.aop.util.Null;
  
  import java.util.*;
  
  /**
   * Map that uses cache as a backend store.
   *
   * @author Ben Wang
   * @author Scott Marlow
   */
  public class CachedMapImpl implements Map
  {
  
  //   protected static final Log log_ = LogFactory.getLog(CachedMapImpl.class);
  
     protected PojoCache cache_;
     protected AbstractCollectionInterceptor interceptor_;
  
     protected CachedMapImpl(PojoCache cache, AbstractCollectionInterceptor interceptor)
     {
        this.cache_ = cache;
        interceptor_ = interceptor;
  
     }
  
     protected Fqn getFqn()
     {
        return interceptor_.getFqn();
     }
  
     // implementation of the java.util.Map interface
  
     protected DataNode getNode()
     {
        try {
           return cache_._get(getFqn());
        } catch (Exception e) {
           throw new RuntimeException(e);
        }
     }
  
     public Object get(Object key)
     {
        try {
           return Null.toNullValue(cache_.getObject(AopUtil.constructFqn(getFqn(), Null.toNullKeyObject(key))));
        } catch (Exception e) {
           throw new RuntimeException(e);
        }
     }
  
     public Object put(Object key, Object value)
     {
        try {
           return cache_.putObject(AopUtil.constructFqn(getFqn(), Null.toNullKeyObject(key)), Null.toNullObject(value));
        } catch (Exception e) {
           throw new RuntimeException(e);
        }
     }
  
     public void putAll(Map map)
     {
        for (Iterator i = map.entrySet().iterator(); i.hasNext();) {
           Map.Entry entry = (Map.Entry) i.next();
           put(entry.getKey(), entry.getValue());
        }
     }
  
     public Object remove(Object key)
     {
        try {
           return cache_.removeObject(AopUtil.constructFqn(getFqn(), Null.toNullKeyObject(key)));
        } catch (Exception e) {
           throw new RuntimeException(e);
        }
     }
  
     public void clear()
     {
        // Need to clone first to avoid CME
        ArrayList list = new ArrayList(keySet());
        for(int i=0; i < list.size(); i++) {
           remove(list.get(i));
        }
     }
  
     public int size()
     {
        DataNode node = getNode();
        if(node == null) {
           return 0;
        }
  
        Map children = node.getChildren();
        return children == null ? 0 : children.size();
     }
  
     public boolean isEmpty()
     {
        return size() == 0;
     }
  
     public boolean containsKey(Object object)
     {
        Map children = getNode().getChildren();
        if(object != null)               // if not null,
           object = object.toString();   // convert to internal form which is always string
        return children != null && children.containsKey(Null.toNullKeyObject(object));
     }
  
     public boolean containsValue(Object object)
     {
        return values().contains(Null.toNullObject(object));
     }
  
     public Set entrySet()
     {
        final CachedMapImpl map = this;
  
        return new AbstractSet()
        {
  
           public int size()
           {
              Map children = getNode().getChildren();
              return children == null ? 0 : children.size();
           }
  
           public Iterator iterator()
           {
              Map children = getNode().getChildren();
              final Iterator i =
                    children == null
                    ? Collections.EMPTY_LIST.iterator()
                    : children.keySet().iterator();
              return new Iterator()
              {
                 Object lastKey; // for remove
  
                 public boolean hasNext()
                 {
                    return i.hasNext();
                 }
  
                 public Object next()
                 {
                    return new Entry(lastKey = i.next());
                 }
  
                 public void remove()
                 {
                    map.remove(lastKey);
                 }
              };
           }
        };
     }
  
     public Collection values()
     {
        final CachedMapImpl map = this;
  
        return new AbstractCollection()
        {
  
           public int size()
           {
              Map children = getNode().getChildren();
              return children == null ? 0 : children.size();
           }
  
           public void clear() {
              map.clear();
           }
  
           public Iterator iterator()
           {
              Map children = getNode().getChildren();
              final Iterator i =
                    children == null
                    ? Collections.EMPTY_LIST.iterator()
                    : children.keySet().iterator();
  
              return new Iterator()
              {
                 Object lastKey; // for remove
  
                 public boolean hasNext()
                 {
                    return i.hasNext();
                 }
  
                 public Object next()
                 {
                    try
                    {
                       lastKey = i.next();
                       return Null.toNullValue(cache_.getObject(AopUtil.constructFqn(getFqn(), lastKey)));
                    }
                    catch (CacheException e)
                    {
                       throw new RuntimeException(e);
                    }
                 }
  
                 public void remove()
                 {
                    Object key = lastKey;
                    if(key != null)  // convert from internal Null form to actual null if needed
                       key = Null.toNullKeyValue(key);
                    map.remove(key);
                 }
              };
           }
        };
     }
  
     public Set keySet()
     {
        final CachedMapImpl map = this;
  
        return new AbstractSet() {
  
           public int size()
           {
              Map children = getNode().getChildren();
              return children == null ? 0 : children.size();
           }
  
           public Iterator iterator()
           {
              Map children = getNode().getChildren();
              final Iterator i =
                    children == null
                    ? Collections.EMPTY_LIST.iterator()
                    : children.keySet().iterator();
  
              return new Iterator()
              {
                 Object lastKey; // for remove
  
                 public boolean hasNext()
                 {
                    return i.hasNext();
                 }
  
                 public Object next()
                 {
                    lastKey = i.next();
                    return Null.toNullKeyValue(lastKey);
  
                 }
  
                 public void remove()
                 {
                    Object key = lastKey;
                    if(key != null)  // convert from internal Null form to actual null if needed
                       key = Null.toNullKeyValue(key);
                    map.remove(key);
                 }
              };
  
           };
        };
     }
  
     public int hashCode()
     {
        int result = 0;
        for (Iterator i = entrySet().iterator(); i.hasNext();) {
           result += i.next().hashCode();
        }
        return result;
     }
  
     public boolean equals(Object object)
     {
        if (object == this)
           return true;
        if (!(object instanceof Map))
           return false;
        Map map = (Map) object;
        if (size() != map.size())
           return false;
        for (Iterator i = entrySet().iterator(); i.hasNext();) {
           Entry entry = (Entry) i.next();
           Object value = entry.getValue();
           Object key = entry.getKey();
           if (value == null) {
              if(! (map.get(key) == null && map.containsKey(key))) {
                 return false;
              }
           }
           else {
              if (map.get(key) == null
                    || !map.containsKey(key))
                 return false;
           }
        }
        return true;
     }
  
     public String toString() {
        StringBuffer buf = new StringBuffer();
        Set set = keySet();
        for(Iterator it = set.iterator(); it.hasNext();) {
           Object key = it.next();
           buf.append("[").append(key).append(", ").append(get(key)).append("]");
           if(it.hasNext()) buf.append(", ");
        }
  
        return buf.toString();
     }
  
     protected class Entry implements Map.Entry
     {
  
        Object key;
  
        public Entry(Object key)
        {
           this.key = key;
        }
  
        public Object getKey()
        {
           return Null.toNullValue(key);
        }
  
        public Object getValue()
        {
           try {
              return Null.toNullValue(cache_.getObject(AopUtil.constructFqn(getFqn(), key)));
           } catch (Exception e) {
              throw new RuntimeException(e);
           }
        }
  
        public Object setValue(Object value)
        {
           try {
              return cache_.putObject(AopUtil.constructFqn(getFqn(), key), Null.toNullObject(value));
           } catch (Exception e) {
              throw new RuntimeException(e);
           }
        }
  
        public int hashCode()
        {
           Object value = getValue();
           return ((key == null) ? 0 : key.hashCode())
                 ^ ((value == null) ? 0 : value.hashCode());
        }
  
        public boolean equals(Object obj)
        {
           if (!(obj instanceof Entry))
              return false;
           Entry entry = (Entry) obj;
           Object value = getValue();
           return (
                 key == null
                 ? entry.getKey() == null
                 : key.equals(entry.getKey()))
                 && (value == null
                 ? entry.getValue() == null
                 : value.equals(entry.getValue()));
        }
     }
  
  
  }
  
  
  
  1.1      date: 2006/10/31 08:01:15;  author: bwang;  state: Exp;JBossCache/old/src/org/jboss/cache/aop/collection/CachedSetImpl.java
  
  Index: CachedSetImpl.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.aop.collection;
  
  import org.jboss.cache.CacheException;
  import org.jboss.cache.DataNode;
  import org.jboss.cache.Fqn;
  import org.jboss.cache.aop.PojoCache;
  import org.jboss.cache.aop.util.AopUtil;
  import org.jboss.cache.aop.util.Null;
  
  import java.util.AbstractSet;
  import java.util.Collection;
  import java.util.Collections;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.Set;
  
  /**
   * Set that uses cache as a underlying backend store
   *
   * @author Ben Wang
   * @author Scott Marlow
   * @author Jussi Pyorre
   */
  public class CachedSetImpl extends AbstractSet
  {
  //   protected static final Log log_=LogFactory.getLog(CachedSetImpl.class);
  
     protected PojoCache cache_;
     protected AbstractCollectionInterceptor interceptor_;
  
     public CachedSetImpl(PojoCache cache, AbstractCollectionInterceptor interceptor)
     {
        this.cache_ = cache;
        this.interceptor_ = interceptor;
     }
  
     protected DataNode getNode()
     {
        try
        {
           return cache_._get(getFqn());
        }
        catch (Exception e)
        {
           throw new RuntimeException(e);
        }
     }
  
     protected Fqn getFqn()
     {
        // Need this since fqn can be reset.
        return interceptor_.getFqn();
     }
  
     // implementation of the java.util.Set interface
     public int size()
     {
        return keySet().size();
     }
  
     public Iterator iterator()
     {
        return new IteratorImpl(keySet());
     }
  
  
     public boolean add(Object o)
     {
        Collection keys = keySet();
  
        // This could be done with 'contains(o)' but it would invoke 'keySet()'
        // twice
        for (Iterator iter = new IteratorImpl(keys); iter.hasNext();)
           if (iter.next() == o)
              return false;
  
        // Search for an available key. This is a fast operation as the key set
        // is already available. Start with the size of the key set and go
        // up as this will be the fastest way to find an unused key. Gaps
        // in the keys don't matter, as this is a Set not a List
        int key = keys.size();
        String keyString;
        while (keys.contains((keyString = Integer.toString(key))))
           key++;
  
        try
        {
           cache_.putObject(AopUtil.constructFqn(getFqn(), keyString), Null.toNullObject(o));
           return true;
        }
        catch (CacheException e)
        {
           throw new RuntimeException(e);
        }
     }
  
     public boolean contains(Object o)
     {
        Iterator iter = iterator();
        if (o == null)
        {
           while (iter.hasNext())
           {
              if (iter.next() == null)
              {
                 return true;
              }
           }
        }
        else
        {
           while (iter.hasNext())
           {
              if (o.equals(iter.next()))
              {
                 return true;
              }
           }
        }
        return false;
     }
  
  
     public String toString()
     {
        StringBuffer buf = new StringBuffer();
        for (Iterator it = iterator(); it.hasNext();)
        {
           Object key = it.next();
           buf.append("[").append(key).append("]");
           if (it.hasNext()) buf.append(", ");
        }
  
        return buf.toString();
     }
  
     public boolean equals(Object o)
     {
        if (o == null)
           return false;
  
        if (o == this)
           return true;
  
        try
        {
           Set set = (Set) o;
  
           return (set.size() == keySet().size() && this.containsAll(set));
        }
        catch (ClassCastException e)
        {
           return false;
        }
        catch (NullPointerException unused)
        {
           return false;
        }
     }
  
     private Collection keySet()
     {
        DataNode node = getNode();
  
        if (node != null)
        {
           Map children = node.getChildren();
  
           if (children != null)
           {
              return children.keySet();
           }
        }
  
        return Collections.EMPTY_SET;
     }
  
     private class IteratorImpl implements Iterator
     {
        private Iterator iterator;
  
        private Object key;
  
        private IteratorImpl(Collection keys)
        {
           iterator = keys.iterator();
        }
  
        public boolean hasNext()
        {
           return iterator.hasNext();
        }
  
        public Object next()
        {
           // (Brian) Removed Jussi's call to iterator.hasNext() followed by
           // an NSOE if false.  That approach was slightly more efficient if
           // hasNext() were false, but in the vast majority of cases iterators
           // are used correctly and it was an extra step.
  
           this.key = iterator.next();
  
           try
           {
              return Null.toNullValue(cache_.getObject(AopUtil.constructFqn(getFqn(), this.key)));
           }
           catch (CacheException e)
           {
              throw new RuntimeException(e);
           }
        }
  
        public void remove() throws IllegalStateException
        {
           if (this.key == null)
           {
              throw new IllegalStateException();
           }
  
           try
           {
              cache_.removeObject(AopUtil.constructFqn(getFqn(), this.key));
           }
           catch (CacheException e)
           {
              throw new RuntimeException(e);
           }
        }
  
     }
  }
  
  
  1.1      date: 2006/10/31 08:01:15;  author: bwang;  state: Exp;JBossCache/old/src/org/jboss/cache/aop/collection/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.aop.collection;
  
  import org.jboss.cache.Fqn;
  import org.jboss.cache.aop.PojoCache;
  
  import java.util.*;
  
  /**
   * Set interceptor that delegates underlying impl.
   *
   * @author Ben Wang
   */
  public class CachedSetInterceptor extends AbstractCollectionInterceptor
  {
  //   protected static final Log log_=LogFactory.getLog(CachedSetInterceptor.class);
  
     protected Map methodMap_;
     protected static final Map managedMethods_ =
           CollectionInterceptorUtil.getManagedMethods(Set.class);
     protected Set cacheImpl_;
     protected Set current_;
     protected Set inMemImpl_;
  
     public CachedSetInterceptor(PojoCache cache, Fqn fqn, Class clazz, Set obj)
     {
        this.fqn_ = fqn;
        methodMap_ = CollectionInterceptorUtil.getMethodMap(clazz);
        cacheImpl_ = new CachedSetImpl(cache, this);
        inMemImpl_ = obj;
        current_ = cacheImpl_;
     }
  
     /**
      * 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_;
     }
  
     protected 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_;
     }
  
     protected 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: 2006/10/31 08:01:15;  author: bwang;  state: Exp;JBossCache/old/src/org/jboss/cache/aop/collection/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.aop.collection;
  
  import org.jboss.cache.Fqn;
  import org.jboss.cache.aop.PojoCache;
  
  import java.util.*;
  
  /**
   * List ineterceptor that delegates to underlying implementation.
   *
   * @author Ben Wang
   */
  
  public class CachedListInterceptor extends AbstractCollectionInterceptor
  {
  
  //   protected static final Log log_ = LogFactory.getLog(CachedListInterceptor.class);
     protected static final Map managedMethods_ =
           CollectionInterceptorUtil.getManagedMethods(List.class);
  
     protected Map methodMap_;
     // This is the copy in cache store when it is attached.
     protected List cacheImpl_;
     // This is the copy in-memory when the state is detached.
     protected List inMemImpl_;
     // Whichever is used now.
     protected List current_;
  
     public CachedListInterceptor(PojoCache 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_;
     }
  
     /**
      * 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_;
     }
  
     protected 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_;
     }
  
     protected 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: 2006/10/31 08:01:15;  author: bwang;  state: Exp;JBossCache/old/src/org/jboss/cache/aop/collection/CachedListImpl.java
  
  Index: CachedListImpl.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.aop.collection;
  
  import org.jboss.cache.Fqn;
  import org.jboss.cache.DataNode;
  import org.jboss.cache.aop.PojoCache;
  import org.jboss.cache.aop.util.AopUtil;
  import org.jboss.cache.aop.util.Null;
  
  import java.util.*;
  
  /**
   * List implementation that uses cache as a backend store.
   *
   * @author Ben Wang
   * @author Scott Marlow
   */
  
  public class CachedListImpl extends CachedListAbstract implements List
  {
  
  //   protected static final Log log_ = LogFactory.getLog(CachedListImpl.class);
     protected PojoCache cache_;
     protected AbstractCollectionInterceptor interceptor_;
  
     public CachedListImpl(PojoCache cache, AbstractCollectionInterceptor interceptor)
     {
        cache_ = cache;
        interceptor_ = interceptor;
     }
  
     protected Fqn getFqn()
     {
        return interceptor_.getFqn();
     }
  
     // implementation of the java.util.List interface
     protected DataNode getNode()
     {
        try {
           return cache_._get(getFqn());
        } catch (Exception e) {
           throw new RuntimeException(e);
        }
     }
  
     public Object get(int index)
     {
        checkIndex(index);
        try {
           return Null.toNullValue(cache_.getObject(AopUtil.constructFqn(getFqn(), Integer.toString(index))));
        } catch (Exception e) {
           throw new RuntimeException(e);
        }
     }
  
     private void checkIndex(int i) {
        // TODO This is too expensive now to check it everytime from the cache (potentially twice).
        // It is showing up in the JProfiler. So I am disabling it now.
        return;
  /*
        if(size() == 0) return; // No need to check here.
        if( i < 0 || i >= size() ) {
           throw new IndexOutOfBoundsException("Index out of bound at CachedListImpl(). Index is " +i
           + " but size is " +size());
        } */
     }
  
     public int size()
     {
        DataNode node = getNode();
        if(node == null) {
           return 0;
        }
  
        Map children = node.getChildren();
        return children == null ? 0 : children.size();
     }
  
     public Object set(int index, Object element)
     {
        try {
           if(index != 0)
              checkIndex(index-1); // Since index can be size().
           return Null.toNullValue(cache_.putObject(AopUtil.constructFqn(getFqn(), Integer.toString(index)), Null.toNullObject(element)));
        } catch (Exception e) {
           throw new RuntimeException(e);
        }
     }
  
     public void add(int index, Object element)
     {
        try {
           if(index != 0)
              checkIndex(index-1); // Since index can be size().
           for (int i = size(); i > index; i--) {
              Object obj = cache_.removeObject(AopUtil.constructFqn(getFqn(), Integer.toString(i - 1)));
              cache_.putObject(AopUtil.constructFqn(getFqn(), Integer.toString(i)), obj);
           }
           cache_.putObject(AopUtil.constructFqn(getFqn(), Integer.toString(index)), Null.toNullObject(element));
        } catch (Exception e) {
           throw new RuntimeException(e);
        }
     }
  
     public int indexOf(Object o)
     {
        int size = size();
        if(o == null) {
           for(int i=0; i < size; i++) {
              if(null == get(i))
                 return i;
           }
        }
        else {
           for(int i=0; i < size; i++) {
              if(o.equals(get(i)))
                 return i;
           }
        }
        return -1;
     }
  
     public int lastIndexOf(Object o)
     {
        if(o == null) {
           for(int i=size() - 1 ; i >=0 ; i--) {
              if(null == get(i))
                 return i;
           }
        }
        else {
           for(int i=size() - 1 ; i >=0 ; i--) {
              if(o.equals(get(i)))
                 return i;
           }
        }
        return -1;
     }
  
     public Object remove(int index)
     {
        try {
           checkIndex(index);
           // Object result = cache.removeObject(((Fqn) fqn.clone()).add(new Integer(index)));
           int size = size();
           Object result = Null.toNullValue(cache_.removeObject(AopUtil.constructFqn(getFqn(), Integer.toString(index))));
           if( size == (index +1)) {
              return result; // We are the last one.
           }
           for (int i = index; i < size-1; i++) {
              Object obj = cache_.removeObject(AopUtil.constructFqn(getFqn(), Integer.toString(i + 1)));
              cache_.putObject(AopUtil.constructFqn(getFqn(), Integer.toString(i)), obj);
           }
           return result;
        } catch (Exception e) {
           throw new RuntimeException(e);
        }
     }
  
     public Iterator iterator()
     {
        // TODO: check for concurrent modification
        return new Iterator()
        {
           // Need to share this
           protected int current = -1;
           protected int size = size();
  
           public boolean hasNext()
           {
              if(size ==0) return false;
              if(current > size)
                 throw new NoSuchElementException("CachedSetImpl.iterator.hasNext(). " +
                         " Cursor position " + current + " is greater than the size " +size());
  
              return current < size-1;
           }
  
           public Object next()
           {
              if(current == size)
                 throw new NoSuchElementException("CachedSetImpl.iterator.next(). " +
                         " Cursor position " + current + " is greater than the size " +size());
  
              try {
                 return Null.toNullValue(cache_.getObject(AopUtil.constructFqn(getFqn(), Integer.toString(++current))));
              } catch (Exception e) {
                 throw new RuntimeException(e);
              }
           }
  
           public void remove()
           {
              // TODO Need optimization here since set does not care about index
              try {
                 if(size ==0) return;
                 if(current == size)
                    throw new IllegalStateException("CachedSetImpl.iterator.remove(). " +
                            " Cursor position " + current + " is greater than the size " +size);
                 if (current < (size-1)) {
                    // Need to reshuffle the items.
                    Object last = cache_.removeObject(AopUtil.constructFqn(getFqn(), Integer.toString(current)));
                    for(int i = current+1 ; i < size; i++) {
                       last = cache_.removeObject(AopUtil.constructFqn(getFqn(), Integer.toString(i)));
                       cache_.putObject(AopUtil.constructFqn(getFqn(), Integer.toString(i-1)), last);
                    }
                 } else { // we are the last index.
                    // Need to move back the cursor.
                    cache_.removeObject(AopUtil.constructFqn(getFqn(), Integer.toString(current)));
                 }
                 current--;
                 size--;
              } catch (Exception e) {
                 throw new RuntimeException(e);
              }
           }
        };
     }
  
     public List subList(int fromIndex, int toIndex)
     {
        if( fromIndex < 0)
           throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
        if( toIndex > size())
           throw new IndexOutOfBoundsException("toIndex = " + toIndex + " but size() =" + size());
        if( fromIndex > toIndex)
           throw new IllegalArgumentException("fromIndex ("+fromIndex+") must be less than toIndex("+toIndex+")");
        if(fromIndex == toIndex)            // request for empty list?
           return new LinkedList();
        return new MyCachedSubListImpl(this, fromIndex, toIndex);
     }
  
     public ListIterator listIterator()
     {
        return new MyListIterator(this,0);
     }
  
     public ListIterator listIterator(int index)
     {
        return new MyListIterator(this, index);
     }
  
     protected static class MyListIterator implements ListIterator {
        protected int index = 0;
        protected List list_;
  
        public MyListIterator(List list, int index) {
           list_ = list;
           if(index < 0 || index >= list_.size()) {
              throw new IndexOutOfBoundsException("CachedListImpl: MyListIterator construction. " +
                    " Index is out of bound : " +index);
           }
           this.index = index;
        }
  
        public int nextIndex()
        {
           return index;
        }
  
        public int previousIndex()
        {
           return index-1;
        }
  
        public void remove()
        {
  
           try {
              int size = list_.size();
              if(size == 0) return;
              if(previousIndex() == size)
                 throw new IllegalStateException("CachedSetImpl.MyListIterator.remove(). " +
                         " Cursor position " + index + " is greater than the size " +size);
              if (previousIndex() < (size)) {
                 list_.remove(previousIndex());
                 index--;
              }
           } catch (Exception e) {
              throw new RuntimeException(e);
           }
  
        }
  
        public boolean hasNext()
        {
           return (index != list_.size() - 1);
        }
  
        public boolean hasPrevious()
        {
           return (index != 0);
        }
  
        public Object next()
        {
           if( index == list_.size() )
              throw new NoSuchElementException();
  
           index++;
           return list_.get(index-1);  // pass zero relative index
        }
  
        public Object previous()
        {
           if( index == 0 )
              throw new NoSuchElementException();
  
           index--;
           return list_.get(index);
        }
  
        public void add(Object o)
        {
           int size = list_.size();
           if(size == 0) return;
  
           if(previousIndex() == size)
              throw new IllegalStateException("CachedSetImpl.MyListIterator.add(). " +
                      " Cursor position " + index + " is greater than the size " +size);
           if (previousIndex() < (size)) {
              list_.add(previousIndex(), o);
           }
        }
  
        public void set(Object o)
        {
           int size = list_.size();
           if(size == 0) return;
  
           if(previousIndex() == size)
              throw new IllegalStateException("CachedSetImpl.MyListIterator.set(). " +
                      " Cursor position " + index + " is greater than the size " +size);
           if (previousIndex() < (size)) {
              list_.set(previousIndex(), o);
           }
        }
     }
  
     static public class MyCachedSubListImpl extends CachedListAbstract implements List {
  
        private List backStore_;
        private int fromIndex_;
        private int toIndex_;
  
        MyCachedSubListImpl(List backStore, int fromIndex, int toIndex) {
           backStore_ = backStore;
           fromIndex_ = fromIndex;
           toIndex_ = toIndex;
        }
  
        public int size()
        {
           int size = backStore_.size();
           if(size > toIndex_)
              size = toIndex_;
           size -= fromIndex_;     // subtract number of items ignored at the start of list
           return size;
        }
  
        public Iterator iterator()
        {
           // TODO: check for concurrent modification
           return new Iterator()
           {
              protected int current = -1;
              protected Iterator iter_ = initializeIter();
  
              private Iterator initializeIter() {
                 Iterator iter = backStore_.iterator();
                 for(int looper = 0; looper < fromIndex_;looper ++)
                    if(iter.hasNext())      // skip past to where we need to start from
                       iter.next();
                 return iter;
              }
  
              public boolean hasNext()
              {
                 int size = size();
                 if(size ==0) return false;
                 if(current > size)
                    throw new IllegalStateException("CachedSetImpl.MyCachedSubListImpl.iterator.hasNext(). " +
                            " Cursor position " + current + " is greater than the size " +size());
  
                 return current < size()-1;
              }
  
              public Object next()
              {
                 if(current == size())
                    throw new IllegalStateException("CachedSetImpl.MyCachedSubListImpl.iterator.next(). " +
                            " Cursor position " + current + " is greater than the size " +size());
                 current++;
                 try {
                    return iter_.next();
                 } catch (Exception e) {
                    throw new RuntimeException(e);
                 }
              }
  
              public void remove()
              {
                 iter_.remove();
                 current--;
              }
           };
  
        }
  
        public Object get(int index)
        {
           checkIndex(index);
           return backStore_.get(index + fromIndex_);
        }
  
        public Object set(int index, Object element)
        {
           checkIndex(index);
           return backStore_.set(index + fromIndex_, element);
        }
  
        public void add(int index, Object element)
        {
           backStore_.add(index + fromIndex_, element);
        }
  
        public Object remove(int index)
        {
           return backStore_.remove(index + fromIndex_);
        }
  
        public int indexOf(Object o)
        {
           int index = backStore_.indexOf(o);
           if(index < fromIndex_ || index >= toIndex_)
              index = -1;
           else
              index -= fromIndex_;    // convert to be relative to our from/to range
           return index;
        }
  
        public int lastIndexOf(Object o)
        {
           int index = backStore_.lastIndexOf(o);
           if(index < fromIndex_ || index >= toIndex_)
              index = -1;
           else
              index -= fromIndex_;    // convert to be relative to our from/to range
           return index;
        }
  
        public ListIterator listIterator()
        {
           return new MyListIterator(this,0);
        }
  
        public ListIterator listIterator(int index)
        {
           return new MyListIterator(this,index);
        }
  
        public List subList(int fromIndex, int toIndex)
        {
           if( fromIndex < 0)
              throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
           if( toIndex > size())
              throw new IndexOutOfBoundsException("toIndex = " + toIndex + " but size() =" + size());
           if( fromIndex > toIndex)
              throw new IllegalArgumentException("fromIndex ("+fromIndex+") must be less than toIndex("+toIndex+")");
           if(fromIndex == toIndex)            // request for empty list?
              return new LinkedList();
           return new MyCachedSubListImpl(this, fromIndex, toIndex);
        }
  
        private void checkIndex(int i) {
           if(size() == 0) return; // No need to check here.
           if( i < 0 || i >= size() ) {
              throw new IndexOutOfBoundsException("Index out of bound at CachedListImpl(). Index is " +i
              + " but size is " +size());
           }
        }
  
     }
  
  }
  
  
  
  1.1      date: 2006/10/31 08:01:15;  author: bwang;  state: Exp;JBossCache/old/src/org/jboss/cache/aop/collection/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.aop.collection;
  
  import org.jboss.cache.Fqn;
  import org.jboss.cache.aop.PojoCache;
  
  import java.util.*;
  
  /**
   * Map interceptor that delegates to the underlying impl.
   *
   * @author Ben Wang
   */
  public class CachedMapInterceptor extends AbstractCollectionInterceptor
  {
  
  //   protected static final Log log_ = LogFactory.getLog(CachedMapInterceptor.class);
     protected static final Map managedMethods_ =
           CollectionInterceptorUtil.getManagedMethods(Map.class);
     protected Map methodMap_;
     protected Map cacheImpl_;
     protected Map inMemImpl_;
     protected Map current_;
  
     protected CachedMapInterceptor(PojoCache cache, Fqn fqn, Class clazz, Map obj)
     {
        this.fqn_ = fqn;
        methodMap_ = CollectionInterceptorUtil.getMethodMap(clazz);
        cacheImpl_ = new CachedMapImpl(cache, this);
        inMemImpl_ = obj;
        current_ = cacheImpl_;
     }
  
     /**
      * 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_;
     }
  
     protected void toCache()
     {
        if(inMemImpl_ == null)
           throw new IllegalStateException("CachedMapInterceptor.toCache(). inMemImpl is null.");
  
        Iterator it = inMemImpl_.keySet().iterator();
        while(it.hasNext())
        {
           Object key = it.next();
           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_;
     }
  
     protected 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: 2006/10/31 08:01:15;  author: bwang;  state: Exp;JBossCache/old/src/org/jboss/cache/aop/collection/CachedListAbstract.java
  
  Index: CachedListAbstract.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.aop.collection;
  
  import java.util.List;
  import java.util.Collection;
  import java.util.Iterator;
  
  /**
   * Abstract class for CachedList
   *
   * @author Scott Marlow
   */
  
  public abstract class CachedListAbstract implements List {
     public void clear()
     {
        // TODO Can use optimization here
        for(int i=size()-1; i >= 0; i--) {
           remove(i);
        }
     }
  
     public boolean isEmpty()
     {
        return size() == 0;
     }
  
     public Object[] toArray()
     {
        Object[] objs = new Object[size()];
        for(int i=0; i < size(); i++) {
           objs[i] = get(i);
        }
        return objs;
     }
  
     public Object[] toArray(Object a[])
     {
        int actualLength = size();
        if(actualLength > a.length)  // need to allocate a larger array
           a = new Object[actualLength];
        int looper;
        for( looper =0; looper < actualLength; looper++) {
           a[looper] = get(looper);
        }
        for( ; looper < a.length;looper ++)
           a[looper] = null; // if the array is larger than needed, set extra slots to null
        return a;
     }
  
     public boolean add(Object o)
     {
        add(size(), o);
        return true;
     }
  
     public boolean contains(Object o)
     {
        if (indexOf(o) != -1) return true;
        return false;
     }
  
     public boolean remove(Object o)
     {
        int i = indexOf(o);
        if(i == -1)
           return false;
  
        remove(i);
        return true;
     }
  
     public boolean addAll(int index, Collection c)
     {
        if(c.size() == 0)
           return false;
        Iterator i = c.iterator();
        // should optimize this
        while(i.hasNext()) {
           Object o = i.next();
           add(index++,o);
        }
        return true;
     }
  
     public boolean addAll(Collection c)
     {
        if(c.size() == 0)
           return false;
        Iterator i = c.iterator();
        while(i.hasNext()) {
           Object o = i.next();
           add(o);
        }
        return true;
     }
  
     public boolean containsAll(Collection c)
     {
        Iterator iter = c.iterator();
        while (iter.hasNext()) {
           if(!contains(iter.next())) {
              return false;
           }
        }
        return true;
     }
  
     public boolean removeAll(Collection c)
     {
        Iterator i = c.iterator();
        while(i.hasNext()) {
           Object o = i.next();
           remove(o);
        }
        return true;
     }
  
     public int hashCode()
     {
        int result = 0;
        for (int i =0; i < size(); i++) {
           Object o = get(i);
           result += (o == null ? 0 : o.hashCode());
        }
        return result;
     }
  
     public boolean equals(Object object)
     {
        if (object == this)
           return true;
        if (!(object instanceof List))
           return false;
        List list = (List) object;
        if (size() != list.size())
           return false;
        for (int i=0; i < list.size(); i++) {
           Object value = list.get(i);
           if( !contains(value) )
              return false;
        }
        return true;
     }
  
     public String toString() {
        StringBuffer buf = new StringBuffer();
        int size = size();
        for (int i =0; i < size; i++) {
           Object key = get(i);
           buf.append("[").append(key).append("]");
           if(i <= size) buf.append(", ");
        }
  
        return buf.toString();
     }
  
     public boolean retainAll(Collection c)
     {
        boolean changedAnything = false;
        Iterator iter = iterator();
        while(iter.hasNext()) {
           if(! c.contains(iter.next())) {
              iter.remove();
              changedAnything = true;
           }
        }
        return changedAnything;
     }
  }
  
  
  
  1.1      date: 2006/10/31 08:01:15;  author: bwang;  state: Exp;JBossCache/old/src/org/jboss/cache/aop/collection/CollectionInterceptorUtil.java
  
  Index: CollectionInterceptorUtil.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.aop.collection;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.jboss.aop.InstanceAdvisor;
  import org.jboss.aop.advice.Interceptor;
  import org.jboss.aop.joinpoint.Invocation;
  import org.jboss.aop.joinpoint.MethodInvocation;
  import org.jboss.aop.proxy.ClassProxy;
  import org.jboss.aop.proxy.ClassProxyFactory;
  import org.jboss.aop.util.MethodHashing;
  import org.jboss.cache.Fqn;
  import org.jboss.cache.aop.PojoCache;
  import org.jboss.cache.aop.util.AopUtil;
  
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import java.util.HashMap;
  import java.util.Map;
  import java.util.List;
  import java.util.Set;
  
  /**
   * CollectionInterceptorUtil contains helper methods for the interceptors of
   * the different collection types.
   *
   * @author <a href="mailto:harald at gliebe.de">Harald Gliebe</a>
   * @author Ben Wang
   */
  public class CollectionInterceptorUtil
  {
     static Log log=LogFactory.getLog(CollectionInterceptorUtil.class.getName());
  
     public static ClassProxy createProxy(Class clazz, AbstractCollectionInterceptor interceptor)
           throws Exception
     {
        ClassProxy result = ClassProxyFactory.newInstance(clazz);
        InstanceAdvisor advisor = result._getInstanceAdvisor();
        advisor.appendInterceptor(interceptor);
        return result;
     }
  
     public static ClassProxy createMapProxy(PojoCache cache, Fqn fqn, Class clazz, Map obj) throws Exception {
        return CollectionInterceptorUtil.createProxy(clazz, new CachedMapInterceptor(cache, fqn, clazz, obj));
     }
  
     public static ClassProxy createListProxy(PojoCache cache, Fqn fqn, Class clazz, List obj) throws Exception {
        return CollectionInterceptorUtil.createProxy(clazz, new CachedListInterceptor(cache, fqn, clazz, obj));
     }
  
     public static ClassProxy createSetProxy(PojoCache cache, Fqn fqn, Class clazz, Set obj) throws Exception {
        return CollectionInterceptorUtil.createProxy(clazz, new CachedSetInterceptor(cache, fqn, clazz, obj));
     }
  
     public static AbstractCollectionInterceptor getInterceptor(ClassProxy proxy)
     {
        InstanceAdvisor advisor = proxy._getInstanceAdvisor();
        return (AbstractCollectionInterceptor)AopUtil.findCollectionInterceptor(advisor);
     }
  
     public static Map getMethodMap(Class clazz)
     {
        Map result = ClassProxyFactory.getMethodMap(clazz.getName());
        if (result == null) {
           try {
              ClassProxyFactory.newInstance(clazz);
           } catch (Exception e) {
              throw new RuntimeException(e);
           }
           result = ClassProxyFactory.getMethodMap(clazz.getName());
        }
        return result;
     }
  
     public static Map getManagedMethods(Class clazz)
     {
        Method tostring = null;
        try {
           tostring = Object.class.getDeclaredMethod("toString", new Class[0]);
        } catch (NoSuchMethodException e) {
           e.printStackTrace();
           throw new RuntimeException("getManagedMathods: " +e);
        }
  
        Map managedMethods = new HashMap();
        try {
           Method[] methods = clazz.getDeclaredMethods();
           for (int i = 0; i < methods.length; i++) {
              long hash = MethodHashing.methodHash(methods[i]);
              managedMethods.put(new Long(hash), methods[i]);
           }
           // Add toString to ManagedMethod
           long hash = MethodHashing.methodHash(tostring);
           managedMethods.put(new Long(hash), tostring);
        } catch (Exception ignored) {
           ignored.printStackTrace();
        }
        return managedMethods;
     }
  
     public static Object invoke(Invocation invocation,
                                 Object interceptor,
                                 Map methodMap,
                                 Map managedMethods)
           throws Throwable
     {
  
        try {
           if (invocation instanceof MethodInvocation) {
              MethodInvocation methodInvocation = (MethodInvocation) invocation;
              Long methodHash = new Long(methodInvocation.getMethodHash());
              Method method = (Method) managedMethods.get(methodHash);
              if (log.isDebugEnabled() && method != null) {
                 log.trace("invoke(): method intercepted " + method.getName());
              }
              Object[] args = methodInvocation.getArguments();
              if (method != null) {
                 return method.invoke(interceptor, args);
              } else {
                 method = methodInvocation.getMethod();
                 if (method == null) {
                    method = (Method) methodMap.get(methodHash);
                 }
  
                 log.trace("invke(): invoke non-managed method: " +method.toString());
                 Object target = methodInvocation.getTargetObject();
                 if(target == null) {
                    throw new RuntimeException("CollectionInterceptorUtil.invoke(): targetObject is null." +
                          " Can't invoke " +method.toString());
                 }
                 return method.invoke(target, args);
     //            return method.invoke(interceptor, args);
              }
           }
        }
        catch(InvocationTargetException e) {
           if(e.getCause() != null)
              throw e.getCause();
           else if(e.getTargetException() != null)
              throw e.getTargetException();
           throw e;
        }
  
        return invocation.invokeNext();
     }
  
  }
  
  
  



More information about the jboss-cvs-commits mailing list