[jbosscache-commits] JBoss Cache SVN: r6374 - in pojo/trunk/src: main/java/org/jboss/cache/pojo/impl and 2 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Wed Jul 23 01:01:03 EDT 2008


Author: jason.greene at jboss.com
Date: 2008-07-23 01:01:02 -0400 (Wed, 23 Jul 2008)
New Revision: 6374

Added:
   pojo/trunk/src/main/java/org/jboss/cache/pojo/Reference.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ReferenceImpl.java
   pojo/trunk/src/test/java/org/jboss/cache/pojo/FindReferencesTest.java
Removed:
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/Referrer.java
Modified:
   pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCache.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AbstractHandler.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/CollectionClassHandler.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/InternalHelper.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/MethodDeclarations.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/NotificationDispatcher.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ObjectGraphHandler.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/impl/PojoInstance.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoUtil.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/SerializableObjectHandler.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/jmx/PojoCacheJmxWrapper.java
Log:
PCACHE-72 - Implement PojoCache.getInternalFqn and PojoCache.getReferences
Thanks to Dan Berindei!


Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCache.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCache.java	2008-07-23 01:33:57 UTC (rev 6373)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCache.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -7,6 +7,7 @@
 package org.jboss.cache.pojo;
 
 import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 import java.util.regex.Pattern;
 
@@ -103,15 +104,41 @@
     */
    Object detach(Fqn<?> id) throws PojoCacheException;
 
-   /**
-    * Return the POJO id that is associated with PojoCache. Note that if a POJO has not yet
-    * attached to the cache system, it will simply return null.
-    *
-    * @param pojo The POJO that is attached to PojoCache.
-    * @return String ID. Null if not existed.
-    */
-   String getPojoID(Object pojo);
+  /**
+   * Return the <code>Fqn</code> of the internal node containing the data of this attached object.
+   * <p>
+   * Note that if the object is not attached to the cache system, this method will simply return
+   * null. Same for any object of an immediate type (primitive wrapper types, String, or Class) or
+   * of any <code>Serializable</code> types.
+   * </p>
+   *
+   * @param object Any object.
+   * @return <code>Fqn</code> of the internal data node. <code>null</code> if the object is
+   *         immediate, serializable, or not in the cache.
+   */
+  Fqn<?> getInternalFqn(Object object);
 
+  /**
+   * Return a list of the references from attached objects to this object. For each reference it
+   * returns a {@link Reference} object containing the <code>Fqn</code> of the referrer object and
+   * the name of the field that contains the reference.
+   * <p>
+   * If the node is not attached to the cache, this method will return an empty list. Same for any
+   * object of an immediate type (primitive wrapper types, String, or Class) or of any
+   * <code>Serializable</code> types.
+   * </p>
+   * <p>
+   * For external references (i.e. when the object was directly attached to the cache by user code)
+   * the <code>Reference.fieldName</code> property is <code>null</code>. Otherwise it is the name
+   * of the field that contains the reference to this object.
+   * </p>
+   *
+   * @param object Any object.
+   * @return Collection of internal references to the given object. Empty collection if the object is
+   *         immediate, serializable, or not in the cache.
+   */
+   Collection<Reference> getReferences(Object object);
+
    /**
     * Determines if an object is attached at a particular location. This is somewhat less expensive
     * than find() because an object is not created, and internal reference links are not traversed.

Added: pojo/trunk/src/main/java/org/jboss/cache/pojo/Reference.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/Reference.java	                        (rev 0)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/Reference.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -0,0 +1,50 @@
+/*
+ * 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;
+
+import org.jboss.cache.Fqn;
+
+/**
+ * A reference to an attached object. This class represents both normal Fqn aliases, and
+ * references from other attached objects.
+ *
+ * @author Dan Berindei <dan.berindei at gmail.com>
+ */
+public interface Reference
+{
+   /**
+    * Returns the Fqn of the referring node. Cannot be <code>null</code>.
+    *
+    * @return <code>Fqn</code> of the referring node.
+    */
+   public Fqn<?> getFqn();
+
+   /**
+    * Returns the name of the node key which references the attached object, or null
+    * if the Fqn is a normal alias to the internal node. If there is a key, then this is
+    * typically a field name or collection index.
+    *
+    * @return Name of the field or key/index in the collection that is containing the reference.
+    */
+   public String getKey();
+}
\ No newline at end of file

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AbstractHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AbstractHandler.java	2008-07-23 01:33:57 UTC (rev 6373)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AbstractHandler.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -22,6 +22,7 @@
 package org.jboss.cache.pojo.impl;
 
 import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.Reference;
 
 abstract class AbstractHandler
 {
@@ -30,14 +31,14 @@
    {
       super();
    }
-   
+
    protected abstract boolean handles(Class<?> clazz);
 
-   protected abstract Object remove(Fqn<?> fqn, Fqn<?> referenceingFqn, Object result);
+   protected abstract Object remove(Fqn<?> fqn, Reference reference, Object result);
 
-   protected abstract void put(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj);
+   protected abstract void put(Fqn<?> fqn, Reference reference, Object obj);
 
    protected abstract Object get(Fqn<?> fqn, Class<?> clazz, PojoInstance pojoInstance);
 
    protected abstract Fqn<?> getFqn(Object obj);
-}
\ No newline at end of file
+}

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-07-23 01:33:57 UTC (rev 6373)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -22,11 +22,7 @@
 package org.jboss.cache.pojo.impl;
 
 import java.lang.reflect.Field;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -37,6 +33,7 @@
 import org.jboss.cache.CacheException;
 import org.jboss.cache.Fqn;
 import org.jboss.cache.pojo.PojoCacheException;
+import org.jboss.cache.pojo.Reference;
 import org.jboss.cache.pojo.interceptors.dynamic.BaseInterceptor;
 import org.jboss.cache.pojo.interceptors.dynamic.CacheFieldInterceptor;
 import org.jboss.cache.pojo.memory.FieldPersistentReference;
@@ -120,7 +117,7 @@
    }
 
    @Override
-   protected void put(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj) throws CacheException
+   protected void put(Fqn<?> fqn, Reference reference, Object obj) throws CacheException
    {
       CachedType type = pCache_.getCachedType(obj.getClass());
       // We have a clean slate then.
@@ -135,7 +132,7 @@
       // Let's do batch update via Map instead
       Map map = new HashMap();
       // Always initialize the ref count so we can mark this as an AopNode.
-      PojoInstance pojoInstance = InternalHelper.initializeAopInstance(referencingFqn);
+      PojoInstance pojoInstance = InternalHelper.initializeAopInstance(reference);
       map.put(PojoInstance.KEY, pojoInstance);
       pojoInstance.setPojoClass(type.getType());
       // we will do it recursively.
@@ -205,7 +202,7 @@
    }
 
    @Override
-   protected Object remove(Fqn<?> fqn, Fqn<?> referencingFqn, Object result) throws CacheException
+   protected Object remove(Fqn<?> fqn, Reference referencingFqn, Object result) throws CacheException
    {
       CachedType type = pCache_.getCachedType(result.getClass());
       InstanceAdvisor advisor = ((Advised) result)._getInstanceAdvisor();

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-07-23 01:33:57 UTC (rev 6373)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -22,6 +22,7 @@
 package org.jboss.cache.pojo.impl;
 
 import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.Reference;
 import org.jboss.cache.pojo.collection.CachedArray;
 import org.jboss.cache.pojo.collection.CachedArrayRegistry;
 
@@ -46,11 +47,11 @@
       return cached != null ? cached.getFqn() : null;
    }
 
-
-   protected void put(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj)
+   @Override
+   protected void put(Fqn<?> fqn, Reference reference, Object obj)
    {
       // Always initialize the ref count so that we can mark this as an AopNode.
-      PojoInstance pojoInstance = InternalHelper.initializeAopInstance(referencingFqn);
+      PojoInstance pojoInstance = InternalHelper.initializeAopInstance(reference);
       pojoInstance.set(obj);
       pojoInstance.setPojoClass(obj.getClass());
       cache.getCache().put(fqn, PojoInstance.KEY, pojoInstance);
@@ -70,7 +71,7 @@
    }
 
    @Override
-   protected Object remove(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj)
+   protected Object remove(Fqn<?> fqn, Reference referencingFqn, Object obj)
    {
       CachedArray cached = CachedArrayRegistry.lookup(obj);
       if (cached != null) {

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/CollectionClassHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/CollectionClassHandler.java	2008-07-23 01:33:57 UTC (rev 6373)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/CollectionClassHandler.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -7,11 +7,7 @@
 
 package org.jboss.cache.pojo.impl;
 
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -20,6 +16,7 @@
 import org.jboss.cache.CacheException;
 import org.jboss.cache.Fqn;
 import org.jboss.cache.pojo.PojoCacheException;
+import org.jboss.cache.pojo.Reference;
 import org.jboss.cache.pojo.collection.CollectionInterceptorUtil;
 import org.jboss.cache.pojo.interceptors.dynamic.AbstractCollectionInterceptor;
 import org.jboss.cache.pojo.interceptors.dynamic.BaseInterceptor;
@@ -84,7 +81,7 @@
       return obj;
    }
 
-   protected void put(Fqn fqn, Fqn referencingFqn, Object obj) throws CacheException
+   protected void put(Fqn fqn, Reference reference, Object obj) throws CacheException
    {
       boolean isCollection = false;
 
@@ -103,7 +100,7 @@
       }
 
       // Always initialize the ref count so that we can mark this as an AopNode.
-      PojoInstance pojoInstance = InternalHelper.initializeAopInstance(referencingFqn);
+      PojoInstance pojoInstance = InternalHelper.initializeAopInstance(reference);
       pojoInstance.set(obj);
       pojoInstance.setPojoClass(type.getType());
       cache_.put(fqn, PojoInstance.KEY, pojoInstance);
@@ -269,7 +266,7 @@
    }
 
    @Override
-   protected Object remove(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj) throws CacheException
+   protected Object remove(Fqn<?> fqn, Reference referencingFqn, Object obj) throws CacheException
    {
       if (!(obj instanceof ClassProxy))
       {

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/InternalHelper.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/InternalHelper.java	2008-07-23 01:33:57 UTC (rev 6373)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/InternalHelper.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -10,12 +10,9 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.Fqn;
+import org.jboss.cache.*;
 import org.jboss.cache.lock.UpgradeException;
-import org.jboss.cache.pojo.PojoCache;
-import org.jboss.cache.pojo.PojoCacheException;
+import org.jboss.cache.pojo.*;
 import org.jboss.cache.pojo.util.ObjectUtil;
 
 /**
@@ -56,24 +53,25 @@
    }
 
 
-   static PojoInstance initializeAopInstance(Fqn sourceFqn)
+   static PojoInstance initializeAopInstance(Reference reference)
    {
       PojoInstance pojoInstance = new PojoInstance();
 
-      pojoInstance.incrementRefCount(sourceFqn);
+      pojoInstance.incrementRefCount(reference);
       return pojoInstance;
    }
 
    /**
     * Increment reference count for the pojo. Note that this is not thread safe or atomic.
+    * @param reference TODO
     */
-   int incrementRefCount(Fqn originalFqn, Fqn referencingFqn) throws CacheException
+   int incrementRefCount(Fqn originalFqn, Reference reference) throws CacheException
    {
       PojoInstance pojoInstance = getPojoInstance(originalFqn);
       if (pojoInstance == null)
          throw new PojoCacheException("InternalDelegate.incrementRefCount(): null pojoReference for fqn: " + originalFqn);
 
-      int count = pojoInstance.incrementRefCount(referencingFqn);
+      int count = pojoInstance.incrementRefCount(reference);
       // need to update it.
       put(originalFqn, PojoInstance.KEY, pojoInstance);
       return count;
@@ -116,13 +114,13 @@
    /**
     * decrement reference count for the pojo. Note that this is not thread safe or atomic.
     */
-   int decrementRefCount(Fqn originalFqn, Fqn referencingFqn) throws CacheException
+   int decrementRefCount(Fqn originalFqn, Reference reference) throws CacheException
    {
       PojoInstance pojoInstance = getPojoInstance(originalFqn);
       if (pojoInstance == null)
          throw new PojoCacheException("InternalDelegate.decrementRefCount(): null pojoReference.");
 
-      int count = pojoInstance.decrementRefCount(referencingFqn);
+      int count = pojoInstance.decrementRefCount(reference);
 
       if (count < -1)  // can't dip below -1
          throw new PojoCacheException("InternalDelegate.decrementRefCount(): null pojoReference.");
@@ -138,49 +136,6 @@
       return (pojoInstance.getRefCount() > 0);
    }
 
-   int getRefCount(Fqn fqn) throws CacheException
-   {
-      return getPojoInstance(fqn).getRefCount();
-   }
-
-   String XgetRefFqn(Fqn fqn) throws CacheException
-   {
-      PojoInstance pojoInstance = getPojoInstance(fqn);
-      return getRefFqn(pojoInstance);
-   }
-
-   String getRefFqn(PojoInstance pojoInstance) throws CacheException
-   {
-      if (pojoInstance == null)
-         return null;
-
-      String aliasFqn = pojoInstance.getInternalFqn();
-
-      if (aliasFqn == null || aliasFqn.length() == 0) return null;
-
-      return getRefFqnFromAlias(aliasFqn);
-   }
-
-   void setRefFqn(Fqn fqn, String internalFqn) throws CacheException
-   {
-      PojoInstance pojoInstance = getPojoInstance(fqn);
-      if (pojoInstance == null)
-         pojoInstance = new PojoInstance();
-
-      pojoInstance.setInternalFqn(internalFqn);
-      put(fqn, PojoInstance.KEY, pojoInstance);
-   }
-
-   void removeRefFqn(Fqn fqn) throws CacheException
-   {
-      PojoInstance pojoInstance = getPojoInstance(fqn);
-      if (pojoInstance == null)
-         throw new PojoCacheException("InternalDelegate.getInternalFqn(): null pojoReference.");
-
-      pojoInstance.removeInternalFqn();
-      put(fqn, PojoInstance.KEY, pojoInstance);
-   }
-
    Object getPojo(Fqn fqn, String field) throws CacheException
    {
       PojoReference pojoReference = getPojoReference(fqn, field);
@@ -357,12 +312,6 @@
       return (String) get(getInternalFqn(aliasFqn), aliasFqn, true);
    }
 
-   Fqn getNextFqnInLine(Fqn currentFqn) throws CacheException
-   {
-      PojoInstance ai = getPojoInstance(currentFqn);
-      return ai.getAndRemoveFirstFqnInList();
-   }
-
    /**
     * Test if this internal node.
     *

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/MethodDeclarations.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/MethodDeclarations.java	2008-07-23 01:33:57 UTC (rev 6373)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/MethodDeclarations.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -9,11 +9,11 @@
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
-import java.util.List;
+import java.util.Set;
 
 import org.jboss.aop.InstanceAdvisor;
 import org.jboss.aop.advice.Interceptor;
-import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.Reference;
 import org.jboss.cache.pojo.collection.CachedArray;
 import org.jboss.cache.pojo.interceptors.dynamic.AbstractCollectionInterceptor;
 
@@ -67,13 +67,13 @@
          undoInMemorySubstitution = PojoUtil.class.getDeclaredMethod("undoInMemorySubstitution",
                                                                      new Class[]{Object.class, Field.class, Object.class});
          incrementReferenceCount = PojoUtil.class.getDeclaredMethod("incrementReferenceCount",
-                                                                    new Class[]{Fqn.class, int.class, List.class});
+                                                                    new Class[]{Reference.class, int.class, Set.class});
          decrementReferenceCount = PojoUtil.class.getDeclaredMethod("decrementReferenceCount",
-                                                                    new Class[]{Fqn.class, int.class, List.class});
+                                                                    new Class[]{Reference.class, int.class, Set.class});
          undoIncrementReferenceCount = PojoUtil.class.getDeclaredMethod("undoIncrementReferenceCount",
-                                                                        new Class[]{Fqn.class, int.class, List.class});
+                                                                        new Class[]{Reference.class, int.class, Set.class});
          undoDecrementReferenceCount = PojoUtil.class.getDeclaredMethod("undoDecrementReferenceCount",
-                                                                        new Class[]{Fqn.class, int.class, List.class});
+                                                                        new Class[]{Reference.class, int.class, Set.class});
 
          attachArray = PojoUtil.class.getDeclaredMethod("attachArray", new Class[]{Object.class, CachedArray.class});
          detachArray = PojoUtil.class.getDeclaredMethod("detachArray", new Class[]{Object.class, CachedArray.class});

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/NotificationDispatcher.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/NotificationDispatcher.java	2008-07-23 01:33:57 UTC (rev 6373)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/NotificationDispatcher.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -25,18 +25,13 @@
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 import java.util.concurrent.CopyOnWriteArraySet;
 import java.util.regex.Pattern;
 
 import org.jboss.cache.Fqn;
 import org.jboss.cache.pojo.PojoCacheException;
+import org.jboss.cache.pojo.Reference;
 import org.jboss.cache.pojo.notification.annotation.ArrayModified;
 import org.jboss.cache.pojo.notification.annotation.Attached;
 import org.jboss.cache.pojo.notification.annotation.Detached;
@@ -204,7 +199,7 @@
       return Collections.unmodifiableSet(set);
    }
 
-   Set<Entry> getListenerEntries(List<Fqn> fqns)
+   Set<Entry> getListenerEntries(Collection<Reference> references)
    {
       Set<Entry> set = new HashSet<Entry>();
       for (Entry entry : listeners)
@@ -215,9 +210,9 @@
             continue;
          }
 
-         for (Fqn fqn : fqns)
+         for (Reference reference : references)
          {
-            if (entry.pattern.matcher(fqn.toString()).matches())
+            if (entry.pattern.matcher(reference.getFqn().toString()).matches())
             {
                set.add(entry);
                break;

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ObjectGraphHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ObjectGraphHandler.java	2008-07-23 01:33:57 UTC (rev 6373)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ObjectGraphHandler.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -12,6 +12,7 @@
 import org.jboss.cache.CacheException;
 import org.jboss.cache.Fqn;
 import org.jboss.cache.pojo.PojoCacheException;
+import org.jboss.cache.pojo.Reference;
 
 /**
  * Handle the object graph management.
@@ -57,9 +58,9 @@
    }
 
    @Override
-   protected void put(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj) throws CacheException
+   protected void put(Fqn<?> fqn, Reference reference, Object obj) throws CacheException
    {
-      setupRefCounting(fqn, referencingFqn);
+      setupRefCounting(fqn, reference);
    }
 
    boolean isMultipleReferenced(Fqn<?> internalFqn)
@@ -80,15 +81,15 @@
    }
 
    @Override
-   protected Object remove(Fqn<?> fqn, Fqn<?> referencingFqn, Object pojo)
+   protected Object remove(Fqn<?> fqn, Reference reference, Object pojo)
          throws CacheException
    {
       if (log.isDebugEnabled())
       {
-         log.debug("remove(): removing object fqn: " + referencingFqn
+         log.debug("remove(): removing object fqn: " + reference
                    + " Will just de-reference it.");
       }
-      removeFromReference(fqn, referencingFqn);
+      removeFromReference(fqn, reference);
 
       return null;
    }
@@ -96,12 +97,12 @@
    /**
     * Remove the object from the the reference fqn, meaning just decrement the ref counter.
     */
-   private void removeFromReference(Fqn<?> originalFqn, Fqn<?> referencingFqn) throws CacheException
+   private void removeFromReference(Fqn<?> originalFqn, Reference reference) throws CacheException
    {
       synchronized (originalFqn)
       {  // we lock the internal fqn here so no one else has access.
          // Decrement ref counting on the internal node
-         if (decrementRefCount(originalFqn, referencingFqn) == PojoInstance.INITIAL_COUNTER_VALUE)
+         if (decrementRefCount(originalFqn, reference) == PojoInstance.INITIAL_COUNTER_VALUE)
          {
             // No one is referring it so it is safe to remove
             // TODO we should make sure the parent nodes are also removed they are empty as well.
@@ -117,22 +118,22 @@
     * @param fqn    The original fqn node
     * @param refFqn The new internal fqn node
     */
-   private void setupRefCounting(Fqn<?> fqn, Fqn<?> referencingFqn) throws CacheException
+   private void setupRefCounting(Fqn<?> fqn, Reference reference) throws CacheException
    {
       synchronized (fqn)
       {
          // increment the reference counting
-         incrementRefCount(fqn, referencingFqn);
+         incrementRefCount(fqn, reference);
       }
    }
 
-   private int incrementRefCount(Fqn<?> originalFqn, Fqn<?> referencingFqn) throws CacheException
+   private int incrementRefCount(Fqn<?> originalFqn, Reference reference) throws CacheException
    {
-      return internal_.incrementRefCount(originalFqn, referencingFqn);
+      return internal_.incrementRefCount(originalFqn, reference);
    }
 
-   private int decrementRefCount(Fqn<?> originalFqn, Fqn<?> referencingFqn) throws CacheException
+   private int decrementRefCount(Fqn<?> originalFqn, Reference reference) throws CacheException
    {
-      return internal_.decrementRefCount(originalFqn, referencingFqn);
+      return internal_.decrementRefCount(originalFqn, reference);
    }
 }

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-07-23 01:33:57 UTC (rev 6373)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -20,6 +20,7 @@
 import org.jboss.cache.Node;
 import org.jboss.cache.Region;
 import org.jboss.cache.pojo.PojoCacheException;
+import org.jboss.cache.pojo.Reference;
 import org.jboss.cache.pojo.collection.CollectionInterceptorUtil;
 import org.jboss.cache.pojo.interceptors.dynamic.AbstractCollectionInterceptor;
 import org.jboss.cache.pojo.interceptors.dynamic.BaseInterceptor;
@@ -27,12 +28,7 @@
 import org.jboss.cache.pojo.util.AopUtil;
 
 import java.lang.reflect.Field;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 /**
  * Delegate class for PojoCache, the real implementation code happens here.
@@ -126,9 +122,10 @@
       AbstractHandler handler = getHandler(obj.getClass(), allowArray);
       Fqn<?> internalFqn = handler.getFqn(obj);
 
+      Reference reference = new ReferenceImpl(fqn, field);
       if (internalFqn != null)
       {
-         graphHandler_.put(internalFqn, fqn, obj);
+         graphHandler_.put(internalFqn, reference , obj);
       }
       else
       {
@@ -136,7 +133,7 @@
          if (log.isDebugEnabled())
             log.debug("attach(): id: " + fqn + " will store the pojo in the internal area: " + internalFqn);
 
-         handler.put(internalFqn, fqn, obj);
+         handler.put(internalFqn, reference, obj);
 
          // Used by notification sub-system
          cache.put(internalFqn, InternalConstant.POJOCACHE_STATUS, "ATTACHED");
@@ -245,15 +242,16 @@
       if (result == null)
          return null;
 
+      Reference reference = new ReferenceImpl(fqn, field);
       if (graphHandler_.isMultipleReferenced(internalFqn))
       {
-         graphHandler_.remove(internalFqn, fqn, result);
+         graphHandler_.remove(internalFqn, reference, result);
       }
       else
       {
          cache.put(internalFqn, InternalConstant.POJOCACHE_STATUS, "DETACHING");
          boolean allowArray = source instanceof ArrayInterceptable;
-         result = getHandler(result.getClass(), allowArray).remove(internalFqn, fqn, result);
+         result = getHandler(result.getClass(), allowArray).remove(internalFqn, reference, result);
       }
 
       internal_.cleanUp(fqn, field);
@@ -346,4 +344,21 @@
    {
       return internal_.getPojoReference(id, null) != null || internal_.getPojoInstance(id) != null;
    }
+
+   public Fqn<?> getInternalFqn(Object object)
+   {
+      AbstractHandler handler = getHandler(object.getClass(), true);
+      Fqn<?> internalFqn = handler.getFqn(object);
+      return internalFqn;
+   }
+
+   public Collection<Reference> getReferences(Object object)
+   {
+      Fqn<?> fqn = getInternalFqn(object);
+      if (fqn == null)
+         return Collections.emptyList();
+
+      PojoInstance pojoInstance = internal_.getPojoInstance(fqn);
+      return pojoInstance.getReferences();
+   }
 }

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-07-23 01:33:57 UTC (rev 6373)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -8,6 +8,7 @@
 package org.jboss.cache.pojo.impl;
 
 import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 import java.util.WeakHashMap;
 import java.util.regex.Pattern;
@@ -29,6 +30,7 @@
 import org.jboss.cache.pojo.PojoCache;
 import org.jboss.cache.pojo.PojoCacheException;
 import org.jboss.cache.pojo.PojoCacheThreadContext;
+import org.jboss.cache.pojo.Reference;
 import org.jboss.cache.pojo.interceptors.PojoTxSynchronizationHandler;
 import org.jboss.cache.transaction.BatchModeTransactionManager;
 
@@ -225,11 +227,16 @@
       return detach(id, null, null);
    }
 
-   public String getPojoID(Object pojo)
+   public Fqn<?> getInternalFqn(Object object)
    {
-      throw new PojoCacheException("getPojoID not yet implemented");
+      return delegate_.getInternalFqn(object);
    }
 
+   public Collection<Reference> getReferences(Object object)
+   {
+      return delegate_.getReferences(object);
+   }
+
    public boolean exists(Fqn<?> id)
    {
       return delegate_.exists(id);

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoInstance.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoInstance.java	2008-07-23 01:33:57 UTC (rev 6373)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoInstance.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -7,11 +7,10 @@
 package org.jboss.cache.pojo.impl;
 
 import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.Reference;
 
 import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
 
 /**
  * POJO class metadata information.
@@ -35,17 +34,13 @@
    // The instance is transient to avoid replication outside the VM
    private transient Object instance_;
 
-   // If not null, it signifies that this is a reference that points to this fqn.
-   // Note that this will get replicated.
-   private String internalFqn_ = null;
-
    // Reference counting. THis will get replicated as well. This keep track of number of
    // other instances that referenced this fqn.
    private int refCount_ = INITIAL_COUNTER_VALUE;
 
-   // List of fqns that reference this fqn. Assume list size is not big since it may not be efficient.
-   private List<Fqn> referencedBy_ = null;
-   private Class clazz_ = null;
+   // List of fqns that reference this fqn.
+   private Set<Reference> referencedBy_ = new HashSet<Reference>(4);
+   private Class<?> clazz_ = null;
    private transient PojoUtil util_ = new PojoUtil();
 
    public PojoInstance()
@@ -77,59 +72,31 @@
       instance_ = instance;
    }
 
-   public String getInternalFqn()
+   synchronized public int incrementRefCount(Reference reference)
    {
-      return internalFqn_;
-   }
-
-   public void setInternalFqn(String refFqn)
-   {
-      internalFqn_ = refFqn;
-   }
-
-   public void removeInternalFqn()
-   {
-      internalFqn_ = null;
-   }
-
-   synchronized public int incrementRefCount(Fqn sourceFqn)
-   {
-      if (sourceFqn == null)
+      if (reference == null || reference.getFqn() == null)
       {
          throw new IllegalStateException("PojoInstance.incrementRefCount(): null sourceFqn");
       }
 
-      if (referencedBy_ == null)
-      {
-         referencedBy_ = new ArrayList();
-      }
-
       if (util_ == null) util_ = new PojoUtil();
-      refCount_ = util_.incrementReferenceCount(sourceFqn, refCount_, referencedBy_);
-//      referencedBy_.add(sourceFqn);
-
-//      refCount_ += 1;
-//logger_.info("incrementRefCount(): current ref count " +refCount_);
+      refCount_ = util_.incrementReferenceCount(reference, refCount_, referencedBy_);
       return refCount_;
    }
 
-   synchronized public int decrementRefCount(Fqn sourceFqn)
+   synchronized public int decrementRefCount(Reference reference)
    {
-      if (sourceFqn == null)
+      if (reference == null || reference.getFqn() == null)
       {
          throw new IllegalStateException("PojoInstance.incrementRefCount(): null sourceFqn");
       }
 
-      if (!referencedBy_.contains(sourceFqn))
-         throw new IllegalStateException("PojoReference.decrementRefCount(): source fqn: " +
-                                         sourceFqn + " is not present.");
+      if (!referencedBy_.contains(reference))
+         throw new IllegalStateException("PojoReference.decrementRefCount(): reference: " +
+                                         reference + " is not present.");
 
       if (util_ == null) util_ = new PojoUtil();
-      refCount_ = util_.decrementReferenceCount(sourceFqn, refCount_, referencedBy_);
-//      referencedBy_.remove(sourceFqn);
-
-//      refCount_ -= 1;
-//logger_.info("decrementRefCount(): current ref count " +refCount_);
+      refCount_ = util_.decrementReferenceCount(reference, refCount_, referencedBy_);
       return refCount_;
    }
 
@@ -138,23 +105,13 @@
       return refCount_;
    }
 
-   public List<Fqn> getReferences()
+   public Collection<Reference> getReferences()
    {
-      return Collections.unmodifiableList(referencedBy_);
+      return Collections.unmodifiableCollection(referencedBy_);
    }
 
-   synchronized public Fqn getAndRemoveFirstFqnInList()
-   {
-      return (Fqn) referencedBy_.remove(0);
-   }
-
-   synchronized public void addXFqnIntoList(Fqn fqn)
-   {
-      referencedBy_.add(0, fqn);
-   }
-
    public String toString()
    {
-      return "PI[fqn=" + internalFqn_ + " ref=" + refCount_ + " class=" + clazz_.getName() + "]";
+      return "PI[ref=" + refCount_ + " class=" + clazz_.getName() + "]";
    }
 }

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoUtil.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoUtil.java	2008-07-23 01:33:57 UTC (rev 6373)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoUtil.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -10,11 +10,13 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.List;
+import java.util.Set;
 
 import org.jboss.aop.InstanceAdvisor;
 import org.jboss.aop.advice.Interceptor;
 import org.jboss.cache.Fqn;
 import org.jboss.cache.pojo.PojoCacheException;
+import org.jboss.cache.pojo.Reference;
 import org.jboss.cache.pojo.collection.CachedArray;
 import org.jboss.cache.pojo.collection.CachedArrayRegistry;
 import org.jboss.cache.pojo.interceptors.PojoTxSynchronizationHandler;
@@ -157,45 +159,45 @@
       }
    }
 
-   public int incrementReferenceCount(Fqn<?> sourceFqn, int count, List<?> refList)
+   public int incrementReferenceCount(Reference reference, int count, Set<Reference> referencedBy_)
    {
-      int ret = _incrementReferenceCount(sourceFqn, count, refList);
+      int ret = _incrementReferenceCount(reference, count, referencedBy_);
       Method method = MethodDeclarations.undoIncrementReferenceCount;
-      Object[] args = new Object[]{sourceFqn, count, refList};
+      Object[] args = new Object[]{reference, count, referencedBy_};
       MethodCall mc = new MethodCall(method, args, this);
       addUndo(mc);
       return ret;
    }
 
-   public int undoIncrementReferenceCount(Fqn sourceFqn, int count, List refList)
+   public int undoIncrementReferenceCount(Reference reference, int count, Set<Reference> refList)
    {
-      return _decrementReferenceCount(sourceFqn, count, refList);
+      return _decrementReferenceCount(reference, count, refList);
    }
 
-   private int _incrementReferenceCount(Fqn sourceFqn, int count, List refList)
+   private int _incrementReferenceCount(Reference reference, int count, Set<Reference> referencedBy_)
    {
-      refList.add(sourceFqn);
+      referencedBy_.add(reference);
       return count + 1;
    }
 
-   public int decrementReferenceCount(Fqn<?> sourceFqn, int count, List<?> refList)
+   public int decrementReferenceCount(Reference reference, int count, Set<Reference> referencedBy_)
    {
-      int ret = _decrementReferenceCount(sourceFqn, count, refList);
+      int ret = _decrementReferenceCount(reference, count, referencedBy_);
       Method method = MethodDeclarations.undoDecrementReferenceCount;
-      Object[] args = new Object[]{sourceFqn, count, refList};
+      Object[] args = new Object[]{reference, count, referencedBy_};
       MethodCall mc = new MethodCall(method, args, this);
       addUndo(mc);
       return ret;
    }
 
-   public int undoDecrementReferenceCount(Fqn sourceFqn, int count, List refList)
+   public int undoDecrementReferenceCount(Reference reference, int count, Set<Reference> refList)
    {
-      return _incrementReferenceCount(sourceFqn, count, refList);
+      return _incrementReferenceCount(reference, count, refList);
    }
 
-   private int _decrementReferenceCount(Fqn sourceFqn, int count, List refList)
+   private int _decrementReferenceCount(Reference reference, int count, Set<Reference> referencedBy_)
    {
-      refList.remove(sourceFqn);
+      referencedBy_.remove(reference);
       return count - 1;
    }
 }

Added: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ReferenceImpl.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ReferenceImpl.java	                        (rev 0)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ReferenceImpl.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -0,0 +1,110 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+
+import net.jcip.annotations.Immutable;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.Reference;
+
+/**
+ * A reference from an attached object to another attached object. This class also contains the name
+ * of the field that contains the reference.
+ *
+ * @author Dan Berindei <dan.berindei at gmail.com>
+ */
+ at Immutable
+public final class ReferenceImpl implements Reference, Serializable
+{
+   private static final long serialVersionUID = 2647262858847953704L;
+
+   private Fqn<?> fqn;
+   private String key;
+
+   public ReferenceImpl(Fqn<?> fqn)
+   {
+      this(fqn, null);
+   }
+
+   /**
+    * @param fqn <code>Fqn</code> of the referring node. Cannot be <code>null</code>.
+    * @param key Name of the field, index in the field or key in the collection that is containing the reference.
+    */
+   public ReferenceImpl(Fqn<?> fqn, String key)
+   {
+      if (fqn == null)
+         throw new IllegalArgumentException("Fqn can not be null!!");
+
+      this.fqn = fqn;
+      this.key = key;
+   }
+
+   public String getKey()
+   {
+      return key;
+   }
+
+   public Fqn<?> getFqn()
+   {
+      return fqn;
+   }
+
+   private boolean equals(Object o1, Object o2)
+   {
+      if (o1 == o2)
+         return true;
+
+      if (o1 != null && o1.equals(o2))
+         return true;
+
+      return false;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      int result = 629 * fqn.hashCode();
+
+      if (key != null)
+         result = 37 * result + key.hashCode();
+
+      return result;
+   }
+
+   @Override
+   public boolean equals(Object o)
+   {
+      if (o instanceof Reference)
+         return equals(((ReferenceImpl) o).fqn, fqn) && equals(((ReferenceImpl) o).key, key);
+
+      return false;
+   }
+
+   @Override
+   public String toString()
+   {
+      return "Reference[fqn=" + fqn + " field=" + key + "]";
+   }
+}
\ No newline at end of file

Deleted: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/Referrer.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/Referrer.java	2008-07-23 01:33:57 UTC (rev 6373)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/Referrer.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -1,89 +0,0 @@
-/*
-* 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;
-
-import org.jboss.cache.Fqn;
-
-/**
- * A referrer node refers to an internal node.
- * 
- * @author Jason T. Greene
- */
-final class Referrer
-{
-   private Fqn fqn;
-   private String field;
-
-   Referrer(Fqn fqn)
-   {
-      this(fqn, null);
-   }
-   
-   Referrer(Fqn fqn, String field)
-   {
-      if (fqn == null)
-         throw new IllegalArgumentException("Fqn can not be null!!");
-      
-      this.fqn = fqn;
-      this.field = field;
-   }
-
-   public String getField()
-   {
-      return field;
-   }
-
-   public Fqn getFqn()
-   {
-      return fqn;
-   }
-   
-   private boolean equals(Object o1, Object o2)
-   {
-      if (o1 == o2)
-         return true;
-      
-      if (o1 != null && o1.equals(o2))
-         return true;
-      
-      return false;
-   }
-   
-   public int hashCode()
-   {
-      int result = 629 * fqn.hashCode();
-
-      if (field != null)
-         result = 37 * result + field.hashCode();
-      
-      return result;
-   }
-   
-   public boolean equals(Object o)
-   {
-      if (o instanceof Referrer)
-         return equals(((Referrer)o).fqn, fqn) && equals(((Referrer)o).field, field);
-      
-      return false;
-   }
-}
\ No newline at end of file

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/SerializableObjectHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/SerializableObjectHandler.java	2008-07-23 01:33:57 UTC (rev 6373)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/SerializableObjectHandler.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -15,8 +15,8 @@
 import org.apache.commons.logging.LogFactory;
 import org.jboss.cache.Cache;
 import org.jboss.cache.CacheException;
-import org.jboss.cache.CacheSPI;
 import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.Reference;
 
 /**
  * Handle Serializable object cache management.
@@ -37,13 +37,13 @@
       this.cache = pojoCache.getCache();
       internal_ = internal;
    }
-   
+
    protected Fqn<?> getFqn(Object obj)
    {
       // Not supported
       return null;
    }
-   
+
    @Override
    protected boolean handles(Class<?> clazz)
    {
@@ -59,7 +59,7 @@
 
 
    @Override
-   protected void put(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj) throws CacheException
+   protected void put(Fqn<?> fqn, Reference reference, Object obj) throws CacheException
    {
       // Note that JBoss Serialization can serialize any type now.
       if (log_.isDebugEnabled())
@@ -87,7 +87,7 @@
    }
 
    @Override
-   protected Object remove(Fqn<?> fqn, Fqn<?> referenceingFqn, Object result) throws CacheException
+   protected Object remove(Fqn<?> fqn, Reference reference, Object result) throws CacheException
    {
       cache.removeNode(fqn);
       return result;

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/jmx/PojoCacheJmxWrapper.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/jmx/PojoCacheJmxWrapper.java	2008-07-23 01:33:57 UTC (rev 6373)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/jmx/PojoCacheJmxWrapper.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -123,7 +123,7 @@
 
    public String getInternalLocation(Object pojo) throws PojoCacheAlreadyDetachedException
    {
-      return pojoCache.getPojoID(pojo);
+      return pojoCache.getInternalFqn(pojo).toString();
    }
 
    public String getUnderlyingCacheObjectName()

Added: pojo/trunk/src/test/java/org/jboss/cache/pojo/FindReferencesTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/FindReferencesTest.java	                        (rev 0)
+++ pojo/trunk/src/test/java/org/jboss/cache/pojo/FindReferencesTest.java	2008-07-23 05:01:02 UTC (rev 6374)
@@ -0,0 +1,155 @@
+package org.jboss.cache.pojo;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertTrue;
+
+import java.util.*;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.impl.ReferenceImpl;
+import org.jboss.cache.pojo.test.*;
+import org.testng.annotations.*;
+
+/**
+ * Test case for finding back-references.
+ *
+ * @author Dan Berindei <dan.berindei at gmail.com>
+ */
+
+ at Test(groups = { "functional" })
+public class FindReferencesTest
+{
+   Log log = LogFactory.getLog(FindReferencesTest.class);
+   PojoCache cache_;
+
+   @BeforeMethod(alwaysRun = true)
+   protected void setUp() throws Exception
+   {
+      log.info("setUp() ....");
+      String configFile = "META-INF/local-service.xml";
+      boolean toStart = false;
+      cache_ = PojoCacheFactory.createCache(configFile, toStart);
+      cache_.start();
+   }
+
+   @AfterMethod(alwaysRun = true)
+   protected void tearDown() throws Exception
+   {
+      cache_.stop();
+   }
+
+   private Person createPerson(String id, String name, int age, Address address)
+   {
+      Person p = new Person(null);
+      p.setName(name);
+      p.setAge(age);
+      p.setAddress(address);
+      cache_.attach(id, p);
+      return p;
+   }
+
+   private Address createAddress()
+   {
+      Address add = new Address();
+      add.setZip(95123);
+      add.setCity("San Jose");
+      return add;
+   }
+
+   public void testImmediateType() throws Exception
+   {
+      log.info("testImmediateType() ....");
+      String test = "This is a test";
+      cache_.attach("/test", test);
+
+      assertEquals("Fqn", null, cache_.getInternalFqn(test));
+      assertEquals("List", Collections.EMPTY_LIST, cache_.getReferences(test));
+   }
+
+   public void testNotAttached() throws Exception
+   {
+      log.info("testImmediateType() ....");
+      Address address = createAddress();
+
+      assertEquals("Fqn", null, cache_.getInternalFqn(address));
+      assertEquals("List", Collections.EMPTY_LIST, cache_.getReferences(address));
+   }
+
+   public void testSingleExternalReference() throws Exception
+   {
+      log.info("testNoReferences() ....");
+      Person joe = createPerson("/person/joe", "Joe Black", 32, null);
+
+      Fqn<?> joesInternalFqn = cache_.getInternalFqn(joe);
+      assertTrue("Internal Fqn not null", joesInternalFqn != null);
+
+      Collection<Reference> addressReferences = cache_.getReferences(joe);
+      assertEquals("Size", 1, addressReferences.size());
+      assertEquals("Reference", new ReferenceImpl(Fqn.fromString("/person/joe"), null),
+            addressReferences.iterator().next());
+   }
+
+   public void testSingleInternalReference() throws Exception
+   {
+      log.info("testSingleReference() ....");
+      Address address = createAddress();
+      Person joe = createPerson("/person/joe", "Joe Black", 32, address);
+
+      Fqn<?> joesInternalFqn = cache_.getInternalFqn(joe);
+      Collection<Reference> addressReferences = cache_.getReferences(address);
+
+      assertEquals("Size", 1, addressReferences.size());
+      assertEquals("Reference", new ReferenceImpl(joesInternalFqn, "address"),
+            addressReferences.iterator().next());
+   }
+
+   public void testMultipleInternalReferences() throws Exception
+   {
+      log.info("testMultipleReferences() ....");
+      Address address = createAddress();
+      Person joe = createPerson("/person/joe", "Joe Black", 32, address);
+      Person jane = createPerson("/person/jane", "Jane Black", 32, address);
+
+      Fqn<?> joesInternalFqn = cache_.getInternalFqn(joe);
+      Fqn<?> janesInternalFqn = cache_.getInternalFqn(jane);
+      HashSet<Reference> expectedReferences = new HashSet<Reference>(Arrays.<Reference> asList(
+            new ReferenceImpl(joesInternalFqn, "address"), new ReferenceImpl(janesInternalFqn, "address")));
+
+      Set<Reference> addressReferences = new HashSet<Reference>(cache_.getReferences(address));
+
+      assertEquals("Reference Fqns", expectedReferences, addressReferences);
+   }
+
+   public void testDoubleReferenceFromSameObject()
+   {
+      log.info("testDoubleReferenceFromSameObject() ...");
+
+      DoubleRef doubleRef = new DoubleRef();
+      cache_.attach("/doubleref", doubleRef);
+
+      Fqn<?> sourceFqn = cache_.getInternalFqn(doubleRef);
+      HashSet<Reference> expectedReferences = new HashSet<Reference>(Arrays.<Reference> asList(
+            new ReferenceImpl(sourceFqn, "one"), new ReferenceImpl(sourceFqn, "two")));
+
+      Student student = doubleRef.getOne();
+      Set<Reference> references = new HashSet<Reference>(cache_.getReferences(student));
+
+      assertEquals("Reference Fqns", expectedReferences, references);
+
+      // removing one of the references
+      doubleRef.setOne(null);
+      Collection<Reference> references2 = cache_.getReferences(student);
+
+      assertEquals("Size", 1, references2.size());
+      assertEquals("Reference Fqn", new ReferenceImpl(sourceFqn, "two"), references2.iterator().next());
+
+      // removing the last reference
+      doubleRef.setTwo(null);
+      Collection<Reference> references3 = cache_.getReferences(student);
+
+      assertEquals("Size", 0, references3.size());
+   }
+
+}
\ No newline at end of file




More information about the jbosscache-commits mailing list