Author: jcarman
Date: Sat Jul 24 12:49:38 2010
New Revision: 978864
URL: http://svn.apache.org/viewvc?rev=978864&view=rev
Log:
LANG-580: Add Event Support Utilities
Applying documentation patch "commons-lang-event-support-docs.patch" from
Michael Wooten.
Modified:
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/EventListenerSupport.java
Modified:
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/EventListenerSupport.java
URL:
http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/EventListenerSupport.java?rev=978864&r1=978863&r2=978864&view=diff
==============================================================================
---
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/EventListenerSupport.java
(original)
+++
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/EventListenerSupport.java
Sat Jul 24 12:49:38 2010
@@ -17,56 +17,88 @@
package org.apache.commons.lang3.event;
-import org.apache.commons.lang3.Validate;
-
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
+import org.apache.commons.lang3.Validate;
+
/**
- * An EventListenerSupport object can be used to manage a list of event
listeners of a particular type.
+ * An EventListenerSupport object can be used to manage a list of event
+ * listeners of a particular type. The class provides
+ * {...@link #addListener(Object)} and {...@link #removeListener(Object)}
methods
+ * for registering listeners, as well as a {...@link #fire()} method for firing
+ * events to the listeners.
+ *
* <p/>
* To use this class, suppose you want to support ActionEvents. You would do:
- * <pre>
+ * <code><pre>
* public class MyActionEventSource
* {
- * private EventListenerSupport<ActionListener> actionListeners =
EventListenerSupport.create(ActionListener.class);
- * <p/>
+ * private EventListenerSupport<ActionListener> actionListeners =
+ * EventListenerSupport.create(ActionListener.class);
+ *
* public void someMethodThatFiresAction()
* {
* ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
"somethingCool");
* actionListeners.fire().actionPerformed(e);
* }
* }
- * </pre>
+ * </pre></code>
*
- * @param <L> The event listener type
+ * @param <L> the type of event listener that is supported by this proxy.
*
* @since 3.0
* @version $Id$
*/
public class EventListenerSupport<L>
{
+ /**
+ * The list used to hold the registered listeners. This list is
+ * intentionally a thread-safe copy-on-write-array so that traversals over
+ * the list of listeners will be atomic.
+ */
private final List<L> listeners = new CopyOnWriteArrayList<L>();
+
+ /**
+ * The proxy representing the collection of listeners. Calls to this proxy
+ * object will sent to all registered listeners.
+ */
private final L proxy;
/**
- * Creates an EventListenerSupport object which supports the specified
listener type.
+ * Creates an EventListenerSupport object which supports the specified
+ * listener type.
*
- * @param listenerType the listener type
- * @return an EventListenerSupport object which supports the specified
listener type
- */
- public static <T> EventListenerSupport<T> create(Class<T> listenerType)
- {
- return new EventListenerSupport<T>(listenerType);
+ * @param listenerInterface the type of listener interface that will
receive
+ * events posted using this class.
+ *
+ * @return an EventListenerSupport object which supports the specified
+ * listener type.
+ *
+ * @throws NullPointerException if <code>listenerInterface</code> is
+ * <code>null</code>.
+ * @throws IllegalArgumentException if <code>listenerInterface</code> is
+ * not an interface.
+ */
+ public static <T> EventListenerSupport<T> create(Class<T>
listenerInterface)
+ {
+ return new EventListenerSupport<T>(listenerInterface);
}
/**
- * Creates an EventListenerSupport object which supports the provided
listener interface.
- *
- * @param listenerInterface the listener interface
+ * Creates an EventListenerSupport object which supports the provided
+ * listener interface.
+ *
+ * @param listenerInterface the type of listener interface that will
receive
+ * events posted using this class.
+ *
+ * @throws NullPointerException if <code>listenerInterface</code> is
+ * <code>null</code>.
+ * @throws IllegalArgumentException if <code>listenerInterface</code> is
+ * not an interface.
*/
public EventListenerSupport(Class<L> listenerInterface)
{
@@ -74,25 +106,37 @@ public class EventListenerSupport<L>
}
/**
- * Creates an EventListenerSupport object which supports the provided
listener interface using the specified
- * class loader to create the JDK dynamic proxy.
- *
- * @param listenerInterface the listener interface
- * @param classLoader the class loader
+ * Creates an EventListenerSupport object which supports the provided
+ * listener interface using the specified class loader to create the JDK
+ * dynamic proxy.
+ *
+ * @param listenerInterface the listener interface.
+ * @param classLoader the class loader.
+ *
+ * @throws NullPointerException if <code>listenerInterface</code> or
+ * <code>classLoader</code> is <code>null</code>.
+ * @throws IllegalArgumentException if <code>listenerInterface</code> is
+ * not an interface.
*/
public EventListenerSupport(Class<L> listenerInterface, ClassLoader
classLoader)
{
Validate.notNull(listenerInterface, "Listener interface cannot be
null.");
Validate.notNull(classLoader, "ClassLoader cannot be null.");
- Validate.isTrue(listenerInterface.isInterface(), "Class {0} is not an
interface", listenerInterface.getName());
- proxy = listenerInterface.cast(Proxy.newProxyInstance(classLoader, new
Class[]{listenerInterface},
+ Validate.isTrue(listenerInterface.isInterface(),
+ "Class {0} is not an interface",
+ listenerInterface.getName());
+ proxy = listenerInterface.cast(Proxy.newProxyInstance(classLoader,
+ new Class[]{listenerInterface},
new ProxyInvocationHandler()));
}
/**
- * Returns a proxy object which can be used to call listener methods on
all of the registered event listeners.
+ * Returns a proxy object which can be used to call listener methods on
all
+ * of the registered event listeners. All calls made to this proxy will be
+ * forwarded to all registered listeners.
*
- * @return a proxy object which can be used to call listener methods on
all of the registered event listeners
+ * @return a proxy object which can be used to call listener methods on
all
+ * of the registered event listeners
*/
public L fire()
{
@@ -106,7 +150,10 @@ public class EventListenerSupport<L>
/**
* Registers an event listener.
*
- * @param listener the event listener
+ * @param listener the event listener (may not be <code>null</code>).
+ *
+ * @throws NullPointerException if <code>listener</code> is
+ * <code>null</code>.
*/
public void addListener(L listener)
{
@@ -117,9 +164,9 @@ public class EventListenerSupport<L>
/**
* Returns the number of registered listeners.
*
- * @return the number of registered listeners
+ * @return the number of registered listeners.
*/
- public int getListenerCount()
+ int getListenerCount()
{
return listeners.size();
}
@@ -127,7 +174,10 @@ public class EventListenerSupport<L>
/**
* Unregisters an event listener.
*
- * @param listener the event listener
+ * @param listener the event listener (may not be <code>null</code>).
+ *
+ * @throws NullPointerException if <code>listener</code> is
+ * <code>null</code>.
*/
public void removeListener(L listener)
{
@@ -140,7 +190,18 @@ public class EventListenerSupport<L>
*/
private class ProxyInvocationHandler implements InvocationHandler
{
- public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
+ /**
+ * Propagates the method call to all registered listeners in place of
+ * the proxy listener object.
+ *
+ * @param proxy the proxy object representing a listener on which the
+ * invocation was called.
+ * @param method the listener method that will be called on all of the
+ * listeners.
+ * @param args event arguments to propogate to the listeners.
+ */
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable
{
for (L listener : listeners)
{