[xwiki-notifications] r8167 - in xwiki-platform/core/trunk/xwiki-observation/src/main/java/org/xwiki/observation: . internal
sdumitriu (SVN)
notifications at xwiki.org
Mon Mar 3 11:08:15 CET 2008
Author: sdumitriu
Date: 2008-03-03 11:08:15 +0100 (Mon, 03 Mar 2008)
New Revision: 8167
Modified:
xwiki-platform/core/trunk/xwiki-observation/src/main/java/org/xwiki/observation/ObservationManager.java
xwiki-platform/core/trunk/xwiki-observation/src/main/java/org/xwiki/observation/internal/DefaultObservationManager.java
Log:
XWIKI-1522: Rewrite the notification mechanism
New version, with several changes:
* Java 1.5 generics and foreach loops
* Removed the WeakReference wrappers, as we don't need those
* Replaced Object[2] with an internal RegisteredListener class
* Fixed a ClassCast bug in DefaultObservationManager#removeListener(EventListener)
Modified: xwiki-platform/core/trunk/xwiki-observation/src/main/java/org/xwiki/observation/ObservationManager.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-observation/src/main/java/org/xwiki/observation/ObservationManager.java 2008-03-03 09:31:29 UTC (rev 8166)
+++ xwiki-platform/core/trunk/xwiki-observation/src/main/java/org/xwiki/observation/ObservationManager.java 2008-03-03 10:08:15 UTC (rev 8167)
@@ -23,7 +23,7 @@
import org.xwiki.observation.event.Event;
/**
- * The main orchestrator for event notification. You register {@link EventListener} against this
+ * The main orchestrator for event notification. You register {@link EventListener}s against this
* manager. It's also used to notify event listeners when an event is triggered.
*/
public interface ObservationManager
Modified: xwiki-platform/core/trunk/xwiki-observation/src/main/java/org/xwiki/observation/internal/DefaultObservationManager.java
===================================================================
--- xwiki-platform/core/trunk/xwiki-observation/src/main/java/org/xwiki/observation/internal/DefaultObservationManager.java 2008-03-03 09:31:29 UTC (rev 8166)
+++ xwiki-platform/core/trunk/xwiki-observation/src/main/java/org/xwiki/observation/internal/DefaultObservationManager.java 2008-03-03 10:08:15 UTC (rev 8167)
@@ -20,53 +20,83 @@
*/
package org.xwiki.observation.internal;
-import org.xwiki.observation.event.Event;
-import org.xwiki.observation.ObservationManager;
-import org.xwiki.observation.EventListener;
-
-import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import org.xwiki.observation.EventListener;
+import org.xwiki.observation.ObservationManager;
+import org.xwiki.observation.event.Event;
+
+/**
+ * Default implementation of the {@link ObservationManager}.
+ *
+ * @version $Id$
+ */
public class DefaultObservationManager implements ObservationManager
{
/**
- * Registered listeners.
- * The Map key is the Event class name and the values is a List with (Event, Listener) pairs.
+ * Internal class for holding an (Event, EventListener) pair. Too bad there's no simple Pair
+ * class in the JDK.
*/
- private Map listeners = new HashMap();
+ protected static class RegisteredListener
+ {
+ /** The event for which this listener is registered. * */
+ Event event;
+ /** The Event Listener. * */
+ EventListener listener;
+
+ /**
+ * Simple constructor, stores the passed Event and Listener.
+ *
+ * @param e The Event.
+ * @param l The Listener.
+ */
+ RegisteredListener(Event e, EventListener l)
+ {
+ event = e;
+ listener = l;
+ }
+ }
+
/**
+ * Registered listeners. The Map key is the Event class name and the value is a List with
+ * (Event, Listener) pairs.
+ */
+ private Map<String, List<RegisteredListener>> listeners =
+ new HashMap<String, List<RegisteredListener>>();
+
+ /**
* {@inheritDoc}
+ *
* @see ObservationManager#addListener(Event,org.xwiki.observation.EventListener)
*/
public void addListener(Event event, EventListener eventListener)
{
// Check if this is a new Event not already registered
- List eventListeners = (List) this.listeners.get(event.getClass().getName());
+ List<RegisteredListener> eventListeners = this.listeners.get(event.getClass().getName());
if (eventListeners == null) {
- eventListeners = new ArrayList();
- this.listeners.put(event.getClass().getName(), eventListeners);
+ eventListeners = new ArrayList<RegisteredListener>();
+ this.listeners.put(event.getClass().getName(), eventListeners);
}
// Check to see if the event/listener pair is already there
- for (Iterator it = eventListeners.iterator(); it.hasNext(); ) {
- WeakReference reference = (WeakReference) it.next();
- Object[] pairs = (Object[]) reference.get();
- if (pairs[1] == eventListener) {
+ for (RegisteredListener pair : eventListeners) {
+ if (pair.listener == eventListener) {
return;
}
}
// Add the event/listener pair
- eventListeners.add(new WeakReference(new Object[] {event, eventListener}));
+ eventListeners.add(new RegisteredListener(event, eventListener));
}
/**
* {@inheritDoc}
+ *
* @see ObservationManager#removeListener(org.xwiki.observation.event.Event, EventListener)
*/
public void removeListener(Event event, EventListener eventListener)
@@ -77,16 +107,15 @@
}
// Find the event key for the specified event
- List eventListeners = (List) this.listeners.get(event.getClass().getName());
+ List<RegisteredListener> eventListeners = this.listeners.get(event.getClass().getName());
if (eventListeners == null) {
return;
}
// Remove the listener
- for (Iterator it = eventListeners.iterator(); it.hasNext();) {
- WeakReference reference = (WeakReference) it.next();
- Object[] pairs = (Object[]) reference.get();
- if (pairs[1] == eventListener) {
+ for (Iterator<RegisteredListener> it = eventListeners.iterator(); it.hasNext();) {
+ RegisteredListener pair = it.next();
+ if (pair.listener == eventListener) {
it.remove();
break;
}
@@ -100,6 +129,7 @@
/**
* {@inheritDoc}
+ *
* @see ObservationManager#removeListener(EventListener)
*/
public void removeListener(EventListener eventListener)
@@ -107,46 +137,42 @@
// Loop over all registered events and remove the specified listener
// Loop over a copy in case the removeListener() call wants to
// remove the entire event from the map.
- List listeners = new ArrayList(this.listeners.keySet());
- for (Iterator it = listeners.iterator(); it.hasNext();) {
- Object[] pairs = (Object[]) it.next();
- if (pairs[1] == eventListener) {
- removeListener((Event) pairs[0], eventListener);
+ for (List<RegisteredListener> list : listeners.values()) {
+ for (RegisteredListener p : list) {
+ if (p.listener == eventListener) {
+ // TODO This is not efficient. We already found the element to remove, why
+ // search for it again?
+ removeListener(p.event, eventListener);
+ }
}
}
}
/**
* {@inheritDoc}
+ *
* @see ObservationManager#notify(org.xwiki.observation.event.Event, Object, Object)
*/
public void notify(Event event, Object source, Object data)
{
// Find all event/listeners pairs for this event
- List eventListeners = (List) this.listeners.get(event.getClass().getName());
+ List<RegisteredListener> eventListeners = this.listeners.get(event.getClass().getName());
if (eventListeners == null) {
return;
}
// Loop over a copy of the list in case it is altered by a listener
- List copy = new ArrayList(eventListeners);
- for (Iterator it = copy.iterator(); it.hasNext();) {
- WeakReference reference = (WeakReference) it.next();
- Object[] pairs = (Object[]) reference.get();
- if (pairs[1] == null) {
- it.remove();
- } else {
- Event storedEvent = (Event) pairs[0];
- if (storedEvent.matches(event)) {
- EventListener eventListener = (EventListener) pairs[1];
- eventListener.onEvent(event, source, data);
- }
+ List<RegisteredListener> copy = new ArrayList<RegisteredListener>(eventListeners);
+ for (RegisteredListener pair : copy) {
+ if (pair.event.matches(event)) {
+ pair.listener.onEvent(event, source, data);
}
}
}
/**
* {@inheritDoc}
+ *
* @see ObservationManager#notify(org.xwiki.observation.event.Event, Object)
*/
public void notify(Event event, Object source)
More information about the notifications
mailing list