[jbosscache-commits] JBoss Cache SVN: r5947 - in pojo/trunk: src/main/java/org/jboss/cache/pojo/collection and 5 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Tue Jun 3 15:19:04 EDT 2008


Author: jason.greene at jboss.com
Date: 2008-06-03 15:19:03 -0400 (Tue, 03 Jun 2008)
New Revision: 5947

Added:
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ArrayInterceptable.java
Modified:
   pojo/trunk/pom.xml
   pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedObjectArray.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/interceptors/dynamic/CacheFieldInterceptor.java
   pojo/trunk/src/main/resources/META-INF/pojocache-aop.xml
   pojo/trunk/src/test/java/org/jboss/cache/pojo/ArrayTest.java
   pojo/trunk/src/test/java/org/jboss/cache/pojo/test/ArrayObject.java
Log:
Only use array interception handlers on types that can be intercepted
Allow array interception to be disabled
Add a multi-dim test
Update to use snapshot versions of projects (requires local building atm until a release)


Modified: pojo/trunk/pom.xml
===================================================================
--- pojo/trunk/pom.xml	2008-06-03 16:22:30 UTC (rev 5946)
+++ pojo/trunk/pom.xml	2008-06-03 19:19:03 UTC (rev 5947)
@@ -6,7 +6,7 @@
   <properties>
     <jbosscache-pojo-version>2.2.0-SNAPSHOT</jbosscache-pojo-version>
     <jbosscache-core-version>2.1.0-SNAPSHOT</jbosscache-core-version>
-    <jboss.aop.version>2.0.0.CR3</jboss.aop.version>
+    <jboss.aop.version>2.0.0-SNAPSHOT</jboss.aop.version>
   </properties>
   <parent>
     <groupId>org.jboss.cache</groupId>
@@ -125,7 +125,7 @@
       <plugin>
         <groupId>org.jboss.maven.plugins</groupId>
         <artifactId>maven-jbossaop-plugin</artifactId>
-        <version>2.0.0.beta1</version>
+        <version>1.0.0-SNAPSHOT</version>
         <!-- HACK: AOP project and plugin has broken deps -->
         <dependencies>    
           <dependency>

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedObjectArray.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedObjectArray.java	2008-06-03 16:22:30 UTC (rev 5946)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedObjectArray.java	2008-06-03 19:19:03 UTC (rev 5947)
@@ -22,6 +22,7 @@
 package org.jboss.cache.pojo.collection;
 
 import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.impl.ArrayInterceptable;
 import org.jboss.cache.pojo.impl.PojoCacheImpl;
 import org.jboss.cache.pojo.util.AopUtil;
 import org.jboss.cache.pojo.util.Null;
@@ -34,31 +35,35 @@
  */
 public class CachedObjectArray extends CachedArray
 {
+   // Used to indicate that the source of the element is an interceptable array
+   // so that multi-dimensional arrays can be handled properly
+   private static ArrayInterceptable arraySource = new ArrayInterceptable() {};
+
    protected CachedObjectArray(Fqn<?> fqn, Class<?> type, PojoCacheImpl cache)
    {
       super(fqn, type, cache);
    }
- 
+
    public void set(int index, Object element)
    {
       Fqn<?> fqn = AopUtil.constructFqn(this.fqn, IntegerCache.toString(index));
 
-      cache.attach(fqn, Null.toNullObject(element));
+      cache.attach(fqn, Null.toNullObject(element), null, arraySource);
    }
-   
+
    public Object get(int index)
    {
       Fqn<?> fqn = AopUtil.constructFqn(this.fqn, IntegerCache.toString(index));
-      
-      return Null.toNullValue(cache.find(fqn));
+
+      return Null.toNullValue(cache.getObject(fqn, null, arraySource));
    }
-   
+
    public void destroy()
    {
       // Detach all children to ensure reference cleanup
       for (int i = 0; i < length(); i++)
-         cache.detach(AopUtil.constructFqn(this.fqn, IntegerCache.toString(i)));
-      
+         cache.detach(AopUtil.constructFqn(this.fqn, IntegerCache.toString(i)), null, arraySource);
+
       super.destroy();
    }
 }

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java	2008-06-03 16:22:30 UTC (rev 5946)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java	2008-06-03 19:19:03 UTC (rev 5947)
@@ -65,7 +65,7 @@
       cache_ = pCache_.getCache();
       util_ = util;
    }
-   
+
    @Override
    protected Fqn<?> getFqn(Object obj)
    {
@@ -74,14 +74,14 @@
          InstanceAdvisor advisor = ((Advised) obj)._getInstanceAdvisor();
          if (advisor == null)
             throw new PojoCacheException("_putObject(): InstanceAdvisor is null for: " + obj);
-      
+
          // Step Check for cross references
          BaseInterceptor interceptor = AopUtil.findCacheInterceptor(advisor);
          if (interceptor != null)
             return interceptor.getFqn();
       }
-      
-      return null;        
+
+      return null;
    }
 
    @Override
@@ -89,21 +89,21 @@
    {
       CachedType type = pCache_.getCachedType(clazz);
       Object obj = Instantiator.newInstance(clazz);
-      
+
       // Eager initialize final fields, since these may not be intercepted
-      
+
       try
       {
          for (FieldPersistentReference ref : type.getFinalFields())
          {
             Field field = ref.getField();
             Object result;
-         
+
             if (CachedType.isSimpleAttribute(field))
                result = cache_.get(fqn, field.getName());
             else
-               result = pCache_.getObject(fqn, field.getName());
-         
+               result = pCache_.getObject(fqn, field.getName(), obj);
+
             field.set(obj, result);
          }
       }
@@ -187,12 +187,12 @@
          Field field = (Field) o;
          Object value = subPojoMap.get(field);
          if (value == null) continue; // really no need to map the POJO.
-         pCache_.attach(fqn, value, field.getName());
+         pCache_.attach(fqn, value, field.getName(), obj);
          // If it is Collection classes, we replace it with dynamic proxy.
          // But we will have to ignore it if value is null
          if (value instanceof Map || value instanceof List || value instanceof Set)
          {
-            Object newValue = pCache_.getObject(fqn, field.getName());
+            Object newValue = pCache_.getObject(fqn, field.getName(), obj);
             util_.inMemorySubstitution(obj, field, newValue);
          }
       }
@@ -216,7 +216,7 @@
 
          if (! CachedType.isSimpleAttribute(field))
          {
-            value = pCache_.detach(fqn, field.getName());
+            value = pCache_.detach(fqn, field.getName(), result);
 
             // Check for Collection. If it is, we need to reset the original reference.
             if ((value instanceof Map || value instanceof List || value instanceof Set))

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java	2008-06-03 16:22:30 UTC (rev 5946)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java	2008-06-03 19:19:03 UTC (rev 5947)
@@ -33,19 +33,19 @@
 public class ArrayHandler extends AbstractHandler
 {
    private final PojoCacheImpl cache;
-   
+
    ArrayHandler(PojoCacheImpl cache)
    {
       this.cache = cache;
    }
-   
+
    protected Fqn<?> getFqn(Object array)
    {
       CachedArray cached = CachedArrayRegistry.lookup(array);
       return cached != null ? cached.getFqn() : null;
    }
-   
-   
+
+
    protected void put(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj)
    {
       // Always initialize the ref count so that we can mark this as an AopNode.
@@ -53,36 +53,35 @@
       pojoInstance.set(obj);
       pojoInstance.setPojoClass(obj.getClass());
       cache.getCache().put(fqn, PojoInstance.KEY, pojoInstance);
-      
+
       CachedArray cached = CachedArray.create(fqn, cache, obj);
       CachedArrayRegistry.register(obj, cached);
    }
-   
+
    @Override
    protected Object get(Fqn<?> fqn, Class<?> clazz, PojoInstance pojo)
    {
       CachedArray cached = CachedArray.load(fqn, cache, clazz);
       Object array = cached.toArray();
       CachedArrayRegistry.register(array, cached);
-      
+
       return array;
    }
-   
+
    @Override
    protected Object remove(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj)
    {
       CachedArray cached = CachedArrayRegistry.unregister(obj);
       if (cached != null)
          cached.destroy();
-      
+
       return obj;
    }
 
    @Override
    protected boolean handles(Class<?> clazz)
    {
-      return false;
-      //return clazz.isArray();
+      return clazz.isArray();
    }
 
 }

Added: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ArrayInterceptable.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ArrayInterceptable.java	                        (rev 0)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ArrayInterceptable.java	2008-06-03 19:19:03 UTC (rev 5947)
@@ -0,0 +1,33 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.cache.pojo.impl;
+
+/**
+ * Internal interface that indicates that a type's fields
+ * can be included for array interception.
+ *
+ * @author Jason T. Greene
+ */
+public interface ArrayInterceptable
+{
+
+}

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java	2008-06-03 16:22:30 UTC (rev 5946)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java	2008-06-03 19:19:03 UTC (rev 5947)
@@ -77,7 +77,7 @@
       return bulkRemove_.get();
    }
 
-   public Object getObject(Fqn fqn, String field) throws CacheException
+   public Object getObject(Fqn fqn, String field, Object source) throws CacheException
    {
       // TODO Must we really to couple with BR? JBCACHE-669
       Object pojo = internal_.getPojo(fqn, field);
@@ -101,7 +101,7 @@
          if (region != null && region.getClassLoader() != null)
             Thread.currentThread().setContextClassLoader(region.getClassLoader());
 
-         return getObjectInternal(fqn, field);
+         return getObjectInternal(fqn, field, source);
       }
       finally
       {
@@ -112,11 +112,12 @@
    /**
     * Note that caller of this method will take care of synchronization within the <code>fqn</code> sub-tree.
     */
-   public Object putObject(Fqn fqn, Object obj, String field) throws CacheException
+   public Object putObject(Fqn fqn, Object obj, String field, Object source) throws CacheException
    {
       // Skip some un-necessary update if obj is the same class as the old one
       Object oldValue = internal_.getPojo(fqn, field);
-      if (oldValue == obj && skipDuplicateAttach(obj))
+      boolean allowArray = source instanceof ArrayInterceptable;
+      if (oldValue == obj && skipDuplicateAttach(obj, allowArray))
       {
          if (log.isDebugEnabled())
          {
@@ -127,14 +128,14 @@
 
       // remove old value before overwriting it. This is necessary to detach any interceptor.
       // TODO Or can we simply walk thru that somewhere? Well, there is also implication of Collection though
-      pojoCache.detach(fqn, field);
+      pojoCache.detach(fqn, field, source);
 
       if (obj == null)
          return oldValue;// we are done
 
-      AbstractHandler handler = getHandler(obj.getClass());
+      AbstractHandler handler = getHandler(obj.getClass(), allowArray);
       Fqn<?> internalFqn = handler.getFqn(obj);
-      
+
       if (internalFqn != null)
       {
          graphHandler_.put(internalFqn, fqn, obj);
@@ -142,44 +143,44 @@
       else
       {
          internalFqn = createInternalFqn(fqn, obj);
-         if (log.isDebugEnabled())        
+         if (log.isDebugEnabled())
             log.debug("attach(): id: " + fqn + " will store the pojo in the internal area: " + internalFqn);
-        
+
          handler.put(internalFqn, fqn, obj);
 
          // Used by notification sub-system
          cache.put(internalFqn, InternalConstant.POJOCACHE_STATUS, "ATTACHED");
       }
-      
+
       setPojoReference(fqn, obj, field, internalFqn);
 
       return oldValue;
    }
-   
-   private boolean skipDuplicateAttach(Object obj)
+
+   private boolean skipDuplicateAttach(Object obj, boolean allowArray)
    {
-      return obj == null || getHandler(obj.getClass()) != serializableHandler_;
+      return obj == null || getHandler(obj.getClass(), allowArray) != serializableHandler_;
    }
-   
-   private AbstractHandler getHandler(Class<?> clazz)
+
+   private AbstractHandler getHandler(Class<?> clazz, boolean allowArray)
    {
       if (advisedHandler_.handles(clazz))
          return advisedHandler_;
-      
+
       if (collectionHandler_.handles(clazz))
          return collectionHandler_;
-      
-      if (arrayHandler.handles(clazz))
+
+      if (allowArray && arrayHandler.handles(clazz))
          return arrayHandler;
-      
+
       if (serializableHandler_.handles(clazz))
          return serializableHandler_;
-    
-      throw new CacheException("Can not manage object. It must be either instrumented, a collection, an array, or Serializable: " 
+
+      throw new CacheException("Can not manage object. It must be either instrumented, a collection, an array, or Serializable: "
             + clazz.getName());
    }
-   
 
+
    private Fqn createInternalFqn(Fqn fqn, Object obj) throws CacheException
    {
       // Create an internal Fqn name
@@ -226,7 +227,7 @@
     * @return detached object
     * @throws CacheException
     */
-   public Object removeObject(Fqn fqn, String field) throws CacheException
+   public Object removeObject(Fqn fqn, String field, Object source) throws CacheException
    {
       // the class attribute is implicitly stored as an immutable read-only attribute
       PojoReference pojoReference = internal_.getPojoReference(fqn, field);
@@ -259,8 +260,8 @@
       else
       {
          cache.put(internalFqn, InternalConstant.POJOCACHE_STATUS, "DETACHING");
-         
-         result = getHandler(result.getClass()).remove(internalFqn, fqn, result);
+         boolean allowArray = source instanceof ArrayInterceptable;
+         result = getHandler(result.getClass(), allowArray).remove(internalFqn, fqn, result);
       }
 
       internal_.cleanUp(fqn, field);
@@ -272,7 +273,7 @@
 
       // Traverse from fqn to do getObject, if it return a pojo we then stop.
       Map map = new HashMap();
-      Object pojo = getObject(fqn, null);
+      Object pojo = getObject(fqn, null, null);
       if (pojo != null)
       {
          map.put(fqn, pojo);// we are done!
@@ -287,7 +288,7 @@
       return map;
    }
 
-   private Object getObjectInternal(Fqn<?> fqn, String field) throws CacheException
+   private Object getObjectInternal(Fqn<?> fqn, String field, Object source) throws CacheException
    {
       Fqn<?> internalFqn = fqn;
       PojoReference pojoReference = internal_.getPojoReference(fqn, field);
@@ -315,7 +316,8 @@
          //throw new PojoCacheException("PojoCacheDelegate.getObjectInternal(): null PojoInstance for fqn: " + internalFqn);
 
       Class<?> clazz = pojoInstance.getPojoClass();
-      obj = getHandler(clazz).get(internalFqn, clazz, pojoInstance);
+      boolean allowArray = source instanceof ArrayInterceptable;
+      obj = getHandler(clazz, allowArray).get(internalFqn, clazz, pojoInstance);
 
       InternalHelper.setPojo(pojoInstance, obj);
       return obj;
@@ -336,7 +338,7 @@
          Fqn newFqn = n.getFqn();
          if (InternalHelper.isInternalNode(newFqn)) continue;// skip
 
-         Object pojo = getObject(newFqn, null);
+         Object pojo = getObject(newFqn, null, null);
          if (pojo != null)
          {
             map.put(newFqn, pojo);

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java	2008-06-03 16:22:30 UTC (rev 5946)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java	2008-06-03 19:19:03 UTC (rev 5947)
@@ -99,7 +99,7 @@
    {
       try
       {
-         Object obj = putObject(id, pojo, null);
+         Object obj = putObject(id, pojo, null, null);
          return obj;
       }
       catch (CacheException e)
@@ -109,11 +109,11 @@
    }
 
    @Attach
-   public Object attach(Fqn<?> id, Object pojo, String field) throws PojoCacheException
+   public Object attach(Fqn<?> id, Object pojo, String field, Object source) throws PojoCacheException
    {
       try
       {
-         Object obj = putObject(id, pojo, field);
+         Object obj = putObject(id, pojo, field, source);
          return obj;
       }
       catch (CacheException e)
@@ -125,9 +125,9 @@
    /**
     * This public API is called from internal package only.
     */
-   public Object putObject(Fqn<?> id, Object pojo, String field) throws CacheException
+   public Object putObject(Fqn<?> id, Object pojo, String field, Object source) throws CacheException
    {
-      return delegate_.putObject(id, pojo, field);
+      return delegate_.putObject(id, pojo, field, source);
    }
 
    public Object detach(String id) throws PojoCacheException
@@ -136,14 +136,14 @@
    }
 
    @Detach
-   public Object detach(Fqn<?> id, String field) throws PojoCacheException
+   public Object detach(Fqn<?> id, String field, Object source) throws PojoCacheException
    {
       try
       {
-         Object pojo = getObject(id, field);// TODO need optimization here since it will be redundant here
+         Object pojo = getObject(id, field, source);// TODO need optimization here since it will be redundant here
          if (pojo == null) return pojo;
 
-         Object obj = removeObject(id, field);
+         Object obj = removeObject(id, field, source);
          return obj;
       }
       catch (CacheException e)
@@ -154,13 +154,13 @@
 
    public Object detach(Fqn<?> id) throws PojoCacheException
    {
-      return detach(id, null);
+      return detach(id, null, null);
    }
 
-   public Object removeObject(Fqn<?> id, String field) throws CacheException
+   public Object removeObject(Fqn<?> id, String field, Object source) throws CacheException
    {
       delegate_.setBulkRemove(false);
-      return delegate_.removeObject(id, field);
+      return delegate_.removeObject(id, field, source);
    }
 
    public String getPojoID(Object pojo)
@@ -193,12 +193,12 @@
 
    public Object getObject(Fqn<?> id) throws CacheException
    {
-      return getObject(id, null);
+      return getObject(id, null, null);
    }
 
-   public Object getObject(Fqn<?> id, String field) throws CacheException
+   public Object getObject(Fqn<?> id, String field, Object source) throws CacheException
    {
-      return delegate_.getObject(id, field);
+      return delegate_.getObject(id, field, source);
    }
 
 
@@ -313,7 +313,7 @@
             cache.removeCacheListener(listenerAdaptor);
       }
    }
-   
+
    public PojoCacheThreadContext getThreadContext()
    {
       return threadContext;

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/interceptors/dynamic/CacheFieldInterceptor.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/interceptors/dynamic/CacheFieldInterceptor.java	2008-06-03 16:22:30 UTC (rev 5946)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/interceptors/dynamic/CacheFieldInterceptor.java	2008-06-03 19:19:03 UTC (rev 5947)
@@ -53,7 +53,7 @@
       util_ = new PojoUtil();
    }
 
-   public CacheFieldInterceptor()
+   private CacheFieldInterceptor()
    {
    }
 
@@ -96,7 +96,7 @@
       // Kind of ad hoc now. MethodInvocation should not invoke this.
       if (invocation instanceof MethodInvocation)
          return invocation.invokeNext();
-      
+
       if (invocation instanceof FieldWriteInvocation)
       {
          Object target = invocation.getTargetObject();
@@ -123,7 +123,7 @@
             }
             else
             {
-               pCache_.attach(fqn_, value, field.getName());
+               pCache_.attach(fqn_, value, field.getName(), target);
             }
          }
 
@@ -148,8 +148,8 @@
             }
             else
             {
-               result = pCache_.getObject(fqn_, field.getName());
-               
+               result = pCache_.getObject(fqn_, field.getName(), target);
+
                // Work around AOP issue with field reads
                if (result != null && result.getClass().isArray())
                   registerArrayWithAOP(target, field.getName(), result);
@@ -172,13 +172,13 @@
       return invocation.invokeNext();
    }
 
-   private void registerArrayWithAOP(Object owner, String fieldName, Object array) 
+   private void registerArrayWithAOP(Object owner, String fieldName, Object array)
    {
       CachedArray cached = CachedArrayRegistry.lookup(array);
       if (cached != null)
-         ArrayRegistry.getInstance().addFieldReference(owner, fieldName, array);         
+         ArrayRegistry.getInstance().addFieldReference(owner, fieldName, array);
    }
-   
+
    /**
     * Check if the pojo is detached already.
     */

Modified: pojo/trunk/src/main/resources/META-INF/pojocache-aop.xml
===================================================================
--- pojo/trunk/src/main/resources/META-INF/pojocache-aop.xml	2008-06-03 16:22:30 UTC (rev 5946)
+++ pojo/trunk/src/main/resources/META-INF/pojocache-aop.xml	2008-06-03 19:19:03 UTC (rev 5947)
@@ -145,13 +145,16 @@
    <prepare expr="field(* $instanceof{@org.jboss.cache.pojo.annotation.Replicable}->*)" />
    
    <!--  Work around that ensures annotated classes which do not access fields are instrumented -->
-   <introduction expr="class($instanceof{@org.jboss.cache.pojo.annotation.Replicable})"/>
 
-   <!-- Array support 
+
+   <!-- Array support -->
+   <!-- Comment entire section to disable -->
    <arrayreplacement expr="class($instanceof{@org.jboss.cache.pojo.annotation.Replicable})"/>
-   <interceptor name="array" class="org.jboss.cache.pojo.interceptors.dynamic.ArrayInterceptor"/>
-   <arraybind type="READ_WRITE">
-      <interceptor-ref name="array"/>
+   <interceptor name="pojocache-array" class="org.jboss.cache.pojo.interceptors.dynamic.ArrayInterceptor"/>
+   <introduction expr="class($instanceof{@org.jboss.cache.pojo.annotation.Replicable})">
+       <interfaces>org.jboss.cache.pojo.impl.ArrayInterceptable</interfaces>
+   </introduction>
+   <arraybind name="pojocache-array" type="READ_WRITE">
+      <interceptor-ref name="pojocache-array"/>
    </arraybind>
-   -->
 </aop>

Modified: pojo/trunk/src/test/java/org/jboss/cache/pojo/ArrayTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/ArrayTest.java	2008-06-03 16:22:30 UTC (rev 5946)
+++ pojo/trunk/src/test/java/org/jboss/cache/pojo/ArrayTest.java	2008-06-03 19:19:03 UTC (rev 5947)
@@ -37,7 +37,7 @@
  * @author Ben Wang
  */
 @Test(groups = {"functional"})
-public class ArrayTest 
+public class ArrayTest
 {
    Log log = LogFactory.getLog(ArrayTest.class);
    PojoCache cache1, cache2;
@@ -49,7 +49,7 @@
       cache1 = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), false);
       cache1.getCache().addCacheListener(new MyCacheListener(false));
       cache1.start();
-      
+
       cache2 = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), false);
       cache2.getCache().addCacheListener(new MyCacheListener(true));
       cache2.start();
@@ -83,32 +83,66 @@
       ao.setPerson(3, ben);
       ao.setPerson(4, joe);
       ao.setPerson(5, ben);
-      
+
       AssertJUnit.assertSame(ao.getPerson(1), ben);
       AssertJUnit.assertSame(ao.getPerson(2), joe);
       AssertJUnit.assertSame(ao.getPerson(3), ben);
       AssertJUnit.assertSame(ao.getPerson(4), joe);
       AssertJUnit.assertSame(ao.getPerson(5), ben);
-      
+
       ArrayObject obj = (ArrayObject) cache2.find("/ao");
       Person person = obj.getPerson(4);
       obj.setPerson(5, person);
       AssertJUnit.assertSame(ao.getPerson(5), ao.getPerson(4));
-      
+
       ao.setNum(5, 4);
       AssertJUnit.assertEquals(4, obj.getNum(5));
    }
 
+   public void testMulti() throws Exception
+   {
+      log.info("testMulti() ....");
+      ArrayObject ao = new ArrayObject();
+      Person joe = new Person();
+      joe.setName("Joe");
+      joe.setAge(19);
+
+      Person ben = new Person();
+      ben.setName("Ben");
+      ben.setAge(19);
+
+      ao.setPerson(0, joe);
+
+      cache1.attach("/ao", ao);
+
+      ao.setMultiPerson(1, 2, 1, ben);
+      ao.setMultiPerson(2, 3, 2, joe);
+      ao.setMultiPerson(1, 2, 3, ben);
+      ao.setMultiPerson(2, 1, 4, joe);
+      ao.setMultiPerson(1, 1, 5, ben);
+
+      AssertJUnit.assertSame(ao.getMultiPerson(1, 2, 1), ben);
+      AssertJUnit.assertSame(ao.getMultiPerson(2, 3, 2), joe);
+      AssertJUnit.assertSame(ao.getMultiPerson(1, 2, 3), ben);
+      AssertJUnit.assertSame(ao.getMultiPerson(2, 1, 4), joe);
+      AssertJUnit.assertSame(ao.getMultiPerson(1, 1, 5), ben);
+
+      ArrayObject obj = (ArrayObject) cache2.find("/ao");
+      Person person = obj.getMultiPerson(2, 1, 4);
+      obj.setMultiPerson(1, 1, 5, person);
+      AssertJUnit.assertSame(ao.getMultiPerson(1, 1, 5), ao.getMultiPerson(2, 1, 4));
+   }
+
    @CacheListener
    public class MyCacheListener
    {
       private boolean visits;
-      
+
       public MyCacheListener(boolean visits)
       {
          this.visits = visits;
       }
-      
+
       @NodeActivated
       @NodePassivated
       @NodeCreated
@@ -118,11 +152,11 @@
       {
          if (visits != ne instanceof NodeVisitedEvent)
             return;
-         
+
          if (!ne.isPre())
             System.out.println((!visits ? "[one] " : "[two] ") + ne.getType() + " " + ne.getFqn());
       }
-      
+
       @NodeModified
       public void print(NodeModifiedEvent ne)
       {

Modified: pojo/trunk/src/test/java/org/jboss/cache/pojo/test/ArrayObject.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/test/ArrayObject.java	2008-06-03 16:22:30 UTC (rev 5946)
+++ pojo/trunk/src/test/java/org/jboss/cache/pojo/test/ArrayObject.java	2008-06-03 19:19:03 UTC (rev 5947)
@@ -41,11 +41,13 @@
       }
    }
    private Person[] team;
+   private Person[][][] multiTeam;
    private int[] nums;
 
    public ArrayObject()
    {
       team = new Person[10];
+      multiTeam = new Person[5][5][6];
       nums = new int[] {1,2,3,4,5,6,7,8,9};
    }
 
@@ -58,16 +60,16 @@
    {
       team = t;
    }
-   
+
    public void setNum(int index, int value)
    {
       int nums[] = this.nums;
       nums[index] = value;
-      
+
       // This will be optimized away if array interception is enabled
       this.nums = nums;
    }
-   
+
    public int getNum(int index)
    {
       return nums[index];
@@ -75,18 +77,25 @@
 
    public Person getPerson(int index)
    {
-      Object o = team[index];
-      return (Person)o;
+      return team[index];
    }
 
    public void setPerson(int index, Person p)
    {
       Person[] array = team;
       array[index] = p;
-      
+
       // This will be optimized away if array interception is enabled
       team = array;
    }
+
+   public Person getMultiPerson(int one, int two, int three) {
+      return multiTeam[one][two][three];
+   }
+
+   public void setMultiPerson(int one, int two, int three, Person person) {
+      multiTeam[one][two][three] = person;
+   }
 }
 
 




More information about the jbosscache-commits mailing list