diff options
Diffstat (limited to 'server/src/com/vaadin/event/EventRouter.java')
-rw-r--r-- | server/src/com/vaadin/event/EventRouter.java | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/server/src/com/vaadin/event/EventRouter.java b/server/src/com/vaadin/event/EventRouter.java new file mode 100644 index 0000000000..90c080b860 --- /dev/null +++ b/server/src/com/vaadin/event/EventRouter.java @@ -0,0 +1,201 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.event; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.EventObject; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; + +/** + * <code>EventRouter</code> class implementing the inheritable event listening + * model. For more information on the event model see the + * {@link com.vaadin.event package documentation}. + * + * @author Vaadin Ltd. + * @version + * @VERSION@ + * @since 3.0 + */ +@SuppressWarnings("serial") +public class EventRouter implements MethodEventSource { + + /** + * List of registered listeners. + */ + private LinkedHashSet<ListenerMethod> listenerList = null; + + /* + * Registers a new listener with the specified activation method to listen + * events generated by this component. Don't add a JavaDoc comment here, we + * use the default documentation from implemented interface. + */ + @Override + public void addListener(Class<?> eventType, Object object, Method method) { + if (listenerList == null) { + listenerList = new LinkedHashSet<ListenerMethod>(); + } + listenerList.add(new ListenerMethod(eventType, object, method)); + } + + /* + * Registers a new listener with the specified named activation method to + * listen events generated by this component. Don't add a JavaDoc comment + * here, we use the default documentation from implemented interface. + */ + @Override + public void addListener(Class<?> eventType, Object object, String methodName) { + if (listenerList == null) { + listenerList = new LinkedHashSet<ListenerMethod>(); + } + listenerList.add(new ListenerMethod(eventType, object, methodName)); + } + + /* + * Removes all registered listeners matching the given parameters. Don't add + * a JavaDoc comment here, we use the default documentation from implemented + * interface. + */ + @Override + public void removeListener(Class<?> eventType, Object target) { + if (listenerList != null) { + final Iterator<ListenerMethod> i = listenerList.iterator(); + while (i.hasNext()) { + final ListenerMethod lm = i.next(); + if (lm.matches(eventType, target)) { + i.remove(); + return; + } + } + } + } + + /* + * Removes the event listener methods matching the given given paramaters. + * Don't add a JavaDoc comment here, we use the default documentation from + * implemented interface. + */ + @Override + public void removeListener(Class<?> eventType, Object target, Method method) { + if (listenerList != null) { + final Iterator<ListenerMethod> i = listenerList.iterator(); + while (i.hasNext()) { + final ListenerMethod lm = i.next(); + if (lm.matches(eventType, target, method)) { + i.remove(); + return; + } + } + } + } + + /* + * Removes the event listener method matching the given given parameters. + * Don't add a JavaDoc comment here, we use the default documentation from + * implemented interface. + */ + @Override + public void removeListener(Class<?> eventType, Object target, + String methodName) { + + // Find the correct method + final Method[] methods = target.getClass().getMethods(); + Method method = null; + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().equals(methodName)) { + method = methods[i]; + } + } + if (method == null) { + throw new IllegalArgumentException(); + } + + // Remove the listeners + if (listenerList != null) { + final Iterator<ListenerMethod> i = listenerList.iterator(); + while (i.hasNext()) { + final ListenerMethod lm = i.next(); + if (lm.matches(eventType, target, method)) { + i.remove(); + return; + } + } + } + + } + + /** + * Removes all listeners from event router. + */ + public void removeAllListeners() { + listenerList = null; + } + + /** + * Sends an event to all registered listeners. The listeners will decide if + * the activation method should be called or not. + * + * @param event + * the Event to be sent to all listeners. + */ + public void fireEvent(EventObject event) { + // It is not necessary to send any events if there are no listeners + if (listenerList != null) { + + // Make a copy of the listener list to allow listeners to be added + // inside listener methods. Fixes #3605. + + // Send the event to all listeners. The listeners themselves + // will filter out unwanted events. + final Object[] listeners = listenerList.toArray(); + for (int i = 0; i < listeners.length; i++) { + ((ListenerMethod) listeners[i]).receiveEvent(event); + } + + } + } + + /** + * Checks if the given Event type is listened by a listener registered to + * this router. + * + * @param eventType + * the event type to be checked + * @return true if a listener is registered for the given event type + */ + public boolean hasListeners(Class<?> eventType) { + if (listenerList != null) { + for (ListenerMethod lm : listenerList) { + if (lm.isType(eventType)) { + return true; + } + } + } + return false; + } + + /** + * Returns all listeners that match or extend the given event type. + * + * @param eventType + * The type of event to return listeners for. + * @return A collection with all registered listeners. Empty if no listeners + * are found. + */ + public Collection<?> getListeners(Class<?> eventType) { + List<Object> listeners = new ArrayList<Object>(); + if (listenerList != null) { + for (ListenerMethod lm : listenerList) { + if (lm.isOrExtendsType(eventType)) { + listeners.add(lm.getTarget()); + } + } + } + return listeners; + } +} |