1. /*
  2. * @(#)EventSetDescriptor.java 1.47 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.beans;
  8. import java.lang.reflect.*;
  9. /**
  10. * An EventSetDescriptor describes a group of events that a given Java
  11. * bean fires.
  12. * <P>
  13. * The given group of events are all delivered as method calls on a single
  14. * event listener interface, and an event listener object can be registered
  15. * via a call on a registration method supplied by the event source.
  16. */
  17. public class EventSetDescriptor extends FeatureDescriptor {
  18. /**
  19. * This constructor creates an EventSetDescriptor assuming that you are
  20. * following the most simple standard design pattern where a named
  21. * event "fred" is (1) delivered as a call on the single method of
  22. * interface FredListener, (2) has a single argument of type FredEvent,
  23. * and (3) where the FredListener may be registered with a call on an
  24. * addFredListener method of the source component and removed with a
  25. * call on a removeFredListener method.
  26. *
  27. * @param sourceClass The class firing the event.
  28. * @param eventSetName The programmatic name of the event. E.g. "fred".
  29. * Note that this should normally start with a lower-case character.
  30. * @param listenerType The target interface that events
  31. * will get delivered to.
  32. * @param listenerMethodName The method that will get called when the event gets
  33. * delivered to its target listener interface.
  34. * @exception IntrospectionException if an exception occurs during
  35. * introspection.
  36. */
  37. public EventSetDescriptor(Class sourceClass, String eventSetName,
  38. Class listenerType, String listenerMethodName)
  39. throws IntrospectionException {
  40. setName(eventSetName);
  41. // Get a Class object for the listener class.
  42. this.listenerType = listenerType;
  43. listenerMethods = new Method[1];
  44. listenerMethods[0] = Introspector.findMethod(listenerType,
  45. listenerMethodName, 1);
  46. String listenerClassName = listenerType.getName();
  47. String tail = listenerClassName.substring(listenerClassName.lastIndexOf('.') + 1);
  48. String addMethodName = "add" + tail;
  49. addMethod = Introspector.findMethod(sourceClass, addMethodName, 1);
  50. String removeMethodName = "remove" + tail;
  51. removeMethod = Introspector.findMethod(sourceClass, removeMethodName, 1);
  52. }
  53. /**
  54. * This constructor creates an EventSetDescriptor from scratch using
  55. * string names.
  56. *
  57. * @param sourceClass The class firing the event.
  58. * @param eventSetName The programmatic name of the event set.
  59. * Note that this should normally start with a lower-case character.
  60. * @param listenerType The Class of the target interface that events
  61. * will get delivered to.
  62. * @param listenerMethodNames The names of the methods that will get called
  63. * when the event gets delivered to its target listener interface.
  64. * @param addListenerMethodName The name of the method on the event source
  65. * that can be used to register an event listener object.
  66. * @param removeListenerMethodName The name of the method on the event source
  67. * that can be used to de-register an event listener object.
  68. * @exception IntrospectionException if an exception occurs during
  69. * introspection.
  70. */
  71. public EventSetDescriptor(Class sourceClass,
  72. String eventSetName,
  73. Class listenerType,
  74. String listenerMethodNames[],
  75. String addListenerMethodName,
  76. String removeListenerMethodName)
  77. throws IntrospectionException {
  78. setName(eventSetName);
  79. listenerMethods = new Method[listenerMethodNames.length];
  80. for (int i = 0; i < listenerMethods.length; i++) {
  81. String listenerName = listenerMethodNames[i];
  82. if (listenerName == null) {
  83. throw new NullPointerException();
  84. }
  85. listenerMethods[i] = Introspector.findMethod(listenerType,
  86. listenerName, 1);
  87. }
  88. this.addMethod = Introspector.findMethod(sourceClass,
  89. addListenerMethodName, 1);
  90. this.removeMethod = Introspector.findMethod(sourceClass,
  91. removeListenerMethodName, 1);
  92. this.listenerType = listenerType;
  93. }
  94. /**
  95. * This constructor creates an EventSetDescriptor from scratch using
  96. * java.lang.reflect.Method and java.lang.Class objects.
  97. *
  98. * @param eventSetName The programmatic name of the event set.
  99. * @param listenerType The Class for the listener interface.
  100. * @param listenerMethods An array of Method objects describing each
  101. * of the event handling methods in the target listener.
  102. * @param addListenerMethod The method on the event source
  103. * that can be used to register an event listener object.
  104. * @param removeListenerMethod The method on the event source
  105. * that can be used to de-register an event listener object.
  106. * @exception IntrospectionException if an exception occurs during
  107. * introspection.
  108. */
  109. public EventSetDescriptor(String eventSetName,
  110. Class listenerType,
  111. Method listenerMethods[],
  112. Method addListenerMethod,
  113. Method removeListenerMethod)
  114. throws IntrospectionException {
  115. setName(eventSetName);
  116. this.listenerMethods = listenerMethods;
  117. this.addMethod = addListenerMethod;
  118. this.removeMethod = removeListenerMethod;
  119. this.listenerType = listenerType;
  120. }
  121. /**
  122. * This constructor creates an EventSetDescriptor from scratch using
  123. * java.lang.reflect.MethodDescriptor and java.lang.Class objects.
  124. *
  125. * @param eventSetName The programmatic name of the event set.
  126. * @param listenerType The Class for the listener interface.
  127. * @param listenerMethodDescriptors An array of MethodDescriptor objects
  128. * describing each of the event handling methods in the
  129. * target listener.
  130. * @param addListenerMethod The method on the event source
  131. * that can be used to register an event listener object.
  132. * @param removeListenerMethod The method on the event source
  133. * that can be used to de-register an event listener object.
  134. * @exception IntrospectionException if an exception occurs during
  135. * introspection.
  136. */
  137. public EventSetDescriptor(String eventSetName,
  138. Class listenerType,
  139. MethodDescriptor listenerMethodDescriptors[],
  140. Method addListenerMethod,
  141. Method removeListenerMethod)
  142. throws IntrospectionException {
  143. setName(eventSetName);
  144. this.listenerMethodDescriptors = listenerMethodDescriptors;
  145. this.addMethod = addListenerMethod;
  146. this.removeMethod = removeListenerMethod;
  147. this.listenerType = listenerType;
  148. }
  149. /**
  150. * Gets the Class object for the target interface.
  151. *
  152. * @return The Class object for the target interface that will
  153. * get invoked when the event is fired.
  154. */
  155. public Class getListenerType() {
  156. return listenerType;
  157. }
  158. /**
  159. * Gets the methods of the target listener interface.
  160. *
  161. * @return An array of Method objects for the target methods
  162. * within the target listener interface that will get called when
  163. * events are fired.
  164. */
  165. public Method[] getListenerMethods() {
  166. if (listenerMethods == null && listenerMethodDescriptors != null) {
  167. // Create Method array from MethodDescriptor array.
  168. listenerMethods = new Method[listenerMethodDescriptors.length];
  169. for (int i = 0; i < listenerMethods.length; i++) {
  170. listenerMethods[i] = listenerMethodDescriptors[i].getMethod();
  171. }
  172. }
  173. return listenerMethods;
  174. }
  175. /**
  176. * Gets the <code>MethodDescriptor</code>s of the target listener interface.
  177. *
  178. * @return An array of MethodDescriptor objects for the target methods
  179. * within the target listener interface that will get called when
  180. * events are fired.
  181. */
  182. public MethodDescriptor[] getListenerMethodDescriptors() {
  183. if (listenerMethodDescriptors == null && listenerMethods != null) {
  184. // Create MethodDescriptor array from Method array.
  185. listenerMethodDescriptors =
  186. new MethodDescriptor[listenerMethods.length];
  187. for (int i = 0; i < listenerMethods.length; i++) {
  188. listenerMethodDescriptors[i] =
  189. new MethodDescriptor(listenerMethods[i]);
  190. }
  191. }
  192. return listenerMethodDescriptors;
  193. }
  194. /**
  195. * Gets the method used to add event listeners.
  196. *
  197. * @return The method used to register a listener at the event source.
  198. */
  199. public Method getAddListenerMethod() {
  200. return addMethod;
  201. }
  202. /**
  203. * Gets the method used to remove event listeners.
  204. *
  205. * @return The method used to remove a listener at the event source.
  206. */
  207. public Method getRemoveListenerMethod() {
  208. return removeMethod;
  209. }
  210. /**
  211. * Mark an event set as unicast (or not).
  212. *
  213. * @param unicast True if the event set is unicast.
  214. */
  215. public void setUnicast(boolean unicast) {
  216. this.unicast = unicast;
  217. }
  218. /**
  219. * Normally event sources are multicast. However there are some
  220. * exceptions that are strictly unicast.
  221. *
  222. * @return True if the event set is unicast. Defaults to "false".
  223. */
  224. public boolean isUnicast() {
  225. return unicast;
  226. }
  227. /**
  228. * Mark an event set as being in the "default" set (or not).
  229. * By default this is true.
  230. *
  231. * @param unicast True if the event set is unicast.
  232. */
  233. public void setInDefaultEventSet(boolean inDefaultEventSet) {
  234. this.inDefaultEventSet = inDefaultEventSet;
  235. }
  236. /**
  237. * Report if an event set is in the "default set".
  238. *
  239. * @return True if the event set is in the "default set". Defaults to "true".
  240. */
  241. public boolean isInDefaultEventSet() {
  242. return inDefaultEventSet;
  243. }
  244. /*
  245. * Package-private constructor
  246. * Merge two event set descriptors. Where they conflict, give the
  247. * second argument (y) priority over the first argument (x).
  248. *
  249. * @param x The first (lower priority) EventSetDescriptor
  250. * @param y The second (higher priority) EventSetDescriptor
  251. */
  252. EventSetDescriptor(EventSetDescriptor x, EventSetDescriptor y) {
  253. super(x,y);
  254. listenerMethodDescriptors = x.listenerMethodDescriptors;
  255. if (y.listenerMethodDescriptors != null) {
  256. listenerMethodDescriptors = y.listenerMethodDescriptors;
  257. }
  258. if (listenerMethodDescriptors == null) {
  259. listenerMethods = y.listenerMethods;
  260. }
  261. addMethod = y.addMethod;
  262. removeMethod = y.removeMethod;
  263. unicast = y.unicast;
  264. listenerType = y.listenerType;
  265. if (!x.inDefaultEventSet || !y.inDefaultEventSet) {
  266. inDefaultEventSet = false;
  267. }
  268. }
  269. /*
  270. * Package-private dup constructor
  271. * This must isolate the new object from any changes to the old object.
  272. */
  273. EventSetDescriptor(EventSetDescriptor old) {
  274. super(old);
  275. if (old.listenerMethodDescriptors != null) {
  276. int len = old.listenerMethodDescriptors.length;
  277. listenerMethodDescriptors = new MethodDescriptor[len];
  278. for (int i = 0; i < len; i++) {
  279. listenerMethodDescriptors[i] = new MethodDescriptor(
  280. old.listenerMethodDescriptors[i]);
  281. }
  282. }
  283. if (old.listenerMethods != null) {
  284. int len = old.listenerMethods.length;
  285. listenerMethods = new Method[len];
  286. for (int i = 0; i < len; i++) {
  287. listenerMethods[i] = old.listenerMethods[i];
  288. }
  289. }
  290. addMethod = old.addMethod;
  291. removeMethod = old.removeMethod;
  292. unicast = old.unicast;
  293. listenerType = old.listenerType;
  294. inDefaultEventSet = old.inDefaultEventSet;
  295. }
  296. private Class listenerType;
  297. private Method[] listenerMethods;
  298. private MethodDescriptor[] listenerMethodDescriptors;
  299. private Method addMethod;
  300. private Method removeMethod;
  301. private boolean unicast;
  302. private boolean inDefaultEventSet = true;
  303. }