mirror of
https://github.com/apache/commons-lang.git
synced 2025-02-08 11:05:09 +00:00
LANG-580: Add Event Support Utilities
Applying documentation patch "commons-lang-event-support-docs.patch" from Michael Wooten. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@978864 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
b1ba66c46e
commit
9a40cd0194
@ -17,56 +17,88 @@
|
|||||||
|
|
||||||
package org.apache.commons.lang3.event;
|
package org.apache.commons.lang3.event;
|
||||||
|
|
||||||
import org.apache.commons.lang3.Validate;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
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/>
|
* <p/>
|
||||||
* To use this class, suppose you want to support ActionEvents. You would do:
|
* To use this class, suppose you want to support ActionEvents. You would do:
|
||||||
* <pre>
|
* <code><pre>
|
||||||
* public class MyActionEventSource
|
* public class MyActionEventSource
|
||||||
* {
|
* {
|
||||||
* private EventListenerSupport<ActionListener> actionListeners = EventListenerSupport.create(ActionListener.class);
|
* private EventListenerSupport<ActionListener> actionListeners =
|
||||||
* <p/>
|
* EventListenerSupport.create(ActionListener.class);
|
||||||
|
*
|
||||||
* public void someMethodThatFiresAction()
|
* public void someMethodThatFiresAction()
|
||||||
* {
|
* {
|
||||||
* ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "somethingCool");
|
* ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "somethingCool");
|
||||||
* actionListeners.fire().actionPerformed(e);
|
* 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
|
* @since 3.0
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class EventListenerSupport<L>
|
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>();
|
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;
|
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
|
* @param listenerInterface the type of listener interface that will receive
|
||||||
* @return an EventListenerSupport object which supports the specified listener type
|
* 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> listenerType)
|
public static <T> EventListenerSupport<T> create(Class<T> listenerInterface)
|
||||||
{
|
{
|
||||||
return new EventListenerSupport<T>(listenerType);
|
return new EventListenerSupport<T>(listenerInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an EventListenerSupport object which supports the provided listener interface.
|
* Creates an EventListenerSupport object which supports the provided
|
||||||
|
* listener interface.
|
||||||
*
|
*
|
||||||
* @param listenerInterface the 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)
|
public EventListenerSupport(Class<L> listenerInterface)
|
||||||
{
|
{
|
||||||
@ -74,25 +106,37 @@ public EventListenerSupport(Class<L> listenerInterface)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an EventListenerSupport object which supports the provided listener interface using the specified
|
* Creates an EventListenerSupport object which supports the provided
|
||||||
* class loader to create the JDK dynamic proxy.
|
* listener interface using the specified class loader to create the JDK
|
||||||
|
* dynamic proxy.
|
||||||
*
|
*
|
||||||
* @param listenerInterface the listener interface
|
* @param listenerInterface the listener interface.
|
||||||
* @param classLoader the class loader
|
* @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)
|
public EventListenerSupport(Class<L> listenerInterface, ClassLoader classLoader)
|
||||||
{
|
{
|
||||||
Validate.notNull(listenerInterface, "Listener interface cannot be null.");
|
Validate.notNull(listenerInterface, "Listener interface cannot be null.");
|
||||||
Validate.notNull(classLoader, "ClassLoader cannot be null.");
|
Validate.notNull(classLoader, "ClassLoader cannot be null.");
|
||||||
Validate.isTrue(listenerInterface.isInterface(), "Class {0} is not an interface", listenerInterface.getName());
|
Validate.isTrue(listenerInterface.isInterface(),
|
||||||
proxy = listenerInterface.cast(Proxy.newProxyInstance(classLoader, new Class[]{listenerInterface},
|
"Class {0} is not an interface",
|
||||||
|
listenerInterface.getName());
|
||||||
|
proxy = listenerInterface.cast(Proxy.newProxyInstance(classLoader,
|
||||||
|
new Class[]{listenerInterface},
|
||||||
new ProxyInvocationHandler()));
|
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()
|
public L fire()
|
||||||
{
|
{
|
||||||
@ -106,7 +150,10 @@ public L fire()
|
|||||||
/**
|
/**
|
||||||
* Registers an event listener.
|
* 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)
|
public void addListener(L listener)
|
||||||
{
|
{
|
||||||
@ -117,9 +164,9 @@ public void addListener(L listener)
|
|||||||
/**
|
/**
|
||||||
* Returns the number of registered listeners.
|
* 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();
|
return listeners.size();
|
||||||
}
|
}
|
||||||
@ -127,7 +174,10 @@ public int getListenerCount()
|
|||||||
/**
|
/**
|
||||||
* Unregisters an event listener.
|
* 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)
|
public void removeListener(L listener)
|
||||||
{
|
{
|
||||||
@ -140,7 +190,18 @@ public void removeListener(L listener)
|
|||||||
*/
|
*/
|
||||||
private class ProxyInvocationHandler implements InvocationHandler
|
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)
|
for (L listener : listeners)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user