You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

EventRouter.java 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /*
  2. @VaadinApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.event;
  5. import java.lang.reflect.Method;
  6. import java.util.ArrayList;
  7. import java.util.Collection;
  8. import java.util.EventObject;
  9. import java.util.Iterator;
  10. import java.util.LinkedHashSet;
  11. import java.util.List;
  12. /**
  13. * <code>EventRouter</code> class implementing the inheritable event listening
  14. * model. For more information on the event model see the
  15. * {@link com.vaadin.event package documentation}.
  16. *
  17. * @author Vaadin Ltd.
  18. * @since 3.0
  19. */
  20. @SuppressWarnings("serial")
  21. public class EventRouter implements MethodEventSource {
  22. /**
  23. * List of registered listeners.
  24. */
  25. private LinkedHashSet<ListenerMethod> listenerList = null;
  26. /*
  27. * Registers a new listener with the specified activation method to listen
  28. * events generated by this component. Don't add a JavaDoc comment here, we
  29. * use the default documentation from implemented interface.
  30. */
  31. @Override
  32. public void addListener(Class<?> eventType, Object object, Method method) {
  33. if (listenerList == null) {
  34. listenerList = new LinkedHashSet<ListenerMethod>();
  35. }
  36. listenerList.add(new ListenerMethod(eventType, object, method));
  37. }
  38. /*
  39. * Registers a new listener with the specified named activation method to
  40. * listen events generated by this component. Don't add a JavaDoc comment
  41. * here, we use the default documentation from implemented interface.
  42. */
  43. @Override
  44. public void addListener(Class<?> eventType, Object object, String methodName) {
  45. if (listenerList == null) {
  46. listenerList = new LinkedHashSet<ListenerMethod>();
  47. }
  48. listenerList.add(new ListenerMethod(eventType, object, methodName));
  49. }
  50. /*
  51. * Removes all registered listeners matching the given parameters. Don't add
  52. * a JavaDoc comment here, we use the default documentation from implemented
  53. * interface.
  54. */
  55. @Override
  56. public void removeListener(Class<?> eventType, Object target) {
  57. if (listenerList != null) {
  58. final Iterator<ListenerMethod> i = listenerList.iterator();
  59. while (i.hasNext()) {
  60. final ListenerMethod lm = i.next();
  61. if (lm.matches(eventType, target)) {
  62. i.remove();
  63. return;
  64. }
  65. }
  66. }
  67. }
  68. /*
  69. * Removes the event listener methods matching the given given paramaters.
  70. * Don't add a JavaDoc comment here, we use the default documentation from
  71. * implemented interface.
  72. */
  73. @Override
  74. public void removeListener(Class<?> eventType, Object target, Method method) {
  75. if (listenerList != null) {
  76. final Iterator<ListenerMethod> i = listenerList.iterator();
  77. while (i.hasNext()) {
  78. final ListenerMethod lm = i.next();
  79. if (lm.matches(eventType, target, method)) {
  80. i.remove();
  81. return;
  82. }
  83. }
  84. }
  85. }
  86. /*
  87. * Removes the event listener method matching the given given parameters.
  88. * Don't add a JavaDoc comment here, we use the default documentation from
  89. * implemented interface.
  90. */
  91. @Override
  92. public void removeListener(Class<?> eventType, Object target,
  93. String methodName) {
  94. // Find the correct method
  95. final Method[] methods = target.getClass().getMethods();
  96. Method method = null;
  97. for (int i = 0; i < methods.length; i++) {
  98. if (methods[i].getName().equals(methodName)) {
  99. method = methods[i];
  100. }
  101. }
  102. if (method == null) {
  103. throw new IllegalArgumentException();
  104. }
  105. // Remove the listeners
  106. if (listenerList != null) {
  107. final Iterator<ListenerMethod> i = listenerList.iterator();
  108. while (i.hasNext()) {
  109. final ListenerMethod lm = i.next();
  110. if (lm.matches(eventType, target, method)) {
  111. i.remove();
  112. return;
  113. }
  114. }
  115. }
  116. }
  117. /**
  118. * Removes all listeners from event router.
  119. */
  120. public void removeAllListeners() {
  121. listenerList = null;
  122. }
  123. /**
  124. * Sends an event to all registered listeners. The listeners will decide if
  125. * the activation method should be called or not.
  126. *
  127. * @param event
  128. * the Event to be sent to all listeners.
  129. */
  130. public void fireEvent(EventObject event) {
  131. // It is not necessary to send any events if there are no listeners
  132. if (listenerList != null) {
  133. // Make a copy of the listener list to allow listeners to be added
  134. // inside listener methods. Fixes #3605.
  135. // Send the event to all listeners. The listeners themselves
  136. // will filter out unwanted events.
  137. final Object[] listeners = listenerList.toArray();
  138. for (int i = 0; i < listeners.length; i++) {
  139. ((ListenerMethod) listeners[i]).receiveEvent(event);
  140. }
  141. }
  142. }
  143. /**
  144. * Checks if the given Event type is listened by a listener registered to
  145. * this router.
  146. *
  147. * @param eventType
  148. * the event type to be checked
  149. * @return true if a listener is registered for the given event type
  150. */
  151. public boolean hasListeners(Class<?> eventType) {
  152. if (listenerList != null) {
  153. for (ListenerMethod lm : listenerList) {
  154. if (lm.isType(eventType)) {
  155. return true;
  156. }
  157. }
  158. }
  159. return false;
  160. }
  161. /**
  162. * Returns all listeners that match or extend the given event type.
  163. *
  164. * @param eventType
  165. * The type of event to return listeners for.
  166. * @return A collection with all registered listeners. Empty if no listeners
  167. * are found.
  168. */
  169. public Collection<?> getListeners(Class<?> eventType) {
  170. List<Object> listeners = new ArrayList<Object>();
  171. if (listenerList != null) {
  172. for (ListenerMethod lm : listenerList) {
  173. if (lm.isOrExtendsType(eventType)) {
  174. listeners.add(lm.getTarget());
  175. }
  176. }
  177. }
  178. return listeners;
  179. }
  180. }