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

Source for java.beans.PropertyDescriptor

 1:  /* java.beans.PropertyDescriptor
 2:  Copyright (C) 1998, 2001, 2004, 2005 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:  package java.beans;
 39: 
 40:  import java.lang.reflect.Constructor;
 41:  import java.lang.reflect.InvocationTargetException;
 42:  import java.lang.reflect.Method;
 43: 
 44:  /**
 45:  ** PropertyDescriptor describes information about a JavaBean property,
 46:  ** by which we mean a property that has been exposed via a pair of
 47:  ** get and set methods. (There may be no get method, which means
 48:  ** the property is write-only, or no set method, which means the
 49:  ** the property is read-only.)<P>
 50:  **
 51:  ** The constraints put on get and set methods are:<P>
 52:  ** <OL>
 53:  ** <LI>A get method must have signature
 54:  ** <CODE>&lt;propertyType&gt; &lt;getMethodName&gt;()</CODE></LI>
 55:  ** <LI>A set method must have signature
 56:  ** <CODE>void &lt;setMethodName&gt;(&lt;propertyType&gt;)</CODE></LI>
 57:  ** <LI>Either method type may throw any exception.</LI>
 58:  ** <LI>Both methods must be public.</LI>
 59:  ** </OL>
 60:  **
 61:  ** @author John Keiser
 62:  ** @author Robert Schuster (thebohemian@gmx.net)
 63:  ** @since 1.1
 64:  ** @status updated to 1.4
 65:  **/
 66:  public class PropertyDescriptor extends FeatureDescriptor
 67: {
 68:  Class<?> propertyType;
 69:  Method getMethod;
 70:  Method setMethod;
 71: 
 72:  Class<?> propertyEditorClass;
 73:  boolean bound;
 74:  boolean constrained;
 75: 
 76:  PropertyDescriptor(String name)
 77:  {
 78:  setName(name);
 79:  }
 80: 
 81:  /** Create a new PropertyDescriptor by introspection.
 82:  ** This form of constructor creates the PropertyDescriptor by
 83:  ** looking for a getter method named <CODE>get&lt;name&gt;()</CODE>
 84:  ** (or, optionally, if the property is boolean,
 85:  ** <CODE>is&lt;name&gt;()</CODE>) and
 86:  ** <CODE>set&lt;name&gt;()</CODE> in class
 87:  ** <CODE>&lt;beanClass&gt;</CODE>, where &lt;name&gt; has its
 88:  ** first letter capitalized by the constructor.<P>
 89:  **
 90:  ** Note that using this constructor the given property must be read- <strong>and</strong>
 91:  ** writeable. If the implementation does not both, a read and a write method, an
 92:  ** <code>IntrospectionException</code> is thrown.
 93:  **
 94:  ** <B>Implementation note:</B> If there is both are both isXXX and
 95:  ** getXXX methods, the former is used in preference to the latter.
 96:  ** We do not check that an isXXX method returns a boolean. In both
 97:  ** cases, this matches the behaviour of JDK 1.4<P>
 98:  **
 99:  ** @param name the programmatic name of the property, usually
 100:  ** starting with a lowercase letter (e.g. fooManChu
 101:  ** instead of FooManChu).
 102:  ** @param beanClass the class the get and set methods live in.
 103:  ** @exception IntrospectionException if the methods are not found 
 104:  ** or invalid.
 105:  **/
 106:  public PropertyDescriptor(String name, Class<?> beanClass)
 107:  throws IntrospectionException
 108:  {
 109:  setName(name);
 110:  if (name.length() == 0)
 111:  {
 112:  throw new IntrospectionException("empty property name");
 113:  }
 114:  String caps = Character.toUpperCase(name.charAt(0)) + name.substring(1);
 115:  findMethods(beanClass, "is" + caps, "get" + caps, "set" + caps);
 116: 
 117:  if (getMethod == null)
 118:  {
 119:  throw new IntrospectionException(
 120:  "Cannot find a is" + caps + " or get" + caps + " method");
 121:  }
 122: 
 123:  if (setMethod == null)
 124:  {
 125:  throw new IntrospectionException(
 126:  "Cannot find a " + caps + " method");
 127:  }
 128: 
 129:  // finally check the methods compatibility 
 130:  propertyType = checkMethods(getMethod, setMethod);
 131:  }
 132: 
 133:  /** Create a new PropertyDescriptor by introspection.
 134:  ** This form of constructor allows you to specify the
 135:  ** names of the get and set methods to search for.<P>
 136:  **
 137:  ** <B>Implementation note:</B> If there is a get method (or
 138:  ** boolean isXXX() method), then the return type of that method
 139:  ** is used to find the set method. If there is no get method,
 140:  ** then the set method is searched for exhaustively.<P>
 141:  **
 142:  ** <B>Spec note:</B>
 143:  ** If there is no get method and multiple set methods with
 144:  ** the same name and a single parameter (different type of course),
 145:  ** then an IntrospectionException is thrown. While Sun's spec
 146:  ** does not state this, it can make Bean behavior different on
 147:  ** different systems (since method order is not guaranteed) and as
 148:  ** such, can be treated as a bug in the spec. I am not aware of
 149:  ** whether Sun's implementation catches this.
 150:  **
 151:  ** @param name the programmatic name of the property, usually
 152:  ** starting with a lowercase letter (e.g. fooManChu
 153:  ** instead of FooManChu).
 154:  ** @param beanClass the class the get and set methods live in.
 155:  ** @param getMethodName the name of the get method or <code>null</code> if the property is write-only.
 156:  ** @param setMethodName the name of the set method or <code>null</code> if the property is read-only.
 157:  ** @exception IntrospectionException if the methods are not found 
 158:  ** or invalid.
 159:  **/
 160:  public PropertyDescriptor(
 161:  String name,
 162:  Class<?> beanClass,
 163:  String getMethodName,
 164:  String setMethodName)
 165:  throws IntrospectionException
 166:  {
 167:  setName(name);
 168:  findMethods(beanClass, getMethodName, null, setMethodName);
 169: 
 170:  if (getMethod == null && getMethodName != null)
 171:  {
 172:  throw new IntrospectionException(
 173:  "Cannot find a getter method called " + getMethodName);
 174:  }
 175: 
 176:  if (setMethod == null && setMethodName != null)
 177:  {
 178:  throw new IntrospectionException(
 179:  "Cannot find a setter method called " + setMethodName);
 180:  }
 181: 
 182:  propertyType = checkMethods(getMethod, setMethod);
 183:  }
 184: 
 185:  /** Create a new PropertyDescriptor using explicit Methods.
 186:  ** Note that the methods will be checked for conformance to standard
 187:  ** Property method rules, as described above at the top of this class.
 188:  **<br>
 189:  ** It is possible to call this method with both <code>Method</code> arguments
 190:  ** being <code>null</code>. In such a case the property type is <code>null</code>.
 191:  ** 
 192:  ** @param name the programmatic name of the property, usually
 193:  ** starting with a lowercase letter (e.g. fooManChu
 194:  ** instead of FooManChu).
 195:  ** @param readMethod the read method or <code>null</code> if the property is write-only.
 196:  ** @param writeMethod the write method or <code>null</code> if the property is read-only.
 197:  ** @exception IntrospectionException if the methods are not found 
 198:  ** or invalid.
 199:  **/
 200:  public PropertyDescriptor(
 201:  String name,
 202:  Method readMethod,
 203:  Method writeMethod)
 204:  throws IntrospectionException
 205:  {
 206:  setName(name);
 207:  getMethod = readMethod;
 208:  setMethod = writeMethod;
 209:  propertyType = checkMethods(getMethod, setMethod);
 210:  }
 211: 
 212:  /** Get the property type.
 213:  ** This is the type the get method returns and the set method
 214:  ** takes in.
 215:  **/
 216:  public Class<?> getPropertyType()
 217:  {
 218:  return propertyType;
 219:  }
 220: 
 221:  /** Get the get method. Why they call it readMethod here and
 222:  ** get everywhere else is beyond me.
 223:  **/
 224:  public Method getReadMethod()
 225:  {
 226:  return getMethod;
 227:  }
 228: 
 229:  /** Sets the read method.<br/>
 230:  * The read method is used to retrieve the value of a property. A legal
 231:  * read method must have no arguments. Its return type must not be
 232:  * <code>void</code>. If this methods succeeds the property type
 233:  * is adjusted to the return type of the read method.<br/>
 234:  * <br/>
 235:  * It is legal to set the read and the write method to <code>null</code>
 236:  * or provide method which have been declared in distinct classes.
 237:  * 
 238:  * @param readMethod The new method to be used or <code>null</code>.
 239:  * @throws IntrospectionException If the given method is invalid.
 240:  * @since 1.2
 241:  */
 242:  public void setReadMethod(Method readMethod) throws IntrospectionException
 243:  {
 244:  propertyType = checkMethods(readMethod, setMethod);
 245: 
 246:  getMethod = readMethod;
 247:  }
 248: 
 249:  /** Get the set method. Why they call it writeMethod here and
 250:  ** set everywhere else is beyond me.
 251:  **/
 252:  public Method getWriteMethod()
 253:  {
 254:  return setMethod;
 255:  }
 256: 
 257:  /** Sets the write method.<br/>
 258:  * The write method is used to set the value of a property. A legal write method
 259:  * must have a single argument which can be assigned to the property. If no
 260:  * read method exists the property type changes to the argument type of the
 261:  * write method.<br/>
 262:  * <br/>
 263:  * It is legal to set the read and the write method to <code>null</code>
 264:  * or provide method which have been declared in distinct classes.
 265:  * 
 266:  * @param writeMethod The new method to be used or <code>null</code>.
 267:  * @throws IntrospectionException If the given method is invalid.
 268:  * @since 1.2
 269:  */
 270:  public void setWriteMethod(Method writeMethod)
 271:  throws IntrospectionException
 272:  {
 273:  propertyType = checkMethods(getMethod, writeMethod);
 274: 
 275:  setMethod = writeMethod;
 276:  }
 277: 
 278:  /** Get whether the property is bound. Defaults to false. **/
 279:  public boolean isBound()
 280:  {
 281:  return bound;
 282:  }
 283: 
 284:  /** Set whether the property is bound.
 285:  ** As long as the the bean implements addPropertyChangeListener() and
 286:  ** removePropertyChangeListener(), setBound(true) may safely be called.<P>
 287:  ** If these things are not true, then the behavior of the system
 288:  ** will be undefined.<P>
 289:  **
 290:  ** When a property is bound, its set method is required to fire the
 291:  ** <CODE>PropertyChangeListener.propertyChange())</CODE> event
 292:  ** after the value has changed.
 293:  ** @param bound whether the property is bound or not.
 294:  **/
 295:  public void setBound(boolean bound)
 296:  {
 297:  this.bound = bound;
 298:  }
 299: 
 300:  /** Get whether the property is constrained. Defaults to false. **/
 301:  public boolean isConstrained()
 302:  {
 303:  return constrained;
 304:  }
 305: 
 306:  /** Set whether the property is constrained.
 307:  ** If the set method throws <CODE>java.beans.PropertyVetoException</CODE>
 308:  ** (or subclass thereof) and the bean implements addVetoableChangeListener()
 309:  ** and removeVetoableChangeListener(), then setConstrained(true) may safely
 310:  ** be called. Otherwise, the system behavior is undefined.
 311:  ** <B>Spec note:</B> given those strict parameters, it would be nice if it
 312:  ** got set automatically by detection, but oh well.<P>
 313:  ** When a property is constrained, its set method is required to:<P>
 314:  ** <OL>
 315:  ** <LI>Fire the <CODE>VetoableChangeListener.vetoableChange()</CODE>
 316:  ** event notifying others of the change and allowing them a chance to
 317:  ** say it is a bad thing.</LI>
 318:  ** <LI>If any of the listeners throws a PropertyVetoException, then
 319:  ** it must fire another vetoableChange() event notifying the others
 320:  ** of a reversion to the old value (though, of course, the change
 321:  ** was never made). Then it rethrows the PropertyVetoException and
 322:  ** exits.</LI>
 323:  ** <LI>If all has gone well to this point, the value may be changed.</LI>
 324:  ** </OL>
 325:  ** @param constrained whether the property is constrained or not.
 326:  **/
 327:  public void setConstrained(boolean constrained)
 328:  {
 329:  this.constrained = constrained;
 330:  }
 331: 
 332:  /** Get the PropertyEditor class. Defaults to null. **/
 333:  public Class<?> getPropertyEditorClass()
 334:  {
 335:  return propertyEditorClass;
 336:  }
 337: 
 338:  /** Set the PropertyEditor class. If the class does not implement
 339:  ** the PropertyEditor interface, you will likely get an exception
 340:  ** late in the game.
 341:  ** @param propertyEditorClass the PropertyEditor class for this 
 342:  ** class to use.
 343:  **/
 344:  public void setPropertyEditorClass(Class<?> propertyEditorClass)
 345:  {
 346:  this.propertyEditorClass = propertyEditorClass;
 347:  }
 348: 
 349:  /**
 350:  * Instantiate a property editor using the property editor class.
 351:  * If no property editor class has been set, this will return null.
 352:  * If the editor class has a public constructor which takes a single
 353:  * argument, that will be used and the bean parameter will be passed
 354:  * to it. Otherwise, a public no-argument constructor will be used,
 355:  * if available. This method will return null if no constructor is
 356:  * found or if construction fails for any reason.
 357:  * @param bean the argument to the constructor
 358:  * @return a new PropertyEditor, or null on error
 359:  * @since 1.5
 360:  */
 361:  public PropertyEditor createPropertyEditor(Object bean)
 362:  {
 363:  if (propertyEditorClass == null)
 364:  return null;
 365:  Constructor c = findConstructor(propertyEditorClass,
 366:  new Class[] { Object.class });
 367:  if (c != null)
 368:  return instantiateClass(c, new Object[] { bean });
 369:  c = findConstructor(propertyEditorClass, null);
 370:  if (c != null)
 371:  return instantiateClass(c, null);
 372:  return null;
 373:  }
 374: 
 375:  // Helper method to look up a constructor and return null if it is not
 376:  // found.
 377:  private Constructor findConstructor(Class k, Class[] argTypes)
 378:  {
 379:  try
 380:  {
 381:  return k.getConstructor(argTypes);
 382:  }
 383:  catch (NoSuchMethodException _)
 384:  {
 385:  return null;
 386:  }
 387:  }
 388: 
 389:  // Helper method to instantiate an object but return null on error.
 390:  private PropertyEditor instantiateClass(Constructor c, Object[] args)
 391:  {
 392:  try
 393:  {
 394:  return (PropertyEditor) c.newInstance(args);
 395:  }
 396:  catch (InstantiationException _)
 397:  {
 398:  return null;
 399:  }
 400:  catch (InvocationTargetException _)
 401:  {
 402:  return null;
 403:  }
 404:  catch (IllegalAccessException _)
 405:  {
 406:  return null;
 407:  }
 408:  catch (ClassCastException _)
 409:  {
 410:  return null;
 411:  }
 412:  }
 413: 
 414:  private void findMethods(
 415:  Class beanClass,
 416:  String getMethodName1,
 417:  String getMethodName2,
 418:  String setMethodName)
 419:  throws IntrospectionException
 420:  {
 421:  try
 422:  {
 423:  // Try the first get method name
 424:  if (getMethodName1 != null)
 425:  {
 426:  try
 427:  {
 428:  getMethod =
 429:  beanClass.getMethod(getMethodName1, new Class[0]);
 430:  }
 431:  catch (NoSuchMethodException e)
 432:  {}
 433:  }
 434: 
 435:  // Fall back to the second get method name
 436:  if (getMethod == null && getMethodName2 != null)
 437:  {
 438:  try
 439:  {
 440:  getMethod =
 441:  beanClass.getMethod(getMethodName2, new Class[0]);
 442:  }
 443:  catch (NoSuchMethodException e)
 444:  {}
 445:  }
 446: 
 447:  // Try the set method name
 448:  if (setMethodName != null)
 449:  {
 450:  if (getMethod != null)
 451:  {
 452:  // If there is a get method, use its return type to help
 453:  // select the corresponding set method.
 454:  Class propertyType = getMethod.getReturnType();
 455:  if (propertyType == Void.TYPE)
 456:  {
 457:  String msg =
 458:  "The property's read method has return type 'void'";
 459:  throw new IntrospectionException(msg);
 460:  }
 461: 
 462:  Class[] setArgs = new Class[] { propertyType };
 463:  try
 464:  {
 465:  setMethod = beanClass.getMethod(setMethodName, setArgs);
 466:  }
 467:  catch (NoSuchMethodException e)
 468:  {}
 469:  }
 470:  else if (getMethodName1 == null && getMethodName2 == null)
 471:  {
 472:  // If this is a write-only property, choose the first set method
 473:  // with the required name, one parameter and return type 'void'
 474:  Method[] methods = beanClass.getMethods();
 475:  for (int i = 0; i < methods.length; i++)
 476:  {
 477:  if (methods[i].getName().equals(setMethodName)
 478:  && methods[i].getParameterTypes().length == 1
 479:  && methods[i].getReturnType() == Void.TYPE)
 480:  {
 481:  setMethod = methods[i];
 482:  break;
 483:  }
 484:  }
 485:  }
 486:  }
 487:  }
 488:  catch (SecurityException e)
 489:  {
 490:  // FIXME -- shouldn't we just allow SecurityException to propagate?
 491:  String msg =
 492:  "SecurityException thrown on attempt to access methods.";
 493:  throw new IntrospectionException(msg);
 494:  }
 495:  }
 496: 
 497:  /** Checks whether the given <code>Method</code> instances are legal read and
 498:  * write methods. The following requirements must be met:<br/>
 499:  * <ul>
 500:  * <li>the read method must not have an argument</li>
 501:  * <li>the read method must have a non void return type</li>
 502:  * <li>the read method may not exist</li>
 503:  * <li>the write method must have a single argument</li>
 504:  * <li>the property type and the read method's return type must be assignable from the
 505:  * write method's argument type</li>
 506:  * <li>the write method may not exist</li>
 507:  * </ul>
 508:  * While checking the methods a common new property type is calculated. If the method
 509:  * succeeds this property type is returned.<br/>
 510:  * <br/>
 511:  * For compatibility this has to be noted:<br/>
 512:  * The two methods are allowed to be defined in two distinct classes and may both be null.
 513:  * 
 514:  * @param readMethod The new read method to check.
 515:  * @param writeMethod The new write method to check.
 516:  * @return The common property type of the two method.
 517:  * @throws IntrospectionException If any of the above requirements are not met.
 518:  */
 519:  private Class<?> checkMethods(Method readMethod, Method writeMethod)
 520:  throws IntrospectionException
 521:  {
 522:  Class<?> newPropertyType = propertyType;
 523: 
 524:  // a valid read method has zero arguments and a non-void return type.
 525:  if (readMethod != null)
 526:  {
 527:  if (readMethod.getParameterTypes().length > 0)
 528:  {
 529:  throw new IntrospectionException("read method has unexpected parameters");
 530:  }
 531: 
 532:  newPropertyType = readMethod.getReturnType();
 533: 
 534:  if (newPropertyType == Void.TYPE)
 535:  {
 536:  throw new IntrospectionException("read method return type is void");
 537:  }
 538:  }
 539: 
 540:  // a valid write method has one argument which can be assigned to the property
 541:  if (writeMethod != null)
 542:  {
 543:  if (writeMethod.getParameterTypes().length != 1)
 544:  {
 545:  String msg = "write method does not have exactly one parameter";
 546:  throw new IntrospectionException(msg);
 547:  }
 548: 
 549:  if (readMethod == null)
 550:  {
 551:  // changes the property type if there is no read method
 552:  newPropertyType = writeMethod.getParameterTypes()[0];
 553:  }
 554:  else
 555:  {
 556:  // checks whether the write method can be assigned to the return type of the read
 557:  // method (if this is not the case, the methods are not compatible)
 558:  // note: newPropertyType may be null if no methods or method names have been
 559:  // delivered in the constructor.
 560:  if (newPropertyType != null
 561:  && !newPropertyType.isAssignableFrom(
 562:  writeMethod.getParameterTypes()[0]))
 563:  {
 564:  // note: newPropertyType is the same as readMethod.getReturnType() at this point
 565:  throw new IntrospectionException("read and write method are not compatible");
 566:  }
 567: 
 568:  /* note: the check whether both method are defined in related classes makes sense but is not
 569:  * done in the JDK. 
 570:  * I leave this code here in case someone at Sun decides to add that functionality in later versions (rschuster)
 571:  if ((!readMethod
 572:  .getDeclaringClass()
 573:  .isAssignableFrom(writeMethod.getDeclaringClass()))
 574:  && (!writeMethod
 575:  .getDeclaringClass()
 576:  .isAssignableFrom(readMethod.getDeclaringClass())))
 577:  {
 578:  String msg =
 579:  "set and get methods are not in the same class.";
 580:  throw new IntrospectionException(msg);
 581:  }
 582:  */
 583: 
 584:  }
 585:  }
 586: 
 587:  return newPropertyType;
 588:  }
 589: 
 590:  /**
 591:  * Return a hash code for this object, conforming to the contract described
 592:  * in {@link Object#hashCode()}.
 593:  * @return the hash code
 594:  * @since 1.5
 595:  */
 596:  public int hashCode()
 597:  {
 598:  return ((propertyType == null ? 0 : propertyType.hashCode())
 599:  | (propertyEditorClass == null ? 0 : propertyEditorClass.hashCode())
 600:  | (bound ? Boolean.TRUE : Boolean.FALSE).hashCode()
 601:  | (constrained ? Boolean.TRUE : Boolean.FALSE).hashCode()
 602:  | (getMethod == null ? 0 : getMethod.hashCode())
 603:  | (setMethod == null ? 0 : setMethod.hashCode()));
 604:  }
 605: 
 606:  /** Compares this <code>PropertyDescriptor</code> against the
 607:  * given object.
 608:  * Two PropertyDescriptors are equals if
 609:  * <ul>
 610:  * <li>the read methods are equal</li>
 611:  * <li>the write methods are equal</li>
 612:  * <li>the property types are equals</li>
 613:  * <li>the property editor classes are equal</li>
 614:  * <li>the flags (constrained and bound) are equal</li>
 615:  * </ul>
 616:  * @return Whether both objects are equal according to the rules given above.
 617:  * @since 1.4
 618:  */
 619:  public boolean equals(Object o)
 620:  {
 621:  if (o instanceof PropertyDescriptor)
 622:  {
 623:  PropertyDescriptor that = (PropertyDescriptor) o;
 624: 
 625:  // compares the property types and checks the case where both are null
 626:  boolean samePropertyType =
 627:  (propertyType == null)
 628:  ? that.propertyType == null
 629:  : propertyType.equals(that.propertyType);
 630: 
 631:  // compares the property editor classes and checks the case where both are null
 632:  boolean samePropertyEditorClass =
 633:  (propertyEditorClass == null)
 634:  ? that.propertyEditorClass == null
 635:  : propertyEditorClass.equals(that.propertyEditorClass);
 636: 
 637:  // compares the flags for equality
 638:  boolean sameFlags =
 639:  bound == that.bound && constrained == that.constrained;
 640: 
 641:  // compares the read methods and checks the case where both are null
 642:  boolean sameReadMethod =
 643:  (getMethod == null)
 644:  ? that.getMethod == null
 645:  : getMethod.equals(that.getMethod);
 646: 
 647:  boolean sameWriteMethod =
 648:  (setMethod == null)
 649:  ? that.setMethod == null
 650:  : setMethod.equals(that.setMethod);
 651: 
 652:  return samePropertyType
 653:  && sameFlags
 654:  && sameReadMethod
 655:  && sameWriteMethod
 656:  && samePropertyEditorClass;
 657:  }
 658:  else
 659:  {
 660:  return false;
 661:  }
 662:  
 663:  }
 664: 
 665: }
Overview Package Class Use Source Tree Index Deprecated About
GNU Classpath (0.95)

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