From 88b3d7f78058f9c3b5b8e32982840d7280c0efab Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Tue, 19 Apr 2011 13:20:32 +0000 Subject: [PATCH] #1410 getListeners method for all classes that have addListener/removeListener svn changeset:18390/svn branch:6.6 --- .../vaadin/data/util/AbstractContainer.java | 21 ++++ .../vaadin/data/util/AbstractProperty.java | 22 ++++ .../vaadin/data/util/IndexedContainer.java | 13 ++ src/com/vaadin/data/util/PropertysetItem.java | 13 ++ src/com/vaadin/event/EventRouter.java | 26 +++- src/com/vaadin/event/ListenerMethod.java | 114 +++++++++++------- src/com/vaadin/ui/AbstractComponent.java | 27 +++++ src/com/vaadin/ui/AbstractSelect.java | 20 +++ src/com/vaadin/ui/Upload.java | 14 +++ 9 files changed, 226 insertions(+), 44 deletions(-) diff --git a/src/com/vaadin/data/util/AbstractContainer.java b/src/com/vaadin/data/util/AbstractContainer.java index 53b9e75ba8..eed58c578a 100644 --- a/src/com/vaadin/data/util/AbstractContainer.java +++ b/src/com/vaadin/data/util/AbstractContainer.java @@ -2,6 +2,7 @@ package com.vaadin.data.util; import java.io.Serializable; import java.util.Collection; +import java.util.Collections; import java.util.EventObject; import java.util.LinkedList; @@ -222,4 +223,24 @@ public abstract class AbstractContainer implements Container { return itemSetChangeListeners; } + public Collection getListeners(Class eventType) { + if (Container.PropertySetChangeEvent.class.isAssignableFrom(eventType)) { + if (propertySetChangeListeners == null) { + return Collections.EMPTY_LIST; + } else { + return Collections + .unmodifiableCollection(propertySetChangeListeners); + } + } else if (Container.ItemSetChangeEvent.class + .isAssignableFrom(eventType)) { + if (itemSetChangeListeners == null) { + return Collections.EMPTY_LIST; + } else { + return Collections + .unmodifiableCollection(itemSetChangeListeners); + } + } + + return Collections.EMPTY_LIST; + } } diff --git a/src/com/vaadin/data/util/AbstractProperty.java b/src/com/vaadin/data/util/AbstractProperty.java index 2b3fcf2c93..953ab664a3 100644 --- a/src/com/vaadin/data/util/AbstractProperty.java +++ b/src/com/vaadin/data/util/AbstractProperty.java @@ -1,5 +1,7 @@ package com.vaadin.data.util; +import java.util.Collection; +import java.util.Collections; import java.util.LinkedList; import com.vaadin.data.Property; @@ -191,4 +193,24 @@ public abstract class AbstractProperty implements Property, } } + public Collection getListeners(Class eventType) { + if (Property.ValueChangeEvent.class.isAssignableFrom(eventType)) { + if (valueChangeListeners == null) { + return Collections.EMPTY_LIST; + } else { + return Collections.unmodifiableCollection(valueChangeListeners); + } + } else if (Property.ReadOnlyStatusChangeEvent.class + .isAssignableFrom(eventType)) { + if (readOnlyStatusChangeListeners == null) { + return Collections.EMPTY_LIST; + } else { + return Collections + .unmodifiableCollection(readOnlyStatusChangeListeners); + } + } + + return Collections.EMPTY_LIST; + } + } diff --git a/src/com/vaadin/data/util/IndexedContainer.java b/src/com/vaadin/data/util/IndexedContainer.java index 11e4c702ed..11ab3c2728 100644 --- a/src/com/vaadin/data/util/IndexedContainer.java +++ b/src/com/vaadin/data/util/IndexedContainer.java @@ -531,6 +531,19 @@ public class IndexedContainer extends } + @Override + public Collection getListeners(Class eventType) { + if (Property.ValueChangeEvent.class.isAssignableFrom(eventType)) { + if (propertyValueChangeListeners == null) { + return Collections.EMPTY_LIST; + } else { + return Collections + .unmodifiableCollection(propertyValueChangeListeners); + } + } + return super.getListeners(eventType); + } + @Override protected void fireItemAdded(int position, Object itemId, Item item) { if (position >= 0) { diff --git a/src/com/vaadin/data/util/PropertysetItem.java b/src/com/vaadin/data/util/PropertysetItem.java index 75f9114bc7..38be8561d0 100644 --- a/src/com/vaadin/data/util/PropertysetItem.java +++ b/src/com/vaadin/data/util/PropertysetItem.java @@ -220,6 +220,19 @@ public class PropertysetItem implements Item, Item.PropertySetChangeNotifier, } } + public Collection getListeners(Class eventType) { + if (Item.PropertySetChangeEvent.class.isAssignableFrom(eventType)) { + if (propertySetChangeListeners == null) { + return Collections.EMPTY_LIST; + } else { + return Collections + .unmodifiableCollection(propertySetChangeListeners); + } + } + + return Collections.EMPTY_LIST; + } + /** * Creates and returns a copy of this object. *

diff --git a/src/com/vaadin/event/EventRouter.java b/src/com/vaadin/event/EventRouter.java index dc4f67bf65..6332e4dd52 100644 --- a/src/com/vaadin/event/EventRouter.java +++ b/src/com/vaadin/event/EventRouter.java @@ -5,10 +5,12 @@ 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.Set; +import java.util.List; /** * EventRouter class implementing the inheritable event listening @@ -26,7 +28,7 @@ public class EventRouter implements MethodEventSource { /** * List of registered listeners. */ - private Set listenerList = null; + private LinkedHashSet listenerList = null; /* * Registers a new listener with the specified activation method to listen @@ -171,4 +173,24 @@ public class EventRouter implements MethodEventSource { } 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 listeners = new ArrayList(); + if (listenerList != null) { + for (ListenerMethod lm : listenerList) { + if (lm.isOrExtendsType(eventType)) { + listeners.add(lm.getTarget()); + } + } + } + return listeners; + } } diff --git a/src/com/vaadin/event/ListenerMethod.java b/src/com/vaadin/event/ListenerMethod.java index b8ec0b1828..11b22c4db8 100644 --- a/src/com/vaadin/event/ListenerMethod.java +++ b/src/com/vaadin/event/ListenerMethod.java @@ -55,7 +55,7 @@ public class ListenerMethod implements EventListener, Serializable { /** * The object containing the trigger method. */ - private final Object object; + private final Object target; /** * The trigger method to call when an event passing the given criteria @@ -85,7 +85,7 @@ public class ListenerMethod implements EventListener, Serializable { out.writeObject(paramTypes); } catch (NotSerializableException e) { logger.warning("Error in serialization of the application: Class " - + object.getClass().getName() + + target.getClass().getName() + " must implement serialization."); throw e; } @@ -101,7 +101,7 @@ public class ListenerMethod implements EventListener, Serializable { Class[] paramTypes = (Class[]) in.readObject(); // We can not use getMethod directly as we want to support anonymous // inner classes - method = findHighestMethod(object.getClass(), name, paramTypes); + method = findHighestMethod(target.getClass(), name, paramTypes); } catch (SecurityException e) { logger.log(Level.SEVERE, "Internal deserialization error", e); } @@ -149,7 +149,7 @@ public class ListenerMethod implements EventListener, Serializable { * @param eventType * the event type that is listener listens to. All events of this * kind (or its subclasses) result in calling the trigger method. - * @param object + * @param target * the object instance that contains the trigger method * @param method * the trigger method @@ -163,15 +163,15 @@ public class ListenerMethod implements EventListener, Serializable { * will not be passed to the trigger method, though it is still * called. * @throws java.lang.IllegalArgumentException - * if method is not a member of object - * . + * if method is not a member of + * listener . */ - public ListenerMethod(Class eventType, Object object, Method method, + public ListenerMethod(Class eventType, Object target, Method method, Object[] arguments, int eventArgumentIndex) throws java.lang.IllegalArgumentException { // Checks that the object is of correct type - if (!method.getDeclaringClass().isAssignableFrom(object.getClass())) { + if (!method.getDeclaringClass().isAssignableFrom(target.getClass())) { throw new java.lang.IllegalArgumentException(); } @@ -188,7 +188,7 @@ public class ListenerMethod implements EventListener, Serializable { } this.eventType = eventType; - this.object = object; + this.target = target; this.method = method; this.arguments = arguments; this.eventArgumentIndex = eventArgumentIndex; @@ -206,7 +206,7 @@ public class ListenerMethod implements EventListener, Serializable { * @param eventType * the event type that is listener listens to. All events of this * kind (or its subclasses) result in calling the trigger method. - * @param object + * @param target * the object instance that contains the trigger method. * @param methodName * the name of the trigger method. If the object does not contain @@ -223,14 +223,14 @@ public class ListenerMethod implements EventListener, Serializable { * called. * @throws java.lang.IllegalArgumentException * unless exactly one match methodName is found in - * object. + * listener. */ - public ListenerMethod(Class eventType, Object object, String methodName, + public ListenerMethod(Class eventType, Object target, String methodName, Object[] arguments, int eventArgumentIndex) throws java.lang.IllegalArgumentException { // Finds the correct method - final Method[] methods = object.getClass().getMethods(); + final Method[] methods = target.getClass().getMethods(); Method method = null; for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals(methodName)) { @@ -254,7 +254,7 @@ public class ListenerMethod implements EventListener, Serializable { } this.eventType = eventType; - this.object = object; + this.target = target; this.method = method; this.arguments = arguments; this.eventArgumentIndex = eventArgumentIndex; @@ -276,26 +276,26 @@ public class ListenerMethod implements EventListener, Serializable { * @param eventType * the event type that is listener listens to. All events of this * kind (or its subclasses) result in calling the trigger method. - * @param object + * @param target * the object instance that contains the trigger method. * @param method * the trigger method. * @param arguments * the arguments to be passed to the trigger method. * @throws java.lang.IllegalArgumentException - * if method is not a member of object - * . + * if method is not a member of + * listener . */ - public ListenerMethod(Class eventType, Object object, Method method, + public ListenerMethod(Class eventType, Object target, Method method, Object[] arguments) throws java.lang.IllegalArgumentException { // Check that the object is of correct type - if (!method.getDeclaringClass().isAssignableFrom(object.getClass())) { + if (!method.getDeclaringClass().isAssignableFrom(target.getClass())) { throw new java.lang.IllegalArgumentException(); } this.eventType = eventType; - this.object = object; + this.target = target; this.method = method; this.arguments = arguments; eventArgumentIndex = -1; @@ -310,7 +310,7 @@ public class ListenerMethod implements EventListener, Serializable { *

* *

- * The actual trigger method is reflected from object, and + * The actual trigger method is reflected from listener, and * java.lang.IllegalArgumentException is thrown unless exactly * one match is found. *

@@ -318,7 +318,7 @@ public class ListenerMethod implements EventListener, Serializable { * @param eventType * the event type that is listener listens to. All events of this * kind (or its subclasses) result in calling the trigger method. - * @param object + * @param target * the object instance that contains the trigger method. * @param methodName * the name of the trigger method. If the object does not contain @@ -330,11 +330,11 @@ public class ListenerMethod implements EventListener, Serializable { * unless exactly one match methodName is found in * object. */ - public ListenerMethod(Class eventType, Object object, String methodName, + public ListenerMethod(Class eventType, Object target, String methodName, Object[] arguments) throws java.lang.IllegalArgumentException { // Find the correct method - final Method[] methods = object.getClass().getMethods(); + final Method[] methods = target.getClass().getMethods(); Method method = null; for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals(methodName)) { @@ -346,7 +346,7 @@ public class ListenerMethod implements EventListener, Serializable { } this.eventType = eventType; - this.object = object; + this.target = target; this.method = method; this.arguments = arguments; eventArgumentIndex = -1; @@ -367,7 +367,7 @@ public class ListenerMethod implements EventListener, Serializable { * @param eventType * the event type that is listener listens to. All events of this * kind (or its subclasses) result in calling the trigger method. - * @param object + * @param target * the object instance that contains the trigger method. * @param method * the trigger method. @@ -375,16 +375,16 @@ public class ListenerMethod implements EventListener, Serializable { * if method is not a member of object * . */ - public ListenerMethod(Class eventType, Object object, Method method) + public ListenerMethod(Class eventType, Object target, Method method) throws java.lang.IllegalArgumentException { // Checks that the object is of correct type - if (!method.getDeclaringClass().isAssignableFrom(object.getClass())) { + if (!method.getDeclaringClass().isAssignableFrom(target.getClass())) { throw new java.lang.IllegalArgumentException(); } this.eventType = eventType; - this.object = object; + this.target = target; this.method = method; eventArgumentIndex = -1; @@ -416,7 +416,7 @@ public class ListenerMethod implements EventListener, Serializable { * @param eventType * the event type that is listener listens to. All events of this * kind (or its subclasses) result in calling the trigger method. - * @param object + * @param target * the object instance that contains the trigger method. * @param methodName * the name of the trigger method. If the object does not contain @@ -424,13 +424,13 @@ public class ListenerMethod implements EventListener, Serializable { * java.lang.IllegalArgumentException is thrown. * @throws java.lang.IllegalArgumentException * unless exactly one match methodName is found in - * object. + * listener. */ - public ListenerMethod(Class eventType, Object object, String methodName) + public ListenerMethod(Class eventType, Object target, String methodName) throws java.lang.IllegalArgumentException { // Finds the correct method - final Method[] methods = object.getClass().getMethods(); + final Method[] methods = target.getClass().getMethods(); Method method = null; for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals(methodName)) { @@ -442,7 +442,7 @@ public class ListenerMethod implements EventListener, Serializable { } this.eventType = eventType; - this.object = object; + this.target = target; this.method = method; eventArgumentIndex = -1; @@ -475,17 +475,17 @@ public class ListenerMethod implements EventListener, Serializable { try { if (eventArgumentIndex >= 0) { if (eventArgumentIndex == 0 && arguments.length == 1) { - method.invoke(object, new Object[] { event }); + method.invoke(target, new Object[] { event }); } else { final Object[] arg = new Object[arguments.length]; for (int i = 0; i < arg.length; i++) { arg[i] = arguments[i]; } arg[eventArgumentIndex] = event; - method.invoke(object, arg); + method.invoke(target, arg); } } else { - method.invoke(object, arguments); + method.invoke(target, arguments); } } catch (final java.lang.IllegalAccessException e) { @@ -516,7 +516,7 @@ public class ListenerMethod implements EventListener, Serializable { * the event type stored in this object. * */ public boolean matches(Class eventType, Object target) { - return (target == object) && (eventType.equals(this.eventType)); + return (this.target == target) && (eventType.equals(this.eventType)); } /** @@ -538,7 +538,7 @@ public class ListenerMethod implements EventListener, Serializable { * equals with the method stored in this object */ public boolean matches(Class eventType, Object target, Method method) { - return (target == object) + return (this.target == target) && (eventType.equals(this.eventType) && method .equals(this.method)); } @@ -549,7 +549,7 @@ public class ListenerMethod implements EventListener, Serializable { hash = 31 * hash + eventArgumentIndex; hash = 31 * hash + (eventType == null ? 0 : eventType.hashCode()); - hash = 31 * hash + (object == null ? 0 : object.hashCode()); + hash = 31 * hash + (target == null ? 0 : target.hashCode()); hash = 31 * hash + (method == null ? 0 : method.hashCode()); return hash; @@ -573,8 +573,8 @@ public class ListenerMethod implements EventListener, Serializable { return eventArgumentIndex == t.eventArgumentIndex && (eventType == t.eventType || (eventType != null && eventType .equals(t.eventType))) - && (object == t.object || (object != null && object - .equals(t.object))) + && (target == t.target || (target != null && target + .equals(t.target))) && (method == t.method || (method != null && method .equals(t.method))) && (arguments == t.arguments || (Arrays.equals(arguments, @@ -642,7 +642,37 @@ public class ListenerMethod implements EventListener, Serializable { } + /** + * Compares the type of this ListenerMethod to the given type + * + * @param eventType + * The type to compare with + * @return true if this type of this ListenerMethod matches the given type, + * false otherwise + */ public boolean isType(Class eventType) { return this.eventType == eventType; } + + /** + * Compares the type of this ListenerMethod to the given type + * + * @param eventType + * The type to compare with + * @return true if this event type can be assigned to the given type, false + * otherwise + */ + public boolean isOrExtendsType(Class eventType) { + return eventType.isAssignableFrom(this.eventType); + } + + /** + * Returns the target object which contains the trigger method. + * + * @return The target object + */ + public Object getTarget() { + return target; + } + } diff --git a/src/com/vaadin/ui/AbstractComponent.java b/src/com/vaadin/ui/AbstractComponent.java index f0938780fe..784ecb262b 100644 --- a/src/com/vaadin/ui/AbstractComponent.java +++ b/src/com/vaadin/ui/AbstractComponent.java @@ -8,6 +8,7 @@ import java.io.Serializable; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; @@ -1143,6 +1144,32 @@ public abstract class AbstractComponent implements Component, MethodEventSource } } + /** + * Returns all listeners that are registered for the given event type or one + * of its subclasses. + * + * @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) { + if (eventType.isAssignableFrom(RepaintRequestEvent.class)) { + // RepaintRequestListeners are not stored in eventRouter + if (repaintRequestListeners == null) { + return Collections.EMPTY_LIST; + } else { + return Collections + .unmodifiableCollection(repaintRequestListeners); + } + } + if (eventRouter == null) { + return Collections.EMPTY_LIST; + } + + return eventRouter.getListeners(eventType); + } + /** * Sends the event to all listeners. * diff --git a/src/com/vaadin/ui/AbstractSelect.java b/src/com/vaadin/ui/AbstractSelect.java index ab17498f7f..66ec7b0980 100644 --- a/src/com/vaadin/ui/AbstractSelect.java +++ b/src/com/vaadin/ui/AbstractSelect.java @@ -1454,6 +1454,26 @@ public abstract class AbstractSelect extends AbstractField implements } } + @Override + public Collection getListeners(Class eventType) { + if (Container.ItemSetChangeEvent.class.isAssignableFrom(eventType)) { + if (itemSetEventListeners == null) + return Collections.EMPTY_LIST; + else + return Collections + .unmodifiableCollection(itemSetEventListeners); + } else if (Container.PropertySetChangeEvent.class + .isAssignableFrom(eventType)) { + if (propertySetEventListeners == null) + return Collections.EMPTY_LIST; + else + return Collections + .unmodifiableCollection(propertySetEventListeners); + } + + return super.getListeners(eventType); + } + /** * Lets the listener know a Containers Item set has changed. * diff --git a/src/com/vaadin/ui/Upload.java b/src/com/vaadin/ui/Upload.java index 3928f809f3..0a8227699a 100644 --- a/src/com/vaadin/ui/Upload.java +++ b/src/com/vaadin/ui/Upload.java @@ -7,12 +7,14 @@ package com.vaadin.ui; import java.io.OutputStream; import java.io.Serializable; import java.lang.reflect.Method; +import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Map; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; +import com.vaadin.terminal.StreamVariable.StreamingProgressEvent; import com.vaadin.terminal.gwt.client.ui.VUpload; import com.vaadin.terminal.gwt.server.NoInputStreamException; import com.vaadin.terminal.gwt.server.NoOutputStreamException; @@ -1030,4 +1032,16 @@ public class Upload extends AbstractComponent implements Component.Focusable { return streamVariable; } + @Override + public java.util.Collection getListeners(java.lang.Class eventType) { + if (StreamingProgressEvent.class.isAssignableFrom(eventType)) { + if (progressListeners == null) { + return Collections.EMPTY_LIST; + } else { + return Collections.unmodifiableCollection(progressListeners); + } + + } + return super.getListeners(eventType); + }; } -- 2.39.5