1:
37:
38:
39: package ;
40:
41: import ;
42:
43: import ;
44: import ;
45: import ;
46:
47:
90:
91: public class EventSetDescriptor extends FeatureDescriptor {
92: private Method addListenerMethod;
93: private Method removeListenerMethod;
94: private Class listenerType;
95: private MethodDescriptor[] listenerMethodDescriptors;
96: private Method[] listenerMethods;
97:
98: private boolean unicast;
99: private boolean inDefaultEventSet = true;
100:
101:
135: public EventSetDescriptor(Class eventSourceClass,
136: String eventSetName,
137: Class listenerType,
138: String listenerMethodName) throws IntrospectionException {
139: setName(eventSetName);
140: if(!java.util.EventListener.class.isAssignableFrom(listenerType)) {
141: throw new IntrospectionException("Listener type is not an EventListener.");
142: }
143:
144: String[] names = new String[1];
145: names[0] = listenerMethodName;
146:
147: try {
148: eventSetName = Character.toUpperCase(eventSetName.charAt(0)) + eventSetName.substring(1);
149: } catch(StringIndexOutOfBoundsException e) {
150: eventSetName = "";
151: }
152:
153: findMethods(eventSourceClass,listenerType,names,"add"+eventSetName+"Listener","remove"+eventSetName+"Listener",eventSetName+"Event");
154: this.listenerType = listenerType;
155: checkAddListenerUnicast();
156: if(this.removeListenerMethod.getExceptionTypes().length > 0) {
157: throw new IntrospectionException("Listener remove method throws exceptions.");
158: }
159: }
160:
161:
175: public EventSetDescriptor(Class eventSourceClass,
176: String eventSetName,
177: Class listenerType,
178: String[] listenerMethodNames,
179: String addListenerMethodName,
180: String removeListenerMethodName) throws IntrospectionException {
181: setName(eventSetName);
182: if(!java.util.EventListener.class.isAssignableFrom(listenerType)) {
183: throw new IntrospectionException("Listener type is not an EventListener.");
184: }
185:
186: findMethods(eventSourceClass,listenerType,listenerMethodNames,addListenerMethodName,removeListenerMethodName,null);
187: this.listenerType = listenerType;
188: checkAddListenerUnicast();
189: if(this.removeListenerMethod.getExceptionTypes().length > 0) {
190: throw new IntrospectionException("Listener remove method throws exceptions.");
191: }
192: }
193:
194:
207: public EventSetDescriptor(String eventSetName,
208: Class listenerType,
209: Method[] listenerMethods,
210: Method addListenerMethod,
211: Method removeListenerMethod) throws IntrospectionException {
212: setName(eventSetName);
213: if(!java.util.EventListener.class.isAssignableFrom(listenerType)) {
214: throw new IntrospectionException("Listener type is not an EventListener.");
215: }
216:
217: this.listenerMethods = listenerMethods;
218: this.addListenerMethod = addListenerMethod;
219: this.removeListenerMethod = removeListenerMethod;
220: this.listenerType = listenerType;
221: checkMethods();
222: checkAddListenerUnicast();
223: if(this.removeListenerMethod.getExceptionTypes().length > 0) {
224: throw new IntrospectionException("Listener remove method throws exceptions.");
225: }
226: }
227:
228:
241: public EventSetDescriptor(String eventSetName,
242: Class listenerType,
243: MethodDescriptor[] listenerMethodDescriptors,
244: Method addListenerMethod,
245: Method removeListenerMethod) throws IntrospectionException {
246: setName(eventSetName);
247: if(!java.util.EventListener.class.isAssignableFrom(listenerType)) {
248: throw new IntrospectionException("Listener type is not an EventListener.");
249: }
250:
251: this.listenerMethodDescriptors = listenerMethodDescriptors;
252: this.listenerMethods = new Method[listenerMethodDescriptors.length];
253: for(int i=0;i<this.listenerMethodDescriptors.length;i++) {
254: this.listenerMethods[i] = this.listenerMethodDescriptors[i].getMethod();
255: }
256:
257: this.addListenerMethod = addListenerMethod;
258: this.removeListenerMethod = removeListenerMethod;
259: this.listenerType = listenerType;
260: checkMethods();
261: checkAddListenerUnicast();
262: if(this.removeListenerMethod.getExceptionTypes().length > 0) {
263: throw new IntrospectionException("Listener remove method throws exceptions.");
264: }
265: }
266:
267:
268: public Class getListenerType() {
269: return listenerType;
270: }
271:
272:
273: public Method[] getListenerMethods() {
274: return listenerMethods;
275: }
276:
277:
278: public MethodDescriptor[] getListenerMethodDescriptors() {
279: if(listenerMethodDescriptors == null) {
280: listenerMethodDescriptors = new MethodDescriptor[listenerMethods.length];
281: for(int i=0;i<listenerMethods.length;i++) {
282: listenerMethodDescriptors[i] = new MethodDescriptor(listenerMethods[i]);
283: }
284: }
285: return listenerMethodDescriptors;
286: }
287:
288:
289: public Method getAddListenerMethod() {
290: return addListenerMethod;
291: }
292:
293:
294: public Method getRemoveListenerMethod() {
295: return removeListenerMethod;
296: }
297:
298:
301: public void setUnicast(boolean unicast) {
302: this.unicast = unicast;
303: }
304:
305:
306: public boolean isUnicast() {
307: return unicast;
308: }
309:
310:
313: public void setInDefaultEventSet(boolean inDefaultEventSet) {
314: this.inDefaultEventSet = inDefaultEventSet;
315: }
316:
317:
318: public boolean isInDefaultEventSet() {
319: return inDefaultEventSet;
320: }
321:
322: private void checkAddListenerUnicast() throws IntrospectionException {
323: Class[] addListenerExceptions = this.addListenerMethod.getExceptionTypes();
324: if(addListenerExceptions.length > 1) {
325: throw new IntrospectionException("Listener add method throws too many exceptions.");
326: } else if(addListenerExceptions.length == 1
327: && !java.util.TooManyListenersException.class.isAssignableFrom(addListenerExceptions[0])) {
328: throw new IntrospectionException("Listener add method throws too many exceptions.");
329: }
330: }
331:
332: private void checkMethods() throws IntrospectionException {
333: if(!addListenerMethod.getDeclaringClass().isAssignableFrom(removeListenerMethod.getDeclaringClass())
334: && !removeListenerMethod.getDeclaringClass().isAssignableFrom(addListenerMethod.getDeclaringClass())) {
335: throw new IntrospectionException("add and remove listener methods do not come from the same class. This is bad.");
336: }
337: if(!addListenerMethod.getReturnType().equals(java.lang.Void.TYPE)
338: || addListenerMethod.getParameterTypes().length != 1
339: || !listenerType.equals(addListenerMethod.getParameterTypes()[0])
340: || !Modifier.isPublic(addListenerMethod.getModifiers())) {
341: throw new IntrospectionException("Add Listener Method invalid.");
342: }
343: if(!removeListenerMethod.getReturnType().equals(java.lang.Void.TYPE)
344: || removeListenerMethod.getParameterTypes().length != 1
345: || !listenerType.equals(removeListenerMethod.getParameterTypes()[0])
346: || removeListenerMethod.getExceptionTypes().length > 0
347: || !Modifier.isPublic(removeListenerMethod.getModifiers())) {
348: throw new IntrospectionException("Remove Listener Method invalid.");
349: }
350:
351: for(int i=0;i<listenerMethods.length;i++) {
352: if(!listenerMethods[i].getReturnType().equals(java.lang.Void.TYPE)
353: || Modifier.isPrivate(listenerMethods[i].getModifiers())) {
354: throw new IntrospectionException("Event Method " + listenerMethods[i].getName() + " non-void or private.");
355: }
356: if(!listenerMethods[i].getDeclaringClass().isAssignableFrom(listenerType)) {
357: throw new IntrospectionException("Event Method " + listenerMethods[i].getName() + " not from class " + listenerType.getName());
358: }
359: }
360: }
361:
362: private void findMethods(Class eventSourceClass,
363: Class listenerType,
364: String listenerMethodNames[],
365: String addListenerMethodName,
366: String removeListenerMethodName,
367: String absurdEventClassCheckName) throws IntrospectionException {
368:
369:
370: Class[] listenerArgList = new Class[1];
371: listenerArgList[0] = listenerType;
372: try {
373: this.addListenerMethod = eventSourceClass.getMethod(addListenerMethodName,listenerArgList);
374: } catch(SecurityException E) {
375: throw new IntrospectionException("SecurityException trying to access method " + addListenerMethodName + ".");
376: } catch(NoSuchMethodException E) {
377: throw new IntrospectionException("Could not find method " + addListenerMethodName + ".");
378: }
379:
380: if(this.addListenerMethod == null || !this.addListenerMethod.getReturnType().equals(java.lang.Void.TYPE)) {
381: throw new IntrospectionException("Add listener method does not exist, is not public, or is not void.");
382: }
383:
384: try {
385: this.removeListenerMethod = eventSourceClass.getMethod(removeListenerMethodName,listenerArgList);
386: } catch(SecurityException E) {
387: throw new IntrospectionException("SecurityException trying to access method " + removeListenerMethodName + ".");
388: } catch(NoSuchMethodException E) {
389: throw new IntrospectionException("Could not find method " + removeListenerMethodName + ".");
390: }
391: if(this.removeListenerMethod == null || !this.removeListenerMethod.getReturnType().equals(java.lang.Void.TYPE)) {
392: throw new IntrospectionException("Remove listener method does not exist, is not public, or is not void.");
393: }
394:
395:
396: Method[] methods;
397: try {
398: methods = ClassHelper.getAllMethods(listenerType);
399: } catch(SecurityException E) {
400: throw new IntrospectionException("Security: You cannot access fields in this class.");
401: }
402:
403: Vector chosenMethods = new Vector();
404: boolean[] listenerMethodFound = new boolean[listenerMethodNames.length];
405: for(int i=0;i<methods.length;i++) {
406: if(Modifier.isPrivate(methods[i].getModifiers())) {
407: continue;
408: }
409: Method currentMethod = methods[i];
410: Class retval = currentMethod.getReturnType();
411: if(retval.equals(java.lang.Void.TYPE)) {
412: for(int j=0;j<listenerMethodNames.length;j++) {
413: if(currentMethod.getName().equals(listenerMethodNames[j])
414: && (absurdEventClassCheckName == null
415: || (currentMethod.getParameterTypes().length == 1
416: && ((currentMethod.getParameterTypes()[0]).getName().equals(absurdEventClassCheckName)
417: || (currentMethod.getParameterTypes()[0]).getName().endsWith("."+absurdEventClassCheckName)
418: )
419: )
420: )
421: ) {
422: chosenMethods.addElement(currentMethod);
423: listenerMethodFound[j] = true;
424: }
425: }
426: }
427: }
428:
429:
430: for(int i=0;i<listenerMethodFound.length;i++) {
431: if(!listenerMethodFound[i]) {
432: throw new IntrospectionException("Could not find event method " + listenerMethodNames[i]);
433: }
434: }
435:
436:
437: this.listenerMethods = new Method[chosenMethods.size()];
438: for(int i=0;i<chosenMethods.size();i++) {
439: this.listenerMethods[i] = (Method)chosenMethods.elementAt(i);
440: }
441: }
442: }