mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			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);
 | |
|       }
 | |
|   }
 | |
|   
 | |
| }
 |