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