Author: tv
Date: Tue Feb 2 15:27:42 2016
New Revision: 1728149
URL: http://svn.apache.org/viewvc?rev=1728149&view=rev
Log:
Simplify managers
Modified:
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/manager/AbstractBaseManager.java
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/manager/CacheListener.java
db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/manager/AbstractBaseManagerTest.java
Modified:
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/manager/AbstractBaseManager.java
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/manager/AbstractBaseManager.java?rev=1728149&r1=1728148&r2=1728149&view=diff
==============================================================================
---
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/manager/AbstractBaseManager.java
(original)
+++
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/manager/AbstractBaseManager.java
Tue Feb 2 15:27:42 2016
@@ -22,15 +22,16 @@ package org.apache.torque.manager;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
-import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
-import org.apache.commons.collections.FastArrayList;
import org.apache.commons.jcs.JCS;
import org.apache.commons.jcs.access.CacheAccess;
import org.apache.commons.jcs.access.GroupCacheAccess;
@@ -82,11 +83,11 @@ public abstract class AbstractBaseManage
private boolean isNew = true;
/** The fields which are valid fields of interest for a listener. */
- protected Map<Column, ?> validFields;
+ private CopyOnWriteArraySet<Column> validFields = new
CopyOnWriteArraySet<Column>();
/** The listeners for this manager. */
- protected Map<Column, FastArrayList> listenersMap
- = new HashMap<Column, FastArrayList>();
+ protected ConcurrentMap<Column, CopyOnWriteArrayList<CacheListener<?>>>
listenersMap =
+ new ConcurrentHashMap<Column,
CopyOnWriteArrayList<CacheListener<?>>>();
/**
* Get the Class instance
@@ -109,6 +110,16 @@ public abstract class AbstractBaseManage
}
/**
+ * Add variable number of fields to the list potentially monitored by a
listener
+ *
+ * @param columns array of columns
+ */
+ protected void addValidField(Column ...columns)
+ {
+ this.validFields.addAll(Arrays.asList(columns));
+ }
+
+ /**
* Get a fresh instance of an om
*
* @return an instance of the om class
@@ -259,7 +270,7 @@ public abstract class AbstractBaseManage
}
/**
- * Disposes of the cache. This triggers a shutdown of the connected cache
+ * Disposes of the manager. This triggers a shutdown of the connected cache
* instances. This method should only be used during shutdown of Torque.
The
* manager instance will not cache anymore after this call.
*/
@@ -276,6 +287,9 @@ public abstract class AbstractBaseManage
groupCache.dispose();
groupCache = null;
}
+
+ validFields.clear();
+ listenersMap.clear();
}
/**
@@ -357,12 +371,12 @@ public abstract class AbstractBaseManage
/**
* Gets a list of om's based on id's.
*
- * @param ids a <code>ObjectKey[]</code> value
- * @return a <code>List</code> value
+ * @param ids a number of object ids
+ * @return a <code>List</code> of objects
* @throws TorqueException Any exceptions caught during processing will be
* rethrown wrapped into a TorqueException.
*/
- protected List<T> getOMs(final ObjectKey[] ids)
+ protected List<T> getOMs(final ObjectKey ...ids)
throws TorqueException
{
return getOMs(Arrays.asList(ids));
@@ -508,6 +522,8 @@ public abstract class AbstractBaseManage
}
/**
+ * Get the object usable for result caching
+ *
* @return The cache instance.
*/
public synchronized MethodResultCache getMethodResultCache()
@@ -530,110 +546,63 @@ public abstract class AbstractBaseManage
}
/**
+ * Add a new listener
*
* @param listener A new listener for cache events.
*/
- public void addCacheListenerImpl(
- final CacheListener<? extends Persistent> listener)
+ public void addCacheListenerImpl(final CacheListener<?> listener)
{
- List<Column> keys = listener.getInterestedFields();
- for (Column key : keys)
+ for (Column key : listener.getInterestedFields())
{
// Peer.column names are the fields
- if (validFields != null && validFields.containsKey(key))
+ if (validFields.contains(key))
{
- FastArrayList listeners = listenersMap.get(key);
+ CopyOnWriteArrayList<CacheListener<?>> newList = new
CopyOnWriteArrayList<CacheListener<?>>();
+ CopyOnWriteArrayList<CacheListener<?>> listeners =
listenersMap.putIfAbsent(key, newList);
+
if (listeners == null)
{
- listeners = createSubsetList(key);
+ listeners = newList;
}
- boolean isListenerNew = true;
- Iterator<?> j = listeners.iterator();
- while (j.hasNext())
- {
- Object listener2 =
- ((WeakReference<?>) j.next()).get();
-// if (listener2 == null)
-// {
-// // do a little cleanup while checking for dupes
-// // not thread-safe, not likely to be many nulls
-// // but should revisit
-// //j.remove();
-// }
-// else
- if (listener2 == listener)
- {
- isListenerNew = false;
- break;
- }
- }
- if (isListenerNew)
- {
- listeners.add(new WeakReference<CacheListener<? extends
Persistent>>(listener));
- }
+ listeners.addIfAbsent(listener);
}
}
}
/**
+ * Notify all listeners in the list that an object has changed
*
- * @param key
- * @return A subset of the list identified by <code>key</code>.
- */
- private synchronized FastArrayList createSubsetList(final Column key)
- {
- FastArrayList list = null;
- if (listenersMap.containsKey(key))
- {
- list = listenersMap.get(key);
- }
- else
- {
- list = new FastArrayList();
- list.setFast(true);
- listenersMap.put(key, list);
- }
- return list;
- }
-
- /**
- *
- * @param listeners
- * @param oldOm
- * @param om
+ * @param listeners the list of listeners
+ * @param oldOm the previous object, null if the object has been added
+ * @param om the new object, null if the object has been removed
*/
protected <TT extends Persistent> void notifyListeners(
- final List<WeakReference<CacheListener<TT>>> listeners,
+ final List<CacheListener<?>> listeners,
final TT oldOm,
final TT om)
{
if (listeners != null)
{
- synchronized (listeners)
+ for (CacheListener<?> cl : listeners)
{
- Iterator<WeakReference<CacheListener<TT>>> i =
listeners.iterator();
- while (i.hasNext())
+ @SuppressWarnings("unchecked")
+ CacheListener<TT> listener = (CacheListener<TT>) cl;
+
+ if (oldOm == null)
{
- CacheListener<TT> listener = i.next().get();
- if (listener == null)
- {
- // remove reference as its object was cleared
- i.remove();
- }
- else
- {
- if (oldOm == null)
- {
- // object was added
- listener.addedObject(om);
- }
- else
- {
- // object was refreshed
- listener.refreshedObject(om);
- }
- }
+ // object was added
+ listener.addedObject(om);
+ }
+ else if (om == null)
+ {
+ // object was removed
+ listener.removedObject(om);
+ }
+ else
+ {
+ // object was refreshed
+ listener.refreshedObject(om);
}
}
}
Modified:
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/manager/CacheListener.java
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/manager/CacheListener.java?rev=1728149&r1=1728148&r2=1728149&view=diff
==============================================================================
---
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/manager/CacheListener.java
(original)
+++
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/manager/CacheListener.java
Tue Feb 2 15:27:42 2016
@@ -34,21 +34,30 @@ import org.apache.torque.om.Persistent;
public interface CacheListener<T extends Persistent>
{
/**
+ * Notify listener that an object has been added to the database
*
- * @param om
+ * @param om the object
*/
void addedObject(T om);
/**
+ * Notify listener that an object has been modified
*
- * @param om
+ * @param om the object
*/
void refreshedObject(T om);
- //public void removedObject(T om);
+ /**
+ * Notify listener that an object has been removed from the database
+ *
+ * @param om the object
+ */
+ void removedObject(T om);
/**
+ * Get the list of fields we are listening for
*
+ * @return a list of fields, not null
*/
List<Column> getInterestedFields();
}
Modified:
db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/manager/AbstractBaseManagerTest.java
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/manager/AbstractBaseManagerTest.java?rev=1728149&r1=1728148&r2=1728149&view=diff
==============================================================================
---
db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/manager/AbstractBaseManagerTest.java
(original)
+++
db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/manager/AbstractBaseManagerTest.java
Tue Feb 2 15:27:42 2016
@@ -20,7 +20,6 @@ package org.apache.torque.manager;
*/
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
import junit.framework.TestCase;
@@ -42,6 +41,7 @@ public class AbstractBaseManagerTest ext
private boolean addedObjectCalled;
private boolean refreshedObjectCalled;
+ private boolean removedObjectCalled;
static
{
@@ -69,7 +69,13 @@ public class AbstractBaseManagerTest ext
this.refreshedObjectCalled = true;
}
- @Override
+ @Override
+ public void removedObject(TestPersistent om)
+ {
+ this.removedObjectCalled = true;
+ }
+
+ @Override
public List<Column> getInterestedFields()
{
List<Column> columnList = new ArrayList<Column>(2);
@@ -172,24 +178,34 @@ public class AbstractBaseManagerTest ext
assertNotNull("Should have MethodResultCache", mrc);
}
- @SuppressWarnings("unchecked")
public void testListeners()
{
- manager.validFields = new HashMap<Column, Object>();
- manager.validFields.put(new ColumnImpl("test1"), null);
- manager.validFields.put(new ColumnImpl("test2"), null);
+ manager.addValidField(new ColumnImpl("test1"), new
ColumnImpl("test2"));
manager.addCacheListenerImpl(this);
this.addedObjectCalled = false;
this.refreshedObjectCalled = false;
+ this.removedObjectCalled = false;
TestPersistent test1 = new TestPersistent();
TestPersistent test2 = new TestPersistent();
manager.notifyListeners(manager.listenersMap.get(new
ColumnImpl("test1")), (TestPersistent)null, test1);
assertTrue("Should call addedObject", addedObjectCalled);
assertFalse("Should not call refreshedObject",
refreshedObjectCalled);
+ assertFalse("Should not call removedObject", removedObjectCalled);
+
this.addedObjectCalled = false;
this.refreshedObjectCalled = false;
+ this.removedObjectCalled = false;
manager.notifyListeners(manager.listenersMap.get(new
ColumnImpl("test2")), test2, test1);
assertFalse("Should not call addedObject", addedObjectCalled);
assertTrue("Should call refreshedObject",
refreshedObjectCalled);
+ assertFalse("Should not call removedObject", removedObjectCalled);
+
+ this.addedObjectCalled = false;
+ this.refreshedObjectCalled = false;
+ this.removedObjectCalled = false;
+ manager.notifyListeners(manager.listenersMap.get(new
ColumnImpl("test2")), test2, null);
+ assertFalse("Should not call addedObject", addedObjectCalled);
+ assertFalse("Should not call refreshedObject", refreshedObjectCalled);
+ assertTrue("Should call removedObject", removedObjectCalled);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]