1 7 8 package java.beans; 9 10 import java.lang.ref.Reference ; 11 12 import java.lang.reflect.Method ; 13 import java.lang.reflect.Constructor ; 14 15 19 public class PropertyDescriptor extends FeatureDescriptor { 20 21 private Reference propertyTypeRef; 22 private Reference readMethodRef; 23 private Reference writeMethodRef; 24 private Reference propertyEditorClassRef; 25 26 private boolean bound; 27 private boolean constrained; 28 29 private String baseName; 32 33 private String writeMethodName; 34 private String readMethodName; 35 36 51 public PropertyDescriptor(String propertyName, Class <?> beanClass) 52 throws IntrospectionException { 53 this(propertyName, beanClass, 54 "is" + capitalize(propertyName), 55 "set" + capitalize(propertyName)); 56 } 57 58 72 public PropertyDescriptor(String propertyName, Class <?> beanClass, 73 String readMethodName, String writeMethodName) 74 throws IntrospectionException { 75 if (beanClass == null) { 76 throw new IntrospectionException ("Target Bean class is null"); 77 } 78 if (propertyName == null || propertyName.length() == 0) { 79 throw new IntrospectionException ("bad property name"); 80 } 81 if ("".equals(readMethodName) || "".equals(writeMethodName)) { 82 throw new IntrospectionException ("read or write method name should not be the empty string"); 83 } 84 setName(propertyName); 85 setClass0(beanClass); 86 87 this.readMethodName = readMethodName; 88 if (readMethodName != null && getReadMethod() == null) { 89 throw new IntrospectionException ("Method not found: " + readMethodName); 90 } 91 this.writeMethodName = writeMethodName; 92 if (writeMethodName != null && getWriteMethod() == null) { 93 throw new IntrospectionException ("Method not found: " + writeMethodName); 94 } 95 96 } 97 98 110 public PropertyDescriptor(String propertyName, Method readMethod, Method writeMethod) 111 throws IntrospectionException { 112 if (propertyName == null || propertyName.length() == 0) { 113 throw new IntrospectionException ("bad property name"); 114 } 115 setName(propertyName); 116 setReadMethod(readMethod); 117 setWriteMethod(writeMethod); 118 } 119 120 130 public synchronized Class <?> getPropertyType() { 131 Class type = getPropertyType0(); 132 if (type == null) { 133 try { 134 type = findPropertyType(getReadMethod(), getWriteMethod()); 135 setPropertyType(type); 136 } catch (IntrospectionException ex) { 137 } 139 } 140 return type; 141 } 142 143 private void setPropertyType(Class type) { 144 propertyTypeRef = createReference(type); 145 } 146 147 private Class getPropertyType0() { 148 return (Class )getObject(propertyTypeRef); 149 } 150 151 157 public synchronized Method getReadMethod() { 158 Method readMethod = getReadMethod0(); 159 if (readMethod == null) { 160 Class cls = getClass0(); 161 if (cls == null || (readMethodName == null && readMethodRef == null)) { 162 return null; 164 } 165 if (readMethodName == null) { 166 Class type = getPropertyType0(); 167 if (type == boolean.class || type == null) { 168 readMethodName = "is" + getBaseName(); 169 } else { 170 readMethodName = "get" + getBaseName(); 171 } 172 } 173 174 readMethod = Introspector.findMethod(cls, readMethodName, 0); 180 if (readMethod == null) { 181 readMethodName = "get" + getBaseName(); 182 readMethod = Introspector.findMethod(cls, readMethodName, 0); 183 } 184 try { 185 setReadMethod(readMethod); 186 } catch (IntrospectionException ex) { 187 } 189 } 190 return readMethod; 191 } 192 193 198 public synchronized void setReadMethod(Method readMethod) 199 throws IntrospectionException { 200 if (readMethod == null) { 201 readMethodName = null; 202 readMethodRef = null; 203 return; 204 } 205 setPropertyType(findPropertyType(readMethod, getWriteMethod0())); 207 setClass0(readMethod.getDeclaringClass()); 208 209 readMethodName = readMethod.getName(); 210 readMethodRef = createReference(readMethod, true); 211 } 212 213 219 public synchronized Method getWriteMethod() { 220 Method writeMethod = getWriteMethod0(); 221 if (writeMethod == null) { 222 Class cls = getClass0(); 223 if (cls == null || (writeMethodName == null && writeMethodRef == null)) { 224 return null; 226 } 227 228 Class type = getPropertyType0(); 230 if (type == null) { 231 try { 232 type = findPropertyType(getReadMethod(), null); 234 setPropertyType(type); 235 } catch (IntrospectionException ex) { 236 return null; 239 } 240 } 241 242 if (writeMethodName == null) { 243 writeMethodName = "set" + getBaseName(); 244 } 245 246 writeMethod = Introspector.findMethod(cls, writeMethodName, 1, 247 (type == null) ? null : new Class [] { type }); 248 try { 249 setWriteMethod(writeMethod); 250 } catch (IntrospectionException ex) { 251 } 253 } 254 return writeMethod; 255 } 256 257 262 public synchronized void setWriteMethod(Method writeMethod) 263 throws IntrospectionException { 264 if (writeMethod == null) { 265 writeMethodName = null; 266 writeMethodRef = null; 267 return; 268 } 269 setPropertyType(findPropertyType(getReadMethod(), writeMethod)); 271 setClass0(writeMethod.getDeclaringClass()); 272 273 writeMethodName = writeMethod.getName(); 274 writeMethodRef = createReference(writeMethod, true); 275 276 } 277 278 private Method getReadMethod0() { 279 return (Method )getObject(readMethodRef); 280 } 281 282 private Method getWriteMethod0() { 283 return (Method )getObject(writeMethodRef); 284 } 285 286 289 void setClass0(Class clz) { 290 if (getClass0() != null && clz.isAssignableFrom(getClass0())) { 291 return; 293 } 294 super.setClass0(clz); 295 } 296 297 303 public boolean isBound() { 304 return bound; 305 } 306 307 313 public void setBound(boolean bound) { 314 this.bound = bound; 315 } 316 317 323 public boolean isConstrained() { 324 return constrained; 325 } 326 327 333 public void setConstrained(boolean constrained) { 334 this.constrained = constrained; 335 } 336 337 338 346 public void setPropertyEditorClass(Class <?> propertyEditorClass) { 347 propertyEditorClassRef = createReference(propertyEditorClass); 348 } 349 350 360 public Class <?> getPropertyEditorClass() { 361 return (Class )getObject(propertyEditorClassRef); 362 } 363 364 377 public PropertyEditor createPropertyEditor(Object bean) { 378 Object editor = null; 379 380 Class cls = getPropertyEditorClass(); 381 if (cls != null) { 382 Constructor ctor = null; 383 if (bean != null) { 384 try { 385 ctor = cls.getConstructor(new Class [] { Object .class }); 386 } catch (Exception ex) { 387 } 389 } 390 try { 391 if (ctor == null) { 392 editor = cls.newInstance(); 393 } else { 394 editor = ctor.newInstance(new Object [] { bean }); 395 } 396 } catch (Exception ex) { 397 throw new RuntimeException ("PropertyEditor not instantiated", 400 ex); 401 } 402 } 403 return (PropertyEditor )editor; 404 } 405 406 407 415 public boolean equals(Object obj) { 416 if (this == obj) { 417 return true; 418 } 419 if (obj != null && obj instanceof PropertyDescriptor ) { 420 PropertyDescriptor other = (PropertyDescriptor )obj; 421 Method otherReadMethod = other.getReadMethod(); 422 Method otherWriteMethod = other.getWriteMethod(); 423 424 if (!compareMethods(getReadMethod(), otherReadMethod)) { 425 return false; 426 } 427 428 if (!compareMethods(getWriteMethod(), otherWriteMethod)) { 429 return false; 430 } 431 432 if (getPropertyType() == other.getPropertyType() && 433 getPropertyEditorClass() == other.getPropertyEditorClass() && 434 bound == other.isBound() && constrained == other.isConstrained() && 435 writeMethodName == other.writeMethodName && 436 readMethodName == other.readMethodName) { 437 return true; 438 } 439 } 440 return false; 441 } 442 443 450 boolean compareMethods(Method a, Method b) { 451 if ((a == null) != (b == null)) { 453 return false; 454 } 455 456 if (a != null && b != null) { 457 if (!a.equals(b)) { 458 return false; 459 } 460 } 461 return true; 462 } 463 464 472 PropertyDescriptor(PropertyDescriptor x, PropertyDescriptor y) { 473 super(x,y); 474 475 if (y.baseName != null) { 476 baseName = y.baseName; 477 } else { 478 baseName = x.baseName; 479 } 480 481 if (y.readMethodName != null) { 482 readMethodName = y.readMethodName; 483 } else { 484 readMethodName = x.readMethodName; 485 } 486 487 if (y.writeMethodName != null) { 488 writeMethodName = y.writeMethodName; 489 } else { 490 writeMethodName = x.writeMethodName; 491 } 492 493 if (y.propertyTypeRef != null) { 494 propertyTypeRef = y.propertyTypeRef; 495 } else { 496 propertyTypeRef = x.propertyTypeRef; 497 } 498 499 Method xr = x.getReadMethod(); 501 Method yr = y.getReadMethod(); 502 503 try { 505 if (yr != null && yr.getDeclaringClass() == getClass0()) { 506 setReadMethod(yr); 507 } else { 508 setReadMethod(xr); 509 } 510 } catch (IntrospectionException ex) { 511 } 513 514 if (xr != null && yr != null && 517 xr.getDeclaringClass() == yr.getDeclaringClass() && 518 xr.getReturnType() == boolean.class && 519 yr.getReturnType() == boolean.class && 520 xr.getName().indexOf("is") == 0 && 521 yr.getName().indexOf("get") == 0) { 522 try { 523 setReadMethod(xr); 524 } catch (IntrospectionException ex) { 525 } 527 } 528 529 Method xw = x.getWriteMethod(); 530 Method yw = y.getWriteMethod(); 531 532 try { 533 if (yw != null && yw.getDeclaringClass() == getClass0()) { 534 setWriteMethod(yw); 535 } else { 536 setWriteMethod(xw); 537 } 538 } catch (IntrospectionException ex) { 539 } 541 542 if (y.getPropertyEditorClass() != null) { 543 setPropertyEditorClass(y.getPropertyEditorClass()); 544 } else { 545 setPropertyEditorClass(x.getPropertyEditorClass()); 546 } 547 548 549 bound = x.bound | y.bound; 550 constrained = x.constrained | y.constrained; 551 } 552 553 557 PropertyDescriptor(PropertyDescriptor old) { 558 super(old); 559 propertyTypeRef = old.propertyTypeRef; 560 readMethodRef = old.readMethodRef; 561 writeMethodRef = old.writeMethodRef; 562 propertyEditorClassRef = old.propertyEditorClassRef; 563 564 writeMethodName = old.writeMethodName; 565 readMethodName = old.readMethodName; 566 baseName = old.baseName; 567 568 bound = old.bound; 569 constrained = old.constrained; 570 } 571 572 580 private Class findPropertyType(Method readMethod, Method writeMethod) 581 throws IntrospectionException { 582 Class propertyType = null; 583 try { 584 if (readMethod != null) { 585 Class [] params = readMethod.getParameterTypes(); 586 if (params.length != 0) { 587 throw new IntrospectionException ("bad read method arg count: " 588 + readMethod); 589 } 590 propertyType = readMethod.getReturnType(); 591 if (propertyType == Void.TYPE) { 592 throw new IntrospectionException ("read method " + 593 readMethod.getName() + " returns void"); 594 } 595 } 596 if (writeMethod != null) { 597 Class params[] = writeMethod.getParameterTypes(); 598 if (params.length != 1) { 599 throw new IntrospectionException ("bad write method arg count: " 600 + writeMethod); 601 } 602 if (propertyType != null && propertyType != params[0]) { 603 throw new IntrospectionException ("type mismatch between read and write methods"); 604 } 605 propertyType = params[0]; 606 } 607 } catch (IntrospectionException ex) { 608 throw ex; 609 } 610 return propertyType; 611 } 612 613 614 621 public int hashCode() { 622 int result = 7; 623 624 result = 37 * result + ((getPropertyType() == null) ? 0 : 625 getPropertyType().hashCode()); 626 result = 37 * result + ((getReadMethod() == null) ? 0 : 627 getReadMethod().hashCode()); 628 result = 37 * result + ((getWriteMethod() == null) ? 0 : 629 getWriteMethod().hashCode()); 630 result = 37 * result + ((getPropertyEditorClass() == null) ? 0 : 631 getPropertyEditorClass().hashCode()); 632 result = 37 * result + ((writeMethodName == null) ? 0 : 633 writeMethodName.hashCode()); 634 result = 37 * result + ((readMethodName == null) ? 0 : 635 readMethodName.hashCode()); 636 result = 37 * result + getName().hashCode(); 637 result = 37 * result + ((bound == false) ? 0 : 1); 638 result = 37 * result + ((constrained == false) ? 0 : 1); 639 640 return result; 641 } 642 643 String getBaseName() { 645 if (baseName == null) { 646 baseName = capitalize(getName()); 647 } 648 return baseName; 649 } 650 651 669 } 670 | Popular Tags |