Overview Package Class Use Source Tree Index Deprecated About
GNU Classpath (0.95)
Frames | No Frames

Source for java.beans.EventSetDescriptor

 1:  /* java.beans.EventSetDescriptor
 2:  Copyright (C) 1998, 2006 Free Software Foundation, Inc.
 3: 
 4:  This file is part of GNU Classpath.
 5: 
 6:  GNU Classpath is free software; you can redistribute it and/or modify
 7:  it under the terms of the GNU General Public License as published by
 8:  the Free Software Foundation; either version 2, or (at your option)
 9:  any later version.
 10:  
 11:  GNU Classpath is distributed in the hope that it will be useful, but
 12:  WITHOUT ANY WARRANTY; without even the implied warranty of
 13:  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 14:  General Public License for more details.
 15: 
 16:  You should have received a copy of the GNU General Public License
 17:  along with GNU Classpath; see the file COPYING. If not, write to the
 18:  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 19:  02110-1301 USA.
 20: 
 21:  Linking this library statically or dynamically with other modules is
 22:  making a combined work based on this library. Thus, the terms and
 23:  conditions of the GNU General Public License cover the whole
 24:  combination.
 25: 
 26:  As a special exception, the copyright holders of this library give you
 27:  permission to link this library with independent modules to produce an
 28:  executable, regardless of the license terms of these independent
 29:  modules, and to copy and distribute the resulting executable under
 30:  terms of your choice, provided that you also meet, for each linked
 31:  independent module, the terms and conditions of the license of that
 32:  module. An independent module is a module which is not derived from
 33:  or based on this library. If you modify this library, you may extend
 34:  this exception to your version of the library, but you are not
 35:  obligated to do so. If you do not wish to do so, delete this
 36:  exception statement from your version. */
 37: 
 38: 
 39:  package java.beans;
 40: 
 41:  import gnu.java.lang.ClassHelper;
 42: 
 43:  import java.lang.reflect.Method;
 44:  import java.lang.reflect.Modifier;
 45:  import java.util.Vector;
 46: 
 47:  /**
 48:  * EventSetDescriptor describes the hookup between an event source class and
 49:  * an event listener class.
 50:  * 
 51:  * <p>EventSets have several attributes: the listener class,
 52:  * the events that can be fired to the listener (methods in the listener
 53:  * class), and an add and remove listener method from the event firer's
 54:  * class.
 55:  * </p>
 56:  * 
 57:  * <p>
 58:  * The methods have these constraints on them:
 59:  * <ul>
 60:  * <li>event firing methods: must have <code>void</code> return value. Any
 61:  * parameters and exceptions are allowed. May be public, protected or
 62:  * package-protected. (Don't ask me why that is, I'm just following the spec.
 63:  * The only place it is even mentioned is in the Java Beans white paper, and
 64:  * there it is only implied.)</li>
 65:  * 
 66:  * <li>add listener method: must have <code>void</code> return value. Must
 67:  * take exactly one argument, of the listener class's type. May fire either
 68:  * zero exceptions, or one exception of type
 69:  * <code>java.util.TooManyListenersException</code>.
 70:  * Must be public.</li>
 71:  * 
 72:  * <li>remove listener method: must have <code>void</code> return value. Must
 73:  * take exactly one argument, of the listener class's type. May not fire any
 74:  * exceptions. Must be public.</li>
 75:  * </ul>
 76:  * 
 77:  * <p>
 78:  * A final constraint is that event listener classes must extend from
 79:  * EventListener.
 80:  * </p>
 81:  * 
 82:  * <p>
 83:  * There are also various design patterns associated with some of the methods
 84:  * of construction. Those are explained in more detail in the appropriate
 85:  * constructors.
 86:  * </p>
 87:  * 
 88:  * <p>
 89:  * <strong>Documentation Convention:</strong> for proper Internalization of
 90:  * Beans inside an RAD tool, sometimes there are two names for a property or
 91:  * method: a programmatic, or locale-independent name, which can be used
 92:  * anywhere, and a localized, display name, for ease of use. In the
 93:  * documentation I will specify different String values as either
 94:  * <em>programmatic</em> or <em>localized</em> to make this distinction clear.
 95:  * 
 96:  * @author John Keiser
 97:  * @author Robert Schuster (robertschuster@fsfe.org)
 98:  * @since 1.1
 99:  */
 100: 
 101:  public class EventSetDescriptor extends FeatureDescriptor
 102: {
 103:  private Method addListenerMethod;
 104: 
 105:  private Method removeListenerMethod;
 106: 
 107:  private Class listenerType;
 108: 
 109:  private MethodDescriptor[] listenerMethodDescriptors;
 110: 
 111:  private Method[] listenerMethods;
 112: 
 113:  private Method getListenerMethod;
 114: 
 115:  private boolean unicast;
 116: 
 117:  private boolean inDefaultEventSet = true;
 118: 
 119:  /**
 120:  * Creates a new <code>EventSetDescriptor</code<.
 121:  * 
 122:  * <p>
 123:  * This version of the constructor enforces the rules imposed on the methods
 124:  * described at the top of this class, as well as searching for:
 125:  * </p>
 126:  * 
 127:  * <ol>
 128:  * <li>
 129:  * The event-firing method must be non-private with signature <code>void
 130:  * &lt;listenerMethodName&gt;(&lt;eventSetName&gt;Event)</code> (where
 131:  * <code>&lt;eventSetName&gt;</code> has its first character capitalized
 132:  * by the constructor and the Event is a descendant of
 133:  * {@link java.util.EventObject}) in class <code>listenerType</code>
 134:  * (any exceptions may be thrown). <b>Implementation note:</b> Note that
 135:  * there could conceivably be multiple methods with this type of signature
 136:  * (example: <code>java.util.MouseEvent</code> vs.
 137:  * <code>my.very.own.MouseEvent</code>). In this implementation, all
 138:  * methods fitting the description will be put into the
 139:  * <code>EventSetDescriptor</code>, even though the spec says only one
 140:  * should be chosen (they probably weren't thinking as pathologically as I
 141:  * was). I don't like arbitrarily choosing things. If your class has only one
 142:  * such signature, as most do, you'll have no problems.</li>
 143:  * 
 144:  * <li>The add and remove methods must be public and named <code>void
 145:  * add&lt;eventSetName&gt;Listener(&lt;listenerType&gt;)</code> and
 146:  * <code>void remove&lt;eventSetName&gt;Listener(&lt;listenerType&gt;)</code>
 147:  * in in class <code>eventSourceClass</code>, where
 148:  * <code>&lt;eventSetName&gt;</code> will have its first letter capitalized.
 149:  * Standard exception rules (see class description) apply.</li>
 150:  * </ol>
 151:  * 
 152:  * @param eventSourceClass
 153:  * the class containing the add/remove listener methods.
 154:  * @param eventSetName
 155:  * the programmatic name of the event set, generally starting with a
 156:  * lowercase letter (i.e. fooManChu instead of FooManChu). This will
 157:  * be used to generate the name of the event object as well as the
 158:  * names of the add and remove methods.
 159:  * @param listenerType
 160:  * the class containing the event firing method.
 161:  * @param listenerMethodName
 162:  * the name of the event firing method.
 163:  * @exception IntrospectionException
 164:  * if listenerType is not an EventListener, or if methods are not
 165:  * found or are invalid.
 166:  */
 167:  public EventSetDescriptor(Class<?> eventSourceClass, String eventSetName,
 168:  Class<?> listenerType, String listenerMethodName)
 169:  throws IntrospectionException
 170:  {
 171:  setName(eventSetName);
 172:  if (!java.util.EventListener.class.isAssignableFrom(listenerType))
 173:  {
 174:  throw new IntrospectionException(
 175:  "Listener type is not an EventListener.");
 176:  }
 177: 
 178:  String[] names = new String[1];
 179:  names[0] = listenerMethodName;
 180: 
 181:  try
 182:  {
 183:  eventSetName = Character.toUpperCase(eventSetName.charAt(0))
 184:  + eventSetName.substring(1);
 185:  }
 186:  catch (StringIndexOutOfBoundsException e)
 187:  {
 188:  eventSetName = "";
 189:  }
 190: 
 191:  findMethods(eventSourceClass, listenerType, names,
 192:  "add" + eventSetName + "Listener",
 193:  "remove" + eventSetName + "Listener", eventSetName + "Event");
 194:  this.listenerType = listenerType;
 195:  checkAddListenerUnicast();
 196:  if (this.removeListenerMethod.getExceptionTypes().length > 0)
 197:  {
 198:  throw new IntrospectionException(
 199:  "Listener remove method throws exceptions.");
 200:  }
 201:  }
 202: 
 203:  /**
 204:  * Creates a new <code>EventSetDescriptor</code>.
 205:  * 
 206:  * <p>This form of the constructor allows you to specify the names of the
 207:  * methods and adds no new constraints on top of the rules already described
 208:  * at the top of the class.
 209:  * </p>
 210:  * 
 211:  * @param eventSourceClass
 212:  * the class containing the add and remove listener methods.
 213:  * @param eventSetName
 214:  * the programmatic name of the event set, generally starting with a
 215:  * lowercase letter (i.e. fooManChu instead of FooManChu).
 216:  * @param listenerType
 217:  * the class containing the event firing methods.
 218:  * @param listenerMethodNames
 219:  * the names of the even firing methods.
 220:  * @param addListenerMethodName
 221:  * the name of the add listener method.
 222:  * @param removeListenerMethodName
 223:  * the name of the remove listener method.
 224:  * @exception IntrospectionException
 225:  * if listenerType is not an EventListener or if methods are not
 226:  * found or are invalid.
 227:  */
 228:  public EventSetDescriptor(Class<?> eventSourceClass, String eventSetName,
 229:  Class<?> listenerType, String[] listenerMethodNames,
 230:  String addListenerMethodName,
 231:  String removeListenerMethodName)
 232:  throws IntrospectionException
 233:  {
 234:  setName(eventSetName);
 235:  if (!java.util.EventListener.class.isAssignableFrom(listenerType))
 236:  {
 237:  throw new IntrospectionException(
 238:  "Listener type is not an EventListener.");
 239:  }
 240: 
 241:  findMethods(eventSourceClass, listenerType, listenerMethodNames,
 242:  addListenerMethodName, removeListenerMethodName, null);
 243:  this.listenerType = listenerType;
 244:  checkAddListenerUnicast();
 245:  if (this.removeListenerMethod.getExceptionTypes().length > 0)
 246:  {
 247:  throw new IntrospectionException(
 248:  "Listener remove method throws exceptions.");
 249:  }
 250:  }
 251: 
 252:  /**
 253:  * Creates a new <code>EventSetDescriptor</code>.
 254:  * 
 255:  * <p>
 256:  * This variant of the constructor allows you to specify the names of the
 257:  * methods and adds no new constraints on top of the rules already described
 258:  * at the top of the class.
 259:  * </p>
 260:  * <p>
 261:  * A valid GetListener method is public, flags no exceptions and has one
 262:  * argument which is of type <code>Class</code>
 263:  * {@link java.awt.Component#getListeners(Class)} is such a method.
 264:  * </p>
 265:  * <p>
 266:  * Note: The validity of the return value of the GetListener method is not
 267:  * checked.
 268:  * </p>
 269:  * 
 270:  * @param eventSourceClass
 271:  * the class containing the add and remove listener methods.
 272:  * @param eventSetName
 273:  * the programmatic name of the event set, generally starting with a
 274:  * lowercase letter (i.e. fooManChu instead of FooManChu).
 275:  * @param listenerType
 276:  * the class containing the event firing methods.
 277:  * @param listenerMethodNames
 278:  * the names of the even firing methods.
 279:  * @param addListenerMethodName
 280:  * the name of the add listener method.
 281:  * @param removeListenerMethodName
 282:  * the name of the remove listener method.
 283:  * @param getListenerMethodName
 284:  * Name of a method which returns the array of listeners.
 285:  * @exception IntrospectionException
 286:  * if listenerType is not an EventListener or if methods are not
 287:  * found or are invalid.
 288:  * @since 1.4
 289:  */
 290:  public EventSetDescriptor(Class<?> eventSourceClass, String eventSetName,
 291:  Class<?> listenerType, String[] listenerMethodNames,
 292:  String addListenerMethodName,
 293:  String removeListenerMethodName,
 294:  String getListenerMethodName)
 295:  throws IntrospectionException
 296:  {
 297:  this(eventSourceClass, eventSetName, listenerType, listenerMethodNames,
 298:  addListenerMethodName, removeListenerMethodName);
 299: 
 300:  Method newGetListenerMethod = null;
 301: 
 302:  try
 303:  {
 304:  newGetListenerMethod 
 305:  = eventSourceClass.getMethod(getListenerMethodName,
 306:  new Class[] { Class.class });
 307:  }
 308:  catch (NoSuchMethodException nsme)
 309:  {
 310:  throw (IntrospectionException) 
 311:  new IntrospectionException("No method named " + getListenerMethodName
 312:  + " in class " + listenerType
 313:  + " which can be used as"
 314:  + " getListenerMethod.").initCause(nsme);
 315:  }
 316: 
 317:  // Note: This does not check the return value (which
 318:  // should be EventListener[]) but the JDK does not either.
 319: 
 320:  getListenerMethod = newGetListenerMethod;
 321: 
 322:  }
 323: 
 324:  /**
 325:  * Creates a new <code>EventSetDescriptor.</code>
 326:  * 
 327:  * <p>
 328:  * This variant of the constructor allows you to specify the names of the
 329:  * methods and adds no new constraints on top of the rules already described
 330:  * at the top of the class.
 331:  * </p>
 332:  * <p>
 333:  * A valid GetListener method is public, flags no exceptions and has one
 334:  * argument which is of type <code>Class</code>
 335:  * {@link java.awt.Component#getListeners(Class)} is such a method.
 336:  * </p>
 337:  * <p>
 338:  * Note: The validity of the return value of the GetListener method is not
 339:  * checked.
 340:  * </p>
 341:  * 
 342:  * @param eventSetName
 343:  * the programmatic name of the event set, generally starting with a
 344:  * lowercase letter (i.e. fooManChu instead of FooManChu).
 345:  * @param listenerType
 346:  * the class containing the listenerMethods.
 347:  * @param listenerMethods
 348:  * the event firing methods.
 349:  * @param addListenerMethod
 350:  * the add listener method.
 351:  * @param removeListenerMethod
 352:  * the remove listener method.
 353:  * @param getListenerMethod
 354:  * The method which returns an array of the listeners.
 355:  * @exception IntrospectionException
 356:  * if the listenerType is not an EventListener, or any of the
 357:  * methods are invalid.
 358:  * @since 1.4
 359:  */
 360:  public EventSetDescriptor(String eventSetName, Class<?> listenerType,
 361:  Method[] listenerMethods, Method addListenerMethod,
 362:  Method removeListenerMethod,
 363:  Method getListenerMethod)
 364:  throws IntrospectionException
 365:  {
 366:  this(eventSetName, listenerType, listenerMethods, addListenerMethod,
 367:  removeListenerMethod);
 368: 
 369:  // Do no checks if the getListenerMethod is null.
 370:  if (getListenerMethod.getParameterTypes().length != 1
 371:  || getListenerMethod.getParameterTypes()[0] != Class.class
 372:  || getListenerMethod.getExceptionTypes().length > 0
 373:  || !Modifier.isPublic(getListenerMethod.getModifiers()))
 374:  throw new IntrospectionException("GetListener method is invalid.");
 375: 
 376:  // Note: This does not check the return value (which
 377:  // should be EventListener[]) but the JDK does not either.
 378: 
 379:  this.getListenerMethod = getListenerMethod;
 380:  }
 381: 
 382:  /**
 383:  * Creates a new <code>EventSetDescriptor</code>.
 384:  * 
 385:  * <p>This form of constructor allows you to explicitly say which methods
 386:  * do what, and no reflection is done by the <code>EventSetDescriptor</code>.
 387:  * The methods are, however, checked to ensure that they follow the rules
 388:  * set forth at the top of the class.
 389:  * 
 390:  * @param eventSetName
 391:  * the programmatic name of the event set, generally starting with a
 392:  * lowercase letter (i.e. fooManChu instead of FooManChu).
 393:  * @param listenerType
 394:  * the class containing the listenerMethods.
 395:  * @param listenerMethods
 396:  * the event firing methods.
 397:  * @param addListenerMethod
 398:  * the add listener method.
 399:  * @param removeListenerMethod
 400:  * the remove listener method.
 401:  * @exception IntrospectionException
 402:  * if the listenerType is not an EventListener, or any of the
 403:  * methods are invalid.
 404:  */
 405:  public EventSetDescriptor(String eventSetName, Class<?> listenerType,
 406:  Method[] listenerMethods, Method addListenerMethod,
 407:  Method removeListenerMethod)
 408:  throws IntrospectionException
 409:  {
 410:  setName(eventSetName);
 411:  if (!java.util.EventListener.class.isAssignableFrom(listenerType))
 412:  {
 413:  throw new IntrospectionException(
 414:  "Listener type is not an EventListener.");
 415:  }
 416: 
 417:  this.listenerMethods = listenerMethods;
 418:  this.addListenerMethod = addListenerMethod;
 419:  this.removeListenerMethod = removeListenerMethod;
 420:  this.listenerType = listenerType;
 421:  checkMethods();
 422:  checkAddListenerUnicast();
 423:  if (this.removeListenerMethod.getExceptionTypes().length > 0)
 424:  {
 425:  throw new IntrospectionException(
 426:  "Listener remove method throws exceptions.");
 427:  }
 428:  }
 429: 
 430:  /** Creates a new <code>EventSetDescriptor</code>.
 431:  * 
 432:  * <p>This form of constructor allows you to explicitly say which methods do
 433:  * what, and no reflection is done by the <code>EventSetDescriptor</code>.
 434:  * The methods are, however, checked to ensure that they follow the rules
 435:  * set forth at the top of the class.
 436:  * 
 437:  * @param eventSetName
 438:  * the programmatic name of the event set, generally starting with a
 439:  * lowercase letter (i.e. fooManChu instead of FooManChu).
 440:  * @param listenerType
 441:  * the class containing the listenerMethods.
 442:  * @param listenerMethodDescriptors
 443:  * the event firing methods.
 444:  * @param addListenerMethod
 445:  * the add listener method.
 446:  * @param removeListenerMethod
 447:  * the remove listener method.
 448:  * @exception IntrospectionException
 449:  * if the listenerType is not an EventListener, or any of the
 450:  * methods are invalid.
 451:  */
 452:  public EventSetDescriptor(String eventSetName, Class<?> listenerType,
 453:  MethodDescriptor[] listenerMethodDescriptors,
 454:  Method addListenerMethod,
 455:  Method removeListenerMethod)
 456:  throws IntrospectionException
 457:  {
 458:  setName(eventSetName);
 459:  if (!java.util.EventListener.class.isAssignableFrom(listenerType))
 460:  {
 461:  throw new IntrospectionException(
 462:  "Listener type is not an EventListener.");
 463:  }
 464: 
 465:  this.listenerMethodDescriptors = listenerMethodDescriptors;
 466:  this.listenerMethods = new Method[listenerMethodDescriptors.length];
 467:  for (int i = 0; i < this.listenerMethodDescriptors.length; i++)
 468:  {
 469:  this.listenerMethods[i]
 470:  = this.listenerMethodDescriptors[i].getMethod();
 471:  }
 472: 
 473:  this.addListenerMethod = addListenerMethod;
 474:  this.removeListenerMethod = removeListenerMethod;
 475:  this.listenerType = listenerType;
 476:  checkMethods();
 477:  checkAddListenerUnicast();
 478:  if (this.removeListenerMethod.getExceptionTypes().length > 0)
 479:  {
 480:  throw new IntrospectionException(
 481:  "Listener remove method throws exceptions.");
 482:  }
 483:  }
 484: 
 485:  /** Returns the class that contains the event firing methods.
 486:  */
 487:  public Class<?> getListenerType()
 488:  {
 489:  return listenerType;
 490:  }
 491: 
 492:  /** Returns the event firing methods.
 493:  */
 494:  public Method[] getListenerMethods()
 495:  {
 496:  return listenerMethods;
 497:  }
 498: 
 499:  /** Returns the event firing methods as {@link MethodDescriptor}.
 500:  */
 501:  public MethodDescriptor[] getListenerMethodDescriptors()
 502:  {
 503:  if (listenerMethodDescriptors == null)
 504:  {
 505:  listenerMethodDescriptors
 506:  = new MethodDescriptor[listenerMethods.length];
 507:  
 508:  for (int i = 0; i < listenerMethods.length; i++)
 509:  {
 510:  listenerMethodDescriptors[i]
 511:  = new MethodDescriptor(listenerMethods[i]);
 512:  }
 513:  }
 514:  
 515:  return listenerMethodDescriptors;
 516:  }
 517: 
 518:  /** Returns the add listener method.
 519:  */
 520:  public Method getAddListenerMethod()
 521:  {
 522:  return addListenerMethod;
 523:  }
 524: 
 525:  /* Returns the remove listener method.
 526:  */
 527:  public Method getRemoveListenerMethod()
 528:  {
 529:  return removeListenerMethod;
 530:  }
 531: 
 532:  /**
 533:  * Returns the method that retrieves the listeners or <code>null</code> if
 534:  * it does not exist.
 535:  */
 536:  public Method getGetListenerMethod()
 537:  {
 538:  return getListenerMethod;
 539:  }
 540: 
 541:  /** Sets whether or not multiple listeners may be added.
 542:  * 
 543:  * @param unicast
 544:  * whether or not multiple listeners may be added.
 545:  */
 546:  public void setUnicast(boolean unicast)
 547:  {
 548:  this.unicast = unicast;
 549:  }
 550: 
 551:  /** Returns whether or not multiple listeners may be added.
 552:  * (Defaults to false.)
 553:  */
 554:  public boolean isUnicast()
 555:  {
 556:  return unicast;
 557:  }
 558: 
 559:  /** Sets whether or not this is in the default event set.
 560:  * 
 561:  * @param inDefaultEventSet
 562:  * whether this is in the default event set.
 563:  */
 564:  public void setInDefaultEventSet(boolean inDefaultEventSet)
 565:  {
 566:  this.inDefaultEventSet = inDefaultEventSet;
 567:  }
 568: 
 569:  /** Returns whether or not this is in the default event set.
 570:  * (Defaults to true.)
 571:  */
 572:  public boolean isInDefaultEventSet()
 573:  {
 574:  return inDefaultEventSet;
 575:  }
 576: 
 577:  private void checkAddListenerUnicast() throws IntrospectionException
 578:  {
 579:  Class[] addListenerExceptions = this.addListenerMethod.getExceptionTypes();
 580:  if (addListenerExceptions.length > 1)
 581:  {
 582:  throw new IntrospectionException(
 583:  "Listener add method throws too many exceptions.");
 584:  }
 585:  else if (addListenerExceptions.length == 1
 586:  && !java.util.TooManyListenersException.class
 587:  .isAssignableFrom(addListenerExceptions[0]))
 588:  {
 589:  throw new IntrospectionException(
 590:  "Listener add method throws too many exceptions.");
 591:  }
 592:  }
 593: 
 594:  private void checkMethods() throws IntrospectionException
 595:  {
 596:  if (!addListenerMethod.getDeclaringClass()
 597:  .isAssignableFrom(removeListenerMethod.getDeclaringClass())
 598:  && !removeListenerMethod.getDeclaringClass()
 599:  .isAssignableFrom(addListenerMethod.getDeclaringClass()))
 600:  {
 601:  throw new IntrospectionException(
 602:  "add and remove listener methods do not come from the"
 603:  + " same class. This is bad.");
 604:  }
 605:  if (!addListenerMethod.getReturnType().equals(java.lang.Void.TYPE)
 606:  || addListenerMethod.getParameterTypes().length != 1
 607:  || !listenerType.equals(addListenerMethod.getParameterTypes()[0])
 608:  || !Modifier.isPublic(addListenerMethod.getModifiers()))
 609:  {
 610:  throw new IntrospectionException("Add Listener Method invalid.");
 611:  }
 612:  if (!removeListenerMethod.getReturnType().equals(java.lang.Void.TYPE)
 613:  || removeListenerMethod.getParameterTypes().length != 1
 614:  || !listenerType.equals(removeListenerMethod.getParameterTypes()[0])
 615:  || removeListenerMethod.getExceptionTypes().length > 0
 616:  || !Modifier.isPublic(removeListenerMethod.getModifiers()))
 617:  {
 618:  throw new IntrospectionException("Remove Listener Method invalid.");
 619:  }
 620: 
 621:  for (int i = 0; i < listenerMethods.length; i++)
 622:  {
 623:  if (!listenerMethods[i].getReturnType().equals(java.lang.Void.TYPE)
 624:  || Modifier.isPrivate(listenerMethods[i].getModifiers()))
 625:  {
 626:  throw new IntrospectionException("Event Method "
 627:  + listenerMethods[i].getName()
 628:  + " non-void or private.");
 629:  }
 630:  if (!listenerMethods[i].getDeclaringClass()
 631:  .isAssignableFrom(listenerType))
 632:  {
 633:  throw new IntrospectionException("Event Method "
 634:  + listenerMethods[i].getName()
 635:  + " not from class "
 636:  + listenerType.getName());
 637:  }
 638:  }
 639:  }
 640: 
 641:  private void findMethods(Class eventSourceClass, Class listenerType,
 642:  String listenerMethodNames[],
 643:  String addListenerMethodName,
 644:  String removeListenerMethodName,
 645:  String absurdEventClassCheckName)
 646:  throws IntrospectionException
 647:  {
 648: 
 649:  /* Find add listener method and remove listener method. */
 650:  Class[] listenerArgList = new Class[1];
 651:  listenerArgList[0] = listenerType;
 652:  try
 653:  {
 654:  this.addListenerMethod
 655:  = eventSourceClass.getMethod(addListenerMethodName,
 656:  listenerArgList);
 657:  }
 658:  catch (SecurityException E)
 659:  {
 660:  throw new IntrospectionException(
 661:  "SecurityException trying to access method "
 662:  + addListenerMethodName + ".");
 663:  }
 664:  catch (NoSuchMethodException E)
 665:  {
 666:  throw new IntrospectionException("Could not find method "
 667:  + addListenerMethodName + ".");
 668:  }
 669: 
 670:  if (this.addListenerMethod == null
 671:  || !this.addListenerMethod.getReturnType().equals(java.lang.Void.TYPE))
 672:  {
 673:  throw new IntrospectionException(
 674:  "Add listener method does not exist, is not public,"
 675:  + " or is not void.");
 676:  }
 677: 
 678:  try
 679:  {
 680:  this.removeListenerMethod
 681:  = eventSourceClass.getMethod(removeListenerMethodName,
 682:  listenerArgList);
 683:  }
 684:  catch (SecurityException E)
 685:  {
 686:  throw new IntrospectionException(
 687:  "SecurityException trying to access method "
 688:  + removeListenerMethodName + ".");
 689:  }
 690:  catch (NoSuchMethodException E)
 691:  {
 692:  throw new IntrospectionException("Could not find method "
 693:  + removeListenerMethodName + ".");
 694:  }
 695:  if (this.removeListenerMethod == null
 696:  || !this.removeListenerMethod.getReturnType()
 697:  .equals(java.lang.Void.TYPE))
 698:  {
 699:  throw new IntrospectionException(
 700:  "Remove listener method does not exist, is not public,"
 701:  + " or is not void.");
 702:  }
 703: 
 704:  /* Find the listener methods. */
 705:  Method[] methods;
 706:  try
 707:  {
 708:  methods = ClassHelper.getAllMethods(listenerType);
 709:  }
 710:  catch (SecurityException E)
 711:  {
 712:  throw new IntrospectionException(
 713:  "Security: You cannot access fields in this class.");
 714:  }
 715: 
 716:  Vector chosenMethods = new Vector();
 717:  boolean[] listenerMethodFound = new boolean[listenerMethodNames.length];
 718:  for (int i = 0; i < methods.length; i++)
 719:  {
 720:  if (Modifier.isPrivate(methods[i].getModifiers()))
 721:  {
 722:  continue;
 723:  }
 724:  Method currentMethod = methods[i];
 725:  Class retval = currentMethod.getReturnType();
 726:  if (retval.equals(java.lang.Void.TYPE))
 727:  {
 728:  for (int j = 0; j < listenerMethodNames.length; j++)
 729:  {
 730:  if (currentMethod.getName().equals(listenerMethodNames[j])
 731:  && (absurdEventClassCheckName == null
 732:  || (currentMethod.getParameterTypes().length == 1
 733:  && ((currentMethod.getParameterTypes()[0])
 734:  .getName().equals(absurdEventClassCheckName)
 735:  || (currentMethod.getParameterTypes()[0])
 736:  .getName().endsWith("." + absurdEventClassCheckName)))))
 737:  {
 738:  chosenMethods.addElement(currentMethod);
 739:  listenerMethodFound[j] = true;
 740:  }
 741:  }
 742:  }
 743:  }
 744: 
 745:  /* Make sure we found all the methods we were looking for. */
 746:  for (int i = 0; i < listenerMethodFound.length; i++)
 747:  {
 748:  if (!listenerMethodFound[i])
 749:  {
 750:  throw new IntrospectionException("Could not find event method "
 751:  + listenerMethodNames[i]);
 752:  }
 753:  }
 754: 
 755:  /* Now that we've chosen the listener methods we want, store them. */
 756:  this.listenerMethods = new Method[chosenMethods.size()];
 757:  for (int i = 0; i < chosenMethods.size(); i++)
 758:  {
 759:  this.listenerMethods[i] = (Method) chosenMethods.elementAt(i);
 760:  }
 761:  }
 762:  
 763: }
Overview Package Class Use Source Tree Index Deprecated About
GNU Classpath (0.95)

AltStyle によって変換されたページ (->オリジナル) /