41
41
* Decorator for a standard {@link BeanInfo} object, e.g. as created by
42
42
* {@link Introspector#getBeanInfo(Class)}, designed to discover and register static
43
43
* and/or non-void returning setter methods. For example:
44
- * <pre>{@ code
44
+ * <pre class=" code">
45
45
* public class Bean {
46
46
* private Foo foo;
47
47
*
53
53
* this.foo = foo;
54
54
* return this;
55
55
* }
56
- * }} </pre>
56
+ * }</pre>
57
57
* The standard JavaBeans {@code Introspector} will discover the {@code getFoo} read
58
58
* method, but will bypass the {@code #setFoo(Foo)} write method, because its non-void
59
59
* returning signature does not comply with the JavaBeans specification.
@@ -206,31 +206,31 @@ public PropertyDescriptor[] getPropertyDescriptors() {
206
206
}
207
207
208
208
public BeanInfo [] getAdditionalBeanInfo () {
209
- return delegate .getAdditionalBeanInfo ();
209
+ return this . delegate .getAdditionalBeanInfo ();
210
210
}
211
211
212
212
public BeanDescriptor getBeanDescriptor () {
213
- return delegate .getBeanDescriptor ();
213
+ return this . delegate .getBeanDescriptor ();
214
214
}
215
215
216
216
public int getDefaultEventIndex () {
217
- return delegate .getDefaultEventIndex ();
217
+ return this . delegate .getDefaultEventIndex ();
218
218
}
219
219
220
220
public int getDefaultPropertyIndex () {
221
- return delegate .getDefaultPropertyIndex ();
221
+ return this . delegate .getDefaultPropertyIndex ();
222
222
}
223
223
224
224
public EventSetDescriptor [] getEventSetDescriptors () {
225
- return delegate .getEventSetDescriptors ();
225
+ return this . delegate .getEventSetDescriptors ();
226
226
}
227
227
228
228
public Image getIcon (int iconKind ) {
229
- return delegate .getIcon (iconKind );
229
+ return this . delegate .getIcon (iconKind );
230
230
}
231
231
232
232
public MethodDescriptor [] getMethodDescriptors () {
233
- return delegate .getMethodDescriptors ();
233
+ return this . delegate .getMethodDescriptors ();
234
234
}
235
235
}
236
236
@@ -284,7 +284,7 @@ public Class<?> getPropertyType() {
284
284
this .propertyType = findPropertyType (this .readMethod , this .writeMethod );
285
285
}
286
286
catch (IntrospectionException ex ) {
287
- // ignore , as does PropertyDescriptor#getPropertyType
287
+ // Ignore , as does PropertyDescriptor#getPropertyType
288
288
}
289
289
}
290
290
return this .propertyType ;
@@ -374,7 +374,7 @@ public Class<?> getPropertyType() {
374
374
this .propertyType = findPropertyType (this .readMethod , this .writeMethod );
375
375
}
376
376
catch (IntrospectionException ex ) {
377
- // ignore , as does IndexedPropertyDescriptor#getPropertyType
377
+ // Ignore , as does IndexedPropertyDescriptor#getPropertyType
378
378
}
379
379
}
380
380
return this .propertyType ;
@@ -408,7 +408,7 @@ public Class<?> getIndexedPropertyType() {
408
408
getName (), getPropertyType (), this .indexedReadMethod , this .indexedWriteMethod );
409
409
}
410
410
catch (IntrospectionException ex ) {
411
- // ignore , as does IndexedPropertyDescriptor#getIndexedPropertyType
411
+ // Ignore , as does IndexedPropertyDescriptor#getIndexedPropertyType
412
412
}
413
413
}
414
414
return this .indexedPropertyType ;
@@ -473,14 +473,14 @@ public static void copyNonMethodProperties(PropertyDescriptor source, PropertyDe
473
473
target .setShortDescription (source .getShortDescription ());
474
474
target .setDisplayName (source .getDisplayName ());
475
475
476
- // copy all attributes (emulating behavior of private FeatureDescriptor#addTable)
476
+ // Copy all attributes (emulating behavior of private FeatureDescriptor#addTable)
477
477
Enumeration <String > keys = source .attributeNames ();
478
478
while (keys .hasMoreElements ()) {
479
479
String key = keys .nextElement ();
480
480
target .setValue (key , source .getValue (key ));
481
481
}
482
482
483
- // see java.beans.PropertyDescriptor#PropertyDescriptor(PropertyDescriptor)
483
+ // See java.beans.PropertyDescriptor#PropertyDescriptor(PropertyDescriptor)
484
484
target .setPropertyEditorClass (source .getPropertyEditorClass ());
485
485
target .setBound (source .isBound ());
486
486
target .setConstrained (source .isConstrained ());
@@ -494,24 +494,34 @@ public static Class<?> findPropertyType(Method readMethod, Method writeMethod) t
494
494
if (readMethod != null ) {
495
495
Class <?>[] params = readMethod .getParameterTypes ();
496
496
if (params .length != 0 ) {
497
- throw new IntrospectionException ("bad read method arg count: " + readMethod );
497
+ throw new IntrospectionException ("Bad read method arg count: " + readMethod );
498
498
}
499
499
propertyType = readMethod .getReturnType ();
500
500
if (propertyType == Void .TYPE ) {
501
- throw new IntrospectionException ("read method "
502
- + readMethod .getName () + " returns void" );
501
+ throw new IntrospectionException ("Read method returns void: " + readMethod );
503
502
}
504
503
}
505
504
if (writeMethod != null ) {
506
505
Class <?> params [] = writeMethod .getParameterTypes ();
507
506
if (params .length != 1 ) {
508
- throw new IntrospectionException ("bad write method arg count: " + writeMethod );
507
+ throw new IntrospectionException ("Bad write method arg count: " + writeMethod );
509
508
}
510
- if (propertyType != null
511
- && !params [0 ].isAssignableFrom (propertyType )) {
512
- throw new IntrospectionException ("type mismatch between read and write methods" );
509
+ if (propertyType != null ) {
510
+ if (propertyType .isAssignableFrom (params [0 ])) {
511
+ // Write method's property type potentially more specific
512
+ propertyType = params [0 ];
513
+ }
514
+ else if (params [0 ].isAssignableFrom (propertyType )) {
515
+ // Proceed with read method's property type
516
+ }
517
+ else {
518
+ throw new IntrospectionException (
519
+ "Type mismatch between read and write methods: " + readMethod + " - " + writeMethod );
520
+ }
521
+ }
522
+ else {
523
+ propertyType = params [0 ];
513
524
}
514
- propertyType = params [0 ];
515
525
}
516
526
return propertyType ;
517
527
}
@@ -523,44 +533,48 @@ public static Class<?> findIndexedPropertyType(String name, Class<?> propertyTyp
523
533
Method indexedReadMethod , Method indexedWriteMethod ) throws IntrospectionException {
524
534
525
535
Class <?> indexedPropertyType = null ;
526
-
527
536
if (indexedReadMethod != null ) {
528
537
Class <?> params [] = indexedReadMethod .getParameterTypes ();
529
538
if (params .length != 1 ) {
530
- throw new IntrospectionException (
531
- "bad indexed read method arg count" );
539
+ throw new IntrospectionException ("Bad indexed read method arg count: " + indexedReadMethod );
532
540
}
533
541
if (params [0 ] != Integer .TYPE ) {
534
- throw new IntrospectionException (
535
- "non int index to indexed read method" );
542
+ throw new IntrospectionException ("Non int index to indexed read method: " + indexedReadMethod );
536
543
}
537
544
indexedPropertyType = indexedReadMethod .getReturnType ();
538
545
if (indexedPropertyType == Void .TYPE ) {
539
- throw new IntrospectionException (
540
- "indexed read method returns void" );
546
+ throw new IntrospectionException ("Indexed read method returns void: " + indexedReadMethod );
541
547
}
542
548
}
543
549
if (indexedWriteMethod != null ) {
544
550
Class <?> params [] = indexedWriteMethod .getParameterTypes ();
545
551
if (params .length != 2 ) {
546
- throw new IntrospectionException (
547
- "bad indexed write method arg count" );
552
+ throw new IntrospectionException ("Bad indexed write method arg count: " + indexedWriteMethod );
548
553
}
549
554
if (params [0 ] != Integer .TYPE ) {
550
- throw new IntrospectionException (
551
- "non int index to indexed write method" );
555
+ throw new IntrospectionException ("Non int index to indexed write method: " + indexedWriteMethod );
552
556
}
553
- if (indexedPropertyType != null && indexedPropertyType != params [1 ]) {
554
- throw new IntrospectionException (
555
- "type mismatch between indexed read and indexed write methods: " + name );
557
+ if (indexedPropertyType != null ) {
558
+ if (indexedPropertyType .isAssignableFrom (params [1 ])) {
559
+ // Write method's property type potentially more specific
560
+ indexedPropertyType = params [1 ];
561
+ }
562
+ else if (params [1 ].isAssignableFrom (indexedPropertyType )) {
563
+ // Proceed with read method's property type
564
+ }
565
+ else {
566
+ throw new IntrospectionException ("Type mismatch between indexed read and write methods: " +
567
+ indexedReadMethod + " - " + indexedWriteMethod );
568
+ }
569
+ }
570
+ else {
571
+ indexedPropertyType = params [1 ];
556
572
}
557
- indexedPropertyType = params [1 ];
558
573
}
559
- if (propertyType != null
560
- && (!propertyType .isArray () ||
561
- propertyType .getComponentType () != indexedPropertyType )) {
562
- throw new IntrospectionException (
563
- "type mismatch between indexed and non-indexed methods: " + name );
574
+ if (propertyType != null && (!propertyType .isArray () ||
575
+ propertyType .getComponentType () != indexedPropertyType )) {
576
+ throw new IntrospectionException ("Type mismatch between indexed and non-indexed methods: " +
577
+ indexedReadMethod + " - " + indexedWriteMethod );
564
578
}
565
579
return indexedPropertyType ;
566
580
}
@@ -581,15 +595,12 @@ public static boolean equals(PropertyDescriptor pd1, Object obj) {
581
595
if (!compareMethods (pd1 .getReadMethod (), pd2 .getReadMethod ())) {
582
596
return false ;
583
597
}
584
-
585
598
if (!compareMethods (pd1 .getWriteMethod (), pd2 .getWriteMethod ())) {
586
599
return false ;
587
600
}
588
-
589
- if (pd1 .getPropertyType () == pd2 .getPropertyType ()
590
- && pd1 .getPropertyEditorClass () == pd2 .getPropertyEditorClass ()
591
- && pd1 .isBound () == pd2 .isBound ()
592
- && pd1 .isConstrained () == pd2 .isConstrained ()) {
601
+ if (pd1 .getPropertyType () == pd2 .getPropertyType () &&
602
+ pd1 .getPropertyEditorClass () == pd2 .getPropertyEditorClass () &&
603
+ pd1 .isBound () == pd2 .isBound () && pd1 .isConstrained () == pd2 .isConstrained ()) {
593
604
return true ;
594
605
}
595
606
}
@@ -603,7 +614,7 @@ public static boolean compareMethods(Method a, Method b) {
603
614
if ((a == null ) != (b == null )) {
604
615
return false ;
605
616
}
606
- if (a != null && b != null ) {
617
+ if (a != null ) {
607
618
if (!a .equals (b )) {
608
619
return false ;
609
620
}
0 commit comments