[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