| /* java.beans.EventSetDescriptor | |
| Copyright (C) 1998, 2006 Free Software Foundation, Inc. | |
| This file is part of GNU Classpath. | |
| GNU Classpath is free software; you can redistribute it and/or modify | |
| it under the terms of the GNU General Public License as published by | |
| the Free Software Foundation; either version 2, or (at your option) | |
| any later version. | |
| GNU Classpath is distributed in the hope that it will be useful, but | |
| WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| General Public License for more details. | |
| You should have received a copy of the GNU General Public License | |
| along with GNU Classpath; see the file COPYING. If not, write to the | |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | |
| 02110-1301 USA. | |
| Linking this library statically or dynamically with other modules is | |
| making a combined work based on this library. Thus, the terms and | |
| conditions of the GNU General Public License cover the whole | |
| combination. | |
| As a special exception, the copyright holders of this library give you | |
| permission to link this library with independent modules to produce an | |
| executable, regardless of the license terms of these independent | |
| modules, and to copy and distribute the resulting executable under | |
| terms of your choice, provided that you also meet, for each linked | |
| independent module, the terms and conditions of the license of that | |
| module. An independent module is a module which is not derived from | |
| or based on this library. If you modify this library, you may extend | |
| this exception to your version of the library, but you are not | |
| obligated to do so. If you do not wish to do so, delete this | |
| exception statement from your version. */ | |
| package java.beans; | |
| import gnu.java.lang.ClassHelper; | |
| import java.lang.reflect.Method; | |
| import java.lang.reflect.Modifier; | |
| import java.util.Vector; | |
| /** | |
| * EventSetDescriptor describes the hookup between an event source class and | |
| * an event listener class. | |
| * | |
| * <p>EventSets have several attributes: the listener class, | |
| * the events that can be fired to the listener (methods in the listener | |
| * class), and an add and remove listener method from the event firer's | |
| * class. | |
| * </p> | |
| * | |
| * <p> | |
| * The methods have these constraints on them: | |
| * <ul> | |
| * <li>event firing methods: must have <code>void</code> return value. Any | |
| * parameters and exceptions are allowed. May be public, protected or | |
| * package-protected. (Don't ask me why that is, I'm just following the spec. | |
| * The only place it is even mentioned is in the Java Beans white paper, and | |
| * there it is only implied.)</li> | |
| * | |
| * <li>add listener method: must have <code>void</code> return value. Must | |
| * take exactly one argument, of the listener class's type. May fire either | |
| * zero exceptions, or one exception of type | |
| * <code>java.util.TooManyListenersException</code>. | |
| * Must be public.</li> | |
| * | |
| * <li>remove listener method: must have <code>void</code> return value. Must | |
| * take exactly one argument, of the listener class's type. May not fire any | |
| * exceptions. Must be public.</li> | |
| * </ul> | |
| * | |
| * <p> | |
| * A final constraint is that event listener classes must extend from | |
| * EventListener. | |
| * </p> | |
| * | |
| * <p> | |
| * There are also various design patterns associated with some of the methods | |
| * of construction. Those are explained in more detail in the appropriate | |
| * constructors. | |
| * </p> | |
| * | |
| * <p> | |
| * <strong>Documentation Convention:</strong> for proper Internalization of | |
| * Beans inside an RAD tool, sometimes there are two names for a property or | |
| * method: a programmatic, or locale-independent name, which can be used | |
| * anywhere, and a localized, display name, for ease of use. In the | |
| * documentation I will specify different String values as either | |
| * <em>programmatic</em> or <em>localized</em> to make this distinction clear. | |
| * | |
| * @author John Keiser | |
| * @author Robert Schuster (robertschuster@fsfe.org) | |
| * @since 1.1 | |
| */ | |
| public class EventSetDescriptor extends FeatureDescriptor | |
| { | |
| private Method addListenerMethod; | |
| private Method removeListenerMethod; | |
| private Class listenerType; | |
| private MethodDescriptor[] listenerMethodDescriptors; | |
| private Method[] listenerMethods; | |
| private Method getListenerMethod; | |
| private boolean unicast; | |
| private boolean inDefaultEventSet = true; | |
| /** | |
| * Creates a new <code>EventSetDescriptor</code<. | |
| * | |
| * <p> | |
| * This version of the constructor enforces the rules imposed on the methods | |
| * described at the top of this class, as well as searching for: | |
| * </p> | |
| * | |
| * <ol> | |
| * <li> | |
| * The event-firing method must be non-private with signature <code>void | |
| * <listenerMethodName>(<eventSetName>Event)</code> (where | |
| * <code><eventSetName></code> has its first character capitalized | |
| * by the constructor and the Event is a descendant of | |
| * {@link java.util.EventObject}) in class <code>listenerType</code> | |
| * (any exceptions may be thrown). <b>Implementation note:</b> Note that | |
| * there could conceivably be multiple methods with this type of signature | |
| * (example: <code>java.util.MouseEvent</code> vs. | |
| * <code>my.very.own.MouseEvent</code>). In this implementation, all | |
| * methods fitting the description will be put into the | |
| * <code>EventSetDescriptor</code>, even though the spec says only one | |
| * should be chosen (they probably weren't thinking as pathologically as I | |
| * was). I don't like arbitrarily choosing things. If your class has only one | |
| * such signature, as most do, you'll have no problems.</li> | |
| * | |
| * <li>The add and remove methods must be public and named <code>void | |
| * add<eventSetName>Listener(<listenerType>)</code> and | |
| * <code>void remove<eventSetName>Listener(<listenerType>)</code> | |
| * in in class <code>eventSourceClass</code>, where | |
| * <code><eventSetName></code> will have its first letter capitalized. | |
| * Standard exception rules (see class description) apply.</li> | |
| * </ol> | |
| * | |
| * @param eventSourceClass | |
| * the class containing the add/remove listener methods. | |
| * @param eventSetName | |
| * the programmatic name of the event set, generally starting with a | |
| * lowercase letter (i.e. fooManChu instead of FooManChu). This will | |
| * be used to generate the name of the event object as well as the | |
| * names of the add and remove methods. | |
| * @param listenerType | |
| * the class containing the event firing method. | |
| * @param listenerMethodName | |
| * the name of the event firing method. | |
| * @exception IntrospectionException | |
| * if listenerType is not an EventListener, or if methods are not | |
| * found or are invalid. | |
| */ | |
| public EventSetDescriptor(Class eventSourceClass, String eventSetName, | |
| Class listenerType, String listenerMethodName) | |
| throws IntrospectionException | |
| { | |
| setName(eventSetName); | |
| if (!java.util.EventListener.class.isAssignableFrom(listenerType)) | |
| { | |
| throw new IntrospectionException( | |
| "Listener type is not an EventListener."); | |
| } | |
| String[] names = new String[1]; | |
| names[0] = listenerMethodName; | |
| try | |
| { | |
| eventSetName = Character.toUpperCase(eventSetName.charAt(0)) | |
| + eventSetName.substring(1); | |
| } | |
| catch (StringIndexOutOfBoundsException e) | |
| { | |
| eventSetName = ""; | |
| } | |
| findMethods(eventSourceClass, listenerType, names, | |
| "add" + eventSetName + "Listener", | |
| "remove" + eventSetName + "Listener", eventSetName + "Event"); | |
| this.listenerType = listenerType; | |
| checkAddListenerUnicast(); | |
| if (this.removeListenerMethod.getExceptionTypes().length > 0) | |
| { | |
| throw new IntrospectionException( | |
| "Listener remove method throws exceptions."); | |
| } | |
| } | |
| /** | |
| * Creates a new <code>EventSetDescriptor</code>. | |
| * | |
| * <p>This form of the constructor allows you to specify the names of the | |
| * methods and adds no new constraints on top of the rules already described | |
| * at the top of the class. | |
| * </p> | |
| * | |
| * @param eventSourceClass | |
| * the class containing the add and remove listener methods. | |
| * @param eventSetName | |
| * the programmatic name of the event set, generally starting with a | |
| * lowercase letter (i.e. fooManChu instead of FooManChu). | |
| * @param listenerType | |
| * the class containing the event firing methods. | |
| * @param listenerMethodNames | |
| * the names of the even firing methods. | |
| * @param addListenerMethodName | |
| * the name of the add listener method. | |
| * @param removeListenerMethodName | |
| * the name of the remove listener method. | |
| * @exception IntrospectionException | |
| * if listenerType is not an EventListener or if methods are not | |
| * found or are invalid. | |
| */ | |
| public EventSetDescriptor(Class eventSourceClass, String eventSetName, | |
| Class listenerType, String[] listenerMethodNames, | |
| String addListenerMethodName, | |
| String removeListenerMethodName) | |
| throws IntrospectionException | |
| { | |
| setName(eventSetName); | |
| if (!java.util.EventListener.class.isAssignableFrom(listenerType)) | |
| { | |
| throw new IntrospectionException( | |
| "Listener type is not an EventListener."); | |
| } | |
| findMethods(eventSourceClass, listenerType, listenerMethodNames, | |
| addListenerMethodName, removeListenerMethodName, null); | |
| this.listenerType = listenerType; | |
| checkAddListenerUnicast(); | |
| if (this.removeListenerMethod.getExceptionTypes().length > 0) | |
| { | |
| throw new IntrospectionException( | |
| "Listener remove method throws exceptions."); | |
| } | |
| } | |
| /** | |
| * Creates a new <code>EventSetDescriptor</code>. | |
| * | |
| * <p> | |
| * This variant of the constructor allows you to specify the names of the | |
| * methods and adds no new constraints on top of the rules already described | |
| * at the top of the class. | |
| * </p> | |
| * <p> | |
| * A valid GetListener method is public, flags no exceptions and has one | |
| * argument which is of type <code>Class</code> | |
| * {@link java.awt.Component#getListeners(Class)} is such a method. | |
| * </p> | |
| * <p> | |
| * Note: The validity of the return value of the GetListener method is not | |
| * checked. | |
| * </p> | |
| * | |
| * @param eventSourceClass | |
| * the class containing the add and remove listener methods. | |
| * @param eventSetName | |
| * the programmatic name of the event set, generally starting with a | |
| * lowercase letter (i.e. fooManChu instead of FooManChu). | |
| * @param listenerType | |
| * the class containing the event firing methods. | |
| * @param listenerMethodNames | |
| * the names of the even firing methods. | |
| * @param addListenerMethodName | |
| * the name of the add listener method. | |
| * @param removeListenerMethodName | |
| * the name of the remove listener method. | |
| * @param getListenerMethodName | |
| * Name of a method which returns the array of listeners. | |
| * @exception IntrospectionException | |
| * if listenerType is not an EventListener or if methods are not | |
| * found or are invalid. | |
| * @since 1.4 | |
| */ | |
| public EventSetDescriptor(Class eventSourceClass, String eventSetName, | |
| Class listenerType, String[] listenerMethodNames, | |
| String addListenerMethodName, | |
| String removeListenerMethodName, | |
| String getListenerMethodName) | |
| throws IntrospectionException | |
| { | |
| this(eventSourceClass, eventSetName, listenerType, listenerMethodNames, | |
| addListenerMethodName, removeListenerMethodName); | |
| Method newGetListenerMethod = null; | |
| try | |
| { | |
| newGetListenerMethod | |
| = eventSourceClass.getMethod(getListenerMethodName, | |
| new Class[] { Class.class }); | |
| } | |
| catch (NoSuchMethodException nsme) | |
| { | |
| throw (IntrospectionException) | |
| new IntrospectionException("No method named " + getListenerMethodName | |
| + " in class " + listenerType | |
| + " which can be used as" | |
| + " getListenerMethod.").initCause(nsme); | |
| } | |
| // Note: This does not check the return value (which | |
| // should be EventListener[]) but the JDK does not either. | |
| getListenerMethod = newGetListenerMethod; | |
| } | |
| /** | |
| * Creates a new <code>EventSetDescriptor.</code> | |
| * | |
| * <p> | |
| * This variant of the constructor allows you to specify the names of the | |
| * methods and adds no new constraints on top of the rules already described | |
| * at the top of the class. | |
| * </p> | |
| * <p> | |
| * A valid GetListener method is public, flags no exceptions and has one | |
| * argument which is of type <code>Class</code> | |
| * {@link java.awt.Component#getListeners(Class)} is such a method. | |
| * </p> | |
| * <p> | |
| * Note: The validity of the return value of the GetListener method is not | |
| * checked. | |
| * </p> | |
| * | |
| * @param eventSetName | |
| * the programmatic name of the event set, generally starting with a | |
| * lowercase letter (i.e. fooManChu instead of FooManChu). | |
| * @param listenerType | |
| * the class containing the listenerMethods. | |
| * @param listenerMethods | |
| * the event firing methods. | |
| * @param addListenerMethod | |
| * the add listener method. | |
| * @param removeListenerMethod | |
| * the remove listener method. | |
| * @param getListenerMethod | |
| * The method which returns an array of the listeners. | |
| * @exception IntrospectionException | |
| * if the listenerType is not an EventListener, or any of the | |
| * methods are invalid. | |
| * @since 1.4 | |
| */ | |
| public EventSetDescriptor(String eventSetName, Class listenerType, | |
| Method[] listenerMethods, Method addListenerMethod, | |
| Method removeListenerMethod, | |
| Method getListenerMethod) | |
| throws IntrospectionException | |
| { | |
| this(eventSetName, listenerType, listenerMethods, addListenerMethod, | |
| removeListenerMethod); | |
| // Do no checks if the getListenerMethod is null. | |
| if (getListenerMethod.getParameterTypes().length != 1 | |
| || getListenerMethod.getParameterTypes()[0] != Class.class | |
| || getListenerMethod.getExceptionTypes().length > 0 | |
| || !Modifier.isPublic(getListenerMethod.getModifiers())) | |
| throw new IntrospectionException("GetListener method is invalid."); | |
| // Note: This does not check the return value (which | |
| // should be EventListener[]) but the JDK does not either. | |
| this.getListenerMethod = getListenerMethod; | |
| } | |
| /** | |
| * Creates a new <code>EventSetDescriptor</code>. | |
| * | |
| * <p>This form of constructor allows you to explicitly say which methods | |
| * do what, and no reflection is done by the <code>EventSetDescriptor</code>. | |
| * The methods are, however, checked to ensure that they follow the rules | |
| * set forth at the top of the class. | |
| * | |
| * @param eventSetName | |
| * the programmatic name of the event set, generally starting with a | |
| * lowercase letter (i.e. fooManChu instead of FooManChu). | |
| * @param listenerType | |
| * the class containing the listenerMethods. | |
| * @param listenerMethods | |
| * the event firing methods. | |
| * @param addListenerMethod | |
| * the add listener method. | |
| * @param removeListenerMethod | |
| * the remove listener method. | |
| * @exception IntrospectionException | |
| * if the listenerType is not an EventListener, or any of the | |
| * methods are invalid. | |
| */ | |
| public EventSetDescriptor(String eventSetName, Class listenerType, | |
| Method[] listenerMethods, Method addListenerMethod, | |
| Method removeListenerMethod) | |
| throws IntrospectionException | |
| { | |
| setName(eventSetName); | |
| if (!java.util.EventListener.class.isAssignableFrom(listenerType)) | |
| { | |
| throw new IntrospectionException( | |
| "Listener type is not an EventListener."); | |
| } | |
| this.listenerMethods = listenerMethods; | |
| this.addListenerMethod = addListenerMethod; | |
| this.removeListenerMethod = removeListenerMethod; | |
| this.listenerType = listenerType; | |
| checkMethods(); | |
| checkAddListenerUnicast(); | |
| if (this.removeListenerMethod.getExceptionTypes().length > 0) | |
| { | |
| throw new IntrospectionException( | |
| "Listener remove method throws exceptions."); | |
| } | |
| } | |
| /** Creates a new <code>EventSetDescriptor</code>. | |
| * | |
| * <p>This form of constructor allows you to explicitly say which methods do | |
| * what, and no reflection is done by the <code>EventSetDescriptor</code>. | |
| * The methods are, however, checked to ensure that they follow the rules | |
| * set forth at the top of the class. | |
| * | |
| * @param eventSetName | |
| * the programmatic name of the event set, generally starting with a | |
| * lowercase letter (i.e. fooManChu instead of FooManChu). | |
| * @param listenerType | |
| * the class containing the listenerMethods. | |
| * @param listenerMethodDescriptors | |
| * the event firing methods. | |
| * @param addListenerMethod | |
| * the add listener method. | |
| * @param removeListenerMethod | |
| * the remove listener method. | |
| * @exception IntrospectionException | |
| * if the listenerType is not an EventListener, or any of the | |
| * methods are invalid. | |
| */ | |
| public EventSetDescriptor(String eventSetName, Class listenerType, | |
| MethodDescriptor[] listenerMethodDescriptors, | |
| Method addListenerMethod, | |
| Method removeListenerMethod) | |
| throws IntrospectionException | |
| { | |
| setName(eventSetName); | |
| if (!java.util.EventListener.class.isAssignableFrom(listenerType)) | |
| { | |
| throw new IntrospectionException( | |
| "Listener type is not an EventListener."); | |
| } | |
| this.listenerMethodDescriptors = listenerMethodDescriptors; | |
| this.listenerMethods = new Method[listenerMethodDescriptors.length]; | |
| for (int i = 0; i < this.listenerMethodDescriptors.length; i++) | |
| { | |
| this.listenerMethods[i] | |
| = this.listenerMethodDescriptors[i].getMethod(); | |
| } | |
| this.addListenerMethod = addListenerMethod; | |
| this.removeListenerMethod = removeListenerMethod; | |
| this.listenerType = listenerType; | |
| checkMethods(); | |
| checkAddListenerUnicast(); | |
| if (this.removeListenerMethod.getExceptionTypes().length > 0) | |
| { | |
| throw new IntrospectionException( | |
| "Listener remove method throws exceptions."); | |
| } | |
| } | |
| /** Returns the class that contains the event firing methods. | |
| */ | |
| public Class getListenerType() | |
| { | |
| return listenerType; | |
| } | |
| /** Returns the event firing methods. | |
| */ | |
| public Method[] getListenerMethods() | |
| { | |
| return listenerMethods; | |
| } | |
| /** Returns the event firing methods as {@link MethodDescriptor}. | |
| */ | |
| public MethodDescriptor[] getListenerMethodDescriptors() | |
| { | |
| if (listenerMethodDescriptors == null) | |
| { | |
| listenerMethodDescriptors | |
| = new MethodDescriptor[listenerMethods.length]; | |
| for (int i = 0; i < listenerMethods.length; i++) | |
| { | |
| listenerMethodDescriptors[i] | |
| = new MethodDescriptor(listenerMethods[i]); | |
| } | |
| } | |
| return listenerMethodDescriptors; | |
| } | |
| /** Returns the add listener method. | |
| */ | |
| public Method getAddListenerMethod() | |
| { | |
| return addListenerMethod; | |
| } | |
| /* Returns the remove listener method. | |
| */ | |
| public Method getRemoveListenerMethod() | |
| { | |
| return removeListenerMethod; | |
| } | |
| /** | |
| * Returns the method that retrieves the listeners or <code>null</code> if | |
| * it does not exist. | |
| */ | |
| public Method getGetListenerMethod() | |
| { | |
| return getListenerMethod; | |
| } | |
| /** Sets whether or not multiple listeners may be added. | |
| * | |
| * @param unicast | |
| * whether or not multiple listeners may be added. | |
| */ | |
| public void setUnicast(boolean unicast) | |
| { | |
| this.unicast = unicast; | |
| } | |
| /** Returns whether or not multiple listeners may be added. | |
| * (Defaults to false.) | |
| */ | |
| public boolean isUnicast() | |
| { | |
| return unicast; | |
| } | |
| /** Sets whether or not this is in the default event set. | |
| * | |
| * @param inDefaultEventSet | |
| * whether this is in the default event set. | |
| */ | |
| public void setInDefaultEventSet(boolean inDefaultEventSet) | |
| { | |
| this.inDefaultEventSet = inDefaultEventSet; | |
| } | |
| /** Returns whether or not this is in the default event set. | |
| * (Defaults to true.) | |
| */ | |
| public boolean isInDefaultEventSet() | |
| { | |
| return inDefaultEventSet; | |
| } | |
| private void checkAddListenerUnicast() throws IntrospectionException | |
| { | |
| Class[] addListenerExceptions = this.addListenerMethod.getExceptionTypes(); | |
| if (addListenerExceptions.length > 1) | |
| { | |
| throw new IntrospectionException( | |
| "Listener add method throws too many exceptions."); | |
| } | |
| else if (addListenerExceptions.length == 1 | |
| && !java.util.TooManyListenersException.class | |
| .isAssignableFrom(addListenerExceptions[0])) | |
| { | |
| throw new IntrospectionException( | |
| "Listener add method throws too many exceptions."); | |
| } | |
| } | |
| private void checkMethods() throws IntrospectionException | |
| { | |
| if (!addListenerMethod.getDeclaringClass() | |
| .isAssignableFrom(removeListenerMethod.getDeclaringClass()) | |
| && !removeListenerMethod.getDeclaringClass() | |
| .isAssignableFrom(addListenerMethod.getDeclaringClass())) | |
| { | |
| throw new IntrospectionException( | |
| "add and remove listener methods do not come from the" | |
| + " same class. This is bad."); | |
| } | |
| if (!addListenerMethod.getReturnType().equals(java.lang.Void.TYPE) | |
| || addListenerMethod.getParameterTypes().length != 1 | |
| || !listenerType.equals(addListenerMethod.getParameterTypes()[0]) | |
| || !Modifier.isPublic(addListenerMethod.getModifiers())) | |
| { | |
| throw new IntrospectionException("Add Listener Method invalid."); | |
| } | |
| if (!removeListenerMethod.getReturnType().equals(java.lang.Void.TYPE) | |
| || removeListenerMethod.getParameterTypes().length != 1 | |
| || !listenerType.equals(removeListenerMethod.getParameterTypes()[0]) | |
| || removeListenerMethod.getExceptionTypes().length > 0 | |
| || !Modifier.isPublic(removeListenerMethod.getModifiers())) | |
| { | |
| throw new IntrospectionException("Remove Listener Method invalid."); | |
| } | |
| for (int i = 0; i < listenerMethods.length; i++) | |
| { | |
| if (!listenerMethods[i].getReturnType().equals(java.lang.Void.TYPE) | |
| || Modifier.isPrivate(listenerMethods[i].getModifiers())) | |
| { | |
| throw new IntrospectionException("Event Method " | |
| + listenerMethods[i].getName() | |
| + " non-void or private."); | |
| } | |
| if (!listenerMethods[i].getDeclaringClass() | |
| .isAssignableFrom(listenerType)) | |
| { | |
| throw new IntrospectionException("Event Method " | |
| + listenerMethods[i].getName() | |
| + " not from class " | |
| + listenerType.getName()); | |
| } | |
| } | |
| } | |
| private void findMethods(Class eventSourceClass, Class listenerType, | |
| String listenerMethodNames[], | |
| String addListenerMethodName, | |
| String removeListenerMethodName, | |
| String absurdEventClassCheckName) | |
| throws IntrospectionException | |
| { | |
| /* Find add listener method and remove listener method. */ | |
| Class[] listenerArgList = new Class[1]; | |
| listenerArgList[0] = listenerType; | |
| try | |
| { | |
| this.addListenerMethod | |
| = eventSourceClass.getMethod(addListenerMethodName, | |
| listenerArgList); | |
| } | |
| catch (SecurityException E) | |
| { | |
| throw new IntrospectionException( | |
| "SecurityException trying to access method " | |
| + addListenerMethodName + "."); | |
| } | |
| catch (NoSuchMethodException E) | |
| { | |
| throw new IntrospectionException("Could not find method " | |
| + addListenerMethodName + "."); | |
| } | |
| if (this.addListenerMethod == null | |
| || !this.addListenerMethod.getReturnType().equals(java.lang.Void.TYPE)) | |
| { | |
| throw new IntrospectionException( | |
| "Add listener method does not exist, is not public," | |
| + " or is not void."); | |
| } | |
| try | |
| { | |
| this.removeListenerMethod | |
| = eventSourceClass.getMethod(removeListenerMethodName, | |
| listenerArgList); | |
| } | |
| catch (SecurityException E) | |
| { | |
| throw new IntrospectionException( | |
| "SecurityException trying to access method " | |
| + removeListenerMethodName + "."); | |
| } | |
| catch (NoSuchMethodException E) | |
| { | |
| throw new IntrospectionException("Could not find method " | |
| + removeListenerMethodName + "."); | |
| } | |
| if (this.removeListenerMethod == null | |
| || !this.removeListenerMethod.getReturnType() | |
| .equals(java.lang.Void.TYPE)) | |
| { | |
| throw new IntrospectionException( | |
| "Remove listener method does not exist, is not public," | |
| + " or is not void."); | |
| } | |
| /* Find the listener methods. */ | |
| Method[] methods; | |
| try | |
| { | |
| methods = ClassHelper.getAllMethods(listenerType); | |
| } | |
| catch (SecurityException E) | |
| { | |
| throw new IntrospectionException( | |
| "Security: You cannot access fields in this class."); | |
| } | |
| Vector chosenMethods = new Vector(); | |
| boolean[] listenerMethodFound = new boolean[listenerMethodNames.length]; | |
| for (int i = 0; i < methods.length; i++) | |
| { | |
| if (Modifier.isPrivate(methods[i].getModifiers())) | |
| { | |
| continue; | |
| } | |
| Method currentMethod = methods[i]; | |
| Class retval = currentMethod.getReturnType(); | |
| if (retval.equals(java.lang.Void.TYPE)) | |
| { | |
| for (int j = 0; j < listenerMethodNames.length; j++) | |
| { | |
| if (currentMethod.getName().equals(listenerMethodNames[j]) | |
| && (absurdEventClassCheckName == null | |
| || (currentMethod.getParameterTypes().length == 1 | |
| && ((currentMethod.getParameterTypes()[0]) | |
| .getName().equals(absurdEventClassCheckName) | |
| || (currentMethod.getParameterTypes()[0]) | |
| .getName().endsWith("." + absurdEventClassCheckName))))) | |
| { | |
| chosenMethods.addElement(currentMethod); | |
| listenerMethodFound[j] = true; | |
| } | |
| } | |
| } | |
| } | |
| /* Make sure we found all the methods we were looking for. */ | |
| for (int i = 0; i < listenerMethodFound.length; i++) | |
| { | |
| if (!listenerMethodFound[i]) | |
| { | |
| throw new IntrospectionException("Could not find event method " | |
| + listenerMethodNames[i]); | |
| } | |
| } | |
| /* Now that we've chosen the listener methods we want, store them. */ | |
| this.listenerMethods = new Method[chosenMethods.size()]; | |
| for (int i = 0; i < chosenMethods.size(); i++) | |
| { | |
| this.listenerMethods[i] = (Method) chosenMethods.elementAt(i); | |
| } | |
| } | |
| } |