97b8365caf
From-SVN: r120621
764 lines
28 KiB
Java
764 lines
28 KiB
Java
/* 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);
|
|
}
|
|
}
|
|
|
|
}
|