1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.beanutils;
20
21
22 import java.beans.PropertyDescriptor;
23 import java.lang.reflect.InvocationTargetException;
24 import java.lang.reflect.Method;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.StringTokenizer;
31
32 import org.apache.commons.beanutils.priv.PrivateBeanFactory;
33 import org.apache.commons.beanutils.priv.PrivateDirect;
34
35 import junit.framework.TestCase;
36 import junit.framework.Test;
37 import junit.framework.TestSuite;
38
39
40 /***
41 * <p>Test Case for the PropertyUtils class. The majority of these tests use
42 * instances of the TestBean class, so be sure to update the tests if you
43 * change the characteristics of that class.</p>
44 *
45 * <p>So far, this test case has tests for the following methods of the
46 * <code>PropertyUtils</code> class:</p>
47 * <ul>
48 * <li>getIndexedProperty(Object,String)</li>
49 * <li>getIndexedProperty(Object,String,int)</li>
50 * <li>getMappedProperty(Object,String)</li>
51 * <li>getMappedProperty(Object,String,String</li>
52 * <li>getNestedProperty(Object,String)</li>
53 * <li>getPropertyDescriptor(Object,String)</li>
54 * <li>getPropertyDescriptors(Object)</li>
55 * <li>getPropertyType(Object,String)</li>
56 * <li>getSimpleProperty(Object,String)</li>
57 * <li>setIndexedProperty(Object,String,Object)</li>
58 * <li>setIndexedProperty(Object,String,String,Object)</li>
59 * <li>setMappedProperty(Object,String,Object)</li>
60 * <li>setMappedProperty(Object,String,String,Object)</li>
61 * <li>setNestedProperty(Object,String,Object)</li>
62 * <li>setSimpleProperty(Object,String,Object)</li>
63 * </ul>
64 *
65 * @author Craig R. McClanahan
66 * @author Jan Sorensen
67 * @version $Revision: 555184 $ $Date: 2007-07-11 07:25:35 +0100 (Wed, 11 Jul 2007) $
68 */
69
70 public class PropertyUtilsTestCase extends TestCase {
71
72
73
74
75
76 /***
77 * The fully qualified class name of our private directly
78 * implemented interface.
79 */
80 private static final String PRIVATE_DIRECT_CLASS =
81 "org.apache.commons.beanutils.priv.PrivateDirect";
82
83
84 /***
85 * The fully qualified class name of our private indirectly
86 * implemented interface.
87 */
88 private static final String PRIVATE_INDIRECT_CLASS =
89 "org.apache.commons.beanutils.priv.PrivateIndirect";
90
91
92 /***
93 * The fully qualified class name of our test bean class.
94 */
95 private static final String TEST_BEAN_CLASS =
96 "org.apache.commons.beanutils.TestBean";
97
98
99 /***
100 * The basic test bean for each test.
101 */
102 protected TestBean bean = null;
103
104
105 /***
106 * The "package private subclass" test bean for each test.
107 */
108 protected TestBeanPackageSubclass beanPackageSubclass = null;
109
110
111 /***
112 * The test bean for private access tests.
113 */
114 protected PrivateDirect beanPrivate = null;
115
116
117 /***
118 * The test bean for private access tests of subclasses.
119 */
120 protected PrivateDirect beanPrivateSubclass = null;
121
122
123 /***
124 * The "public subclass" test bean for each test.
125 */
126 protected TestBeanPublicSubclass beanPublicSubclass = null;
127
128
129 /***
130 * The set of properties that should be described.
131 */
132 protected String describes[] =
133 { "booleanProperty",
134 "booleanSecond",
135 "doubleProperty",
136 "floatProperty",
137 "intArray",
138
139 "intProperty",
140 "listIndexed",
141 "longProperty",
142
143
144
145 "nested",
146 "nullProperty",
147
148 "shortProperty",
149 "stringArray",
150
151 "stringProperty"
152 };
153
154
155 /***
156 * The set of property names we expect to have returned when calling
157 * <code>getPropertyDescriptors()</code>. You should update this list
158 * when new properties are added to TestBean.
159 */
160 protected final static String[] properties = {
161 "booleanProperty",
162 "booleanSecond",
163 "doubleProperty",
164 "dupProperty",
165 "floatProperty",
166 "intArray",
167 "intIndexed",
168 "intProperty",
169 "listIndexed",
170 "longProperty",
171 "nested",
172 "nullProperty",
173 "readOnlyProperty",
174 "shortProperty",
175 "stringArray",
176 "stringIndexed",
177 "stringProperty",
178 "writeOnlyProperty",
179 };
180
181
182
183
184
185 /***
186 * Construct a new instance of this test case.
187 *
188 * @param name Name of the test case
189 */
190 public PropertyUtilsTestCase(String name) {
191
192 super(name);
193
194 }
195
196
197
198
199
200 /***
201 * Set up instance variables required by this test case.
202 */
203 public void setUp() {
204
205 bean = new TestBean();
206 beanPackageSubclass = new TestBeanPackageSubclass();
207 beanPrivate = PrivateBeanFactory.create();
208 beanPrivateSubclass = PrivateBeanFactory.createSubclass();
209 beanPublicSubclass = new TestBeanPublicSubclass();
210
211 }
212
213
214 /***
215 * Return the tests included in this test suite.
216 */
217 public static Test suite() {
218
219 return (new TestSuite(PropertyUtilsTestCase.class));
220
221 }
222
223
224 /***
225 * Tear down instance variables required by this test case.
226 */
227 public void tearDown() {
228
229 bean = null;
230 beanPackageSubclass = null;
231 beanPrivate = null;
232 beanPrivateSubclass = null;
233 beanPublicSubclass = null;
234
235 }
236
237
238
239
240
241
242 /***
243 * Test copyProperties() when the origin is a a <code>Map</code>.
244 */
245 public void testCopyPropertiesMap() {
246
247 Map map = new HashMap();
248 map.put("booleanProperty", Boolean.FALSE);
249 map.put("doubleProperty", new Double(333.0));
250 map.put("dupProperty", new String[] { "New 0", "New 1", "New 2" });
251 map.put("floatProperty", new Float((float) 222.0));
252 map.put("intArray", new int[] { 0, 100, 200 });
253 map.put("intProperty", new Integer(111));
254 map.put("longProperty", new Long(444));
255 map.put("shortProperty", new Short((short) 555));
256 map.put("stringProperty", "New String Property");
257
258 try {
259 PropertyUtils.copyProperties(bean, map);
260 } catch (Throwable t) {
261 fail("Threw " + t.toString());
262 }
263
264
265 assertEquals("booleanProperty", false,
266 bean.getBooleanProperty());
267 assertEquals("doubleProperty", 333.0,
268 bean.getDoubleProperty(), 0.005);
269 assertEquals("floatProperty", (float) 222.0,
270 bean.getFloatProperty(), (float) 0.005);
271 assertEquals("intProperty", 111,
272 bean.getIntProperty());
273 assertEquals("longProperty", 444,
274 bean.getLongProperty());
275 assertEquals("shortProperty", (short) 555,
276 bean.getShortProperty());
277 assertEquals("stringProperty", "New String Property",
278 bean.getStringProperty());
279
280
281 String dupProperty[] = bean.getDupProperty();
282 assertNotNull("dupProperty present", dupProperty);
283 assertEquals("dupProperty length", 3, dupProperty.length);
284 assertEquals("dupProperty[0]", "New 0", dupProperty[0]);
285 assertEquals("dupProperty[1]", "New 1", dupProperty[1]);
286 assertEquals("dupProperty[2]", "New 2", dupProperty[2]);
287 int intArray[] = bean.getIntArray();
288 assertNotNull("intArray present", intArray);
289 assertEquals("intArray length", 3, intArray.length);
290 assertEquals("intArray[0]", 0, intArray[0]);
291 assertEquals("intArray[1]", 100, intArray[1]);
292 assertEquals("intArray[2]", 200, intArray[2]);
293
294 }
295
296
297 /***
298 * Test the describe() method.
299 */
300 public void testDescribe() {
301
302 Map map = null;
303 try {
304 map = PropertyUtils.describe(bean);
305 } catch (Exception e) {
306 fail("Threw exception " + e);
307 }
308
309
310 for (int i = 0; i < describes.length; i++) {
311 assertTrue("Property '" + describes[i] + "' is present",
312 map.containsKey(describes[i]));
313 }
314 assertTrue("Property 'writeOnlyProperty' is not present",
315 !map.containsKey("writeOnlyProperty"));
316
317
318 assertEquals("Value of 'booleanProperty'",
319 Boolean.TRUE, map.get("booleanProperty"));
320 assertEquals("Value of 'doubleProperty'",
321 new Double(321.0), map.get("doubleProperty"));
322 assertEquals("Value of 'floatProperty'",
323 new Float((float) 123.0), map.get("floatProperty"));
324 assertEquals("Value of 'intProperty'",
325 new Integer(123), map.get("intProperty"));
326 assertEquals("Value of 'longProperty'",
327 new Long(321), map.get("longProperty"));
328 assertEquals("Value of 'shortProperty'",
329 new Short((short) 987), map.get("shortProperty"));
330 assertEquals("Value of 'stringProperty'",
331 "This is a string",
332 (String) map.get("stringProperty"));
333
334 }
335
336
337 /***
338 * Corner cases on getPropertyDescriptor invalid arguments.
339 */
340 public void testGetDescriptorArguments() {
341
342 try {
343 PropertyUtils.getPropertyDescriptor(null, "stringProperty");
344 fail("Should throw IllegalArgumentException 1");
345 } catch (IllegalArgumentException e) {
346
347 } catch (Throwable t) {
348 fail("Threw " + t + " instead of IllegalArgumentException 1");
349 }
350
351 try {
352 PropertyUtils.getPropertyDescriptor(bean, null);
353 fail("Should throw IllegalArgumentException 2");
354 } catch (IllegalArgumentException e) {
355
356 } catch (Throwable t) {
357 fail("Threw " + t + " instead of IllegalArgumentException 2");
358 }
359
360 }
361
362
363 /***
364 * Positive getPropertyDescriptor on property <code>booleanProperty</code>.
365 */
366 public void testGetDescriptorBoolean() {
367
368 testGetDescriptorBase("booleanProperty", "getBooleanProperty",
369 "setBooleanProperty");
370
371 }
372
373
374 /***
375 * Positive getPropertyDescriptor on property <code>doubleProperty</code>.
376 */
377 public void testGetDescriptorDouble() {
378
379 testGetDescriptorBase("doubleProperty", "getDoubleProperty",
380 "setDoubleProperty");
381
382 }
383
384
385 /***
386 * Positive getPropertyDescriptor on property <code>floatProperty</code>.
387 */
388 public void testGetDescriptorFloat() {
389
390 testGetDescriptorBase("floatProperty", "getFloatProperty",
391 "setFloatProperty");
392
393 }
394
395
396 /***
397 * Positive getPropertyDescriptor on property <code>intProperty</code>.
398 */
399 public void testGetDescriptorInt() {
400
401 testGetDescriptorBase("intProperty", "getIntProperty",
402 "setIntProperty");
403
404 }
405
406
407 /***
408 * <p>Negative tests on an invalid property with two different boolean
409 * getters (which is fine, according to the JavaBeans spec) but a
410 * String setter instead of a boolean setter.</p>
411 *
412 * <p>Although one could logically argue that this combination of method
413 * signatures should not identify a property at all, there is a sentence
414 * in Section 8.3.1 making it clear that the behavior tested for here
415 * is correct: "If we find only one of these methods, then we regard
416 * it as defining either a read-only or write-only property called
417 * <em><property-name></em>.</p>
418 */
419 public void testGetDescriptorInvalidBoolean() throws Exception {
420
421 PropertyDescriptor pd =
422 PropertyUtils.getPropertyDescriptor(bean, "invalidBoolean");
423 assertNotNull("invalidBoolean is a property", pd);
424 assertNotNull("invalidBoolean has a getter method",
425 pd.getReadMethod());
426 assertNull("invalidBoolean has no write method",
427 pd.getWriteMethod());
428 assertTrue("invalidBoolean getter method is isInvalidBoolean",
429 "isInvalidBoolean".equals(pd.getReadMethod().getName()));
430
431 }
432
433
434 /***
435 * Positive getPropertyDescriptor on property <code>longProperty</code>.
436 */
437 public void testGetDescriptorLong() {
438
439 testGetDescriptorBase("longProperty", "getLongProperty",
440 "setLongProperty");
441
442 }
443
444 /***
445 * Test getting mapped descriptor with periods in the key.
446 */
447 public void testGetDescriptorMappedPeriods() {
448
449 bean.getMappedIntProperty("xyz");
450
451 PropertyDescriptor desc;
452 Integer testIntegerValue = new Integer(1234);
453
454 bean.setMappedIntProperty("key.with.a.dot", testIntegerValue.intValue());
455 assertEquals("Can retrieve directly",
456 testIntegerValue,
457 new Integer(bean.getMappedIntProperty("key.with.a.dot")));
458 try {
459 desc = PropertyUtils.getPropertyDescriptor
460 (bean, "mappedIntProperty(key.with.a.dot)");
461 assertEquals("Check descriptor type (A)",
462 Integer.TYPE,
463 ((MappedPropertyDescriptor)desc).getMappedPropertyType());
464 } catch (Exception e) {
465 fail("Threw exception (A): " + e);
466 }
467
468 bean.setMappedObjects("nested.property", new TestBean(testIntegerValue.intValue()));
469 assertEquals("Can retrieve directly",
470 testIntegerValue,
471 new Integer(((TestBean)bean.getMappedObjects("nested.property")).getIntProperty()));
472 try {
473 desc = PropertyUtils.getPropertyDescriptor
474 (bean, "mappedObjects(nested.property).intProperty");
475 assertEquals("Check descriptor type (B)",
476 Integer.TYPE,
477 desc.getPropertyType());
478 } catch (Exception e) {
479 fail("Threw exception (B): " + e);
480 }
481 }
482
483
484 /***
485 * Positive getPropertyDescriptor on property
486 * <code>readOnlyProperty</code>.
487 */
488 public void testGetDescriptorReadOnly() {
489
490 testGetDescriptorBase("readOnlyProperty", "getReadOnlyProperty",
491 null);
492
493 }
494
495
496 /***
497 * Positive getPropertyDescriptor on property <code>booleanSecond</code>
498 * that uses an "is" method as the getter.
499 */
500 public void testGetDescriptorSecond() {
501
502 testGetDescriptorBase("booleanSecond", "isBooleanSecond",
503 "setBooleanSecond");
504
505 }
506
507
508 /***
509 * Positive getPropertyDescriptor on property <code>shortProperty</code>.
510 */
511 public void testGetDescriptorShort() {
512
513 testGetDescriptorBase("shortProperty", "getShortProperty",
514 "setShortProperty");
515
516 }
517
518
519 /***
520 * Positive getPropertyDescriptor on property <code>stringProperty</code>.
521 */
522 public void testGetDescriptorString() {
523
524 testGetDescriptorBase("stringProperty", "getStringProperty",
525 "setStringProperty");
526
527 }
528
529
530 /***
531 * Negative getPropertyDescriptor on property <code>unknown</code>.
532 */
533 public void testGetDescriptorUnknown() {
534
535 testGetDescriptorBase("unknown", null, null);
536
537 }
538
539
540 /***
541 * Positive getPropertyDescriptor on property
542 * <code>writeOnlyProperty</code>.
543 */
544 public void testGetDescriptorWriteOnly() {
545
546 testGetDescriptorBase("writeOnlyProperty", null,
547 "setWriteOnlyProperty");
548
549 }
550
551
552 /***
553 * Positive test for getPropertyDescriptors(). Each property name
554 * listed in <code>properties</code> should be returned exactly once.
555 */
556 public void testGetDescriptors() {
557
558 PropertyDescriptor pd[] =
559 PropertyUtils.getPropertyDescriptors(bean);
560 assertNotNull("Got descriptors", pd);
561 int count[] = new int[properties.length];
562 for (int i = 0; i < pd.length; i++) {
563 String name = pd[i].getName();
564 for (int j = 0; j < properties.length; j++) {
565 if (name.equals(properties[j]))
566 count[j]++;
567 }
568 }
569 for (int j = 0; j < properties.length; j++) {
570 if (count[j] < 0)
571 fail("Missing property " + properties[j]);
572 else if (count[j] > 1)
573 fail("Duplicate property " + properties[j]);
574 }
575
576 }
577
578
579 /***
580 * Corner cases on getPropertyDescriptors invalid arguments.
581 */
582 public void testGetDescriptorsArguments() {
583
584 try {
585 PropertyUtils.getPropertyDescriptors(null);
586 fail("Should throw IllegalArgumentException");
587 } catch (IllegalArgumentException e) {
588
589 } catch (Throwable t) {
590 fail("Threw " + t + " instead of IllegalArgumentException");
591 }
592
593 }
594
595
596 /***
597 * Corner cases on getIndexedProperty invalid arguments.
598 */
599 public void testGetIndexedArguments() {
600
601
602
603 try {
604 PropertyUtils.getIndexedProperty(null, "intArray", 0);
605 fail("Should throw IllegalArgumentException 1");
606 } catch (IllegalArgumentException e) {
607
608 } catch (Throwable t) {
609 fail("Threw " + t + " instead of IllegalArgumentException 1");
610 }
611
612 try {
613 PropertyUtils.getIndexedProperty(bean, null, 0);
614 fail("Should throw IllegalArgumentException 2");
615 } catch (IllegalArgumentException e) {
616
617 } catch (Throwable t) {
618 fail("Threw " + t + " instead of IllegalArgumentException 2");
619 }
620
621
622
623 try {
624 PropertyUtils.getIndexedProperty(null,
625 "intArray[0]");
626 fail("Should throw IllegalArgumentException 3");
627 } catch (IllegalArgumentException e) {
628
629 } catch (Throwable t) {
630 fail("Threw " + t + " instead of IllegalArgumentException 3");
631 }
632
633 try {
634 PropertyUtils.getIndexedProperty(bean, "[0]");
635 fail("Should throw NoSuchMethodException 4");
636 } catch (NoSuchMethodException e) {
637
638 } catch (Throwable t) {
639 fail("Threw " + t + " instead of NoSuchMethodException 4");
640 }
641
642 try {
643 PropertyUtils.getIndexedProperty(bean, "intArray");
644 fail("Should throw IllegalArgumentException 5");
645 } catch (IllegalArgumentException e) {
646
647 } catch (Throwable t) {
648 fail("Threw " + t + " instead of IllegalArgumentException 5");
649 }
650
651
652
653 try {
654 PropertyUtils.getIndexedProperty(null, "intIndexed", 0);
655 fail("Should throw IllegalArgumentException 1");
656 } catch (IllegalArgumentException e) {
657
658 } catch (Throwable t) {
659 fail("Threw " + t + " instead of IllegalArgumentException 1");
660 }
661
662 try {
663 PropertyUtils.getIndexedProperty(bean, null, 0);
664 fail("Should throw IllegalArgumentException 2");
665 } catch (IllegalArgumentException e) {
666
667 } catch (Throwable t) {
668 fail("Threw " + t + " instead of IllegalArgumentException 2");
669 }
670
671
672
673 try {
674 PropertyUtils.getIndexedProperty(null,
675 "intIndexed[0]");
676 fail("Should throw IllegalArgumentException 3");
677 } catch (IllegalArgumentException e) {
678
679 } catch (Throwable t) {
680 fail("Threw " + t + " instead of IllegalArgumentException 3");
681 }
682
683 try {
684 PropertyUtils.getIndexedProperty(bean, "[0]");
685 fail("Should throw NoSuchMethodException 4");
686 } catch (NoSuchMethodException e) {
687
688 } catch (Throwable t) {
689 fail("Threw " + t + " instead of NoSuchMethodException 4");
690 }
691
692 try {
693 PropertyUtils.getIndexedProperty(bean, "intIndexed");
694 fail("Should throw IllegalArgumentException 5");
695 } catch (IllegalArgumentException e) {
696
697 } catch (Throwable t) {
698 fail("Threw " + t + " instead of IllegalArgumentException 5");
699 }
700
701 }
702
703
704 /***
705 * Positive and negative tests on getIndexedProperty valid arguments.
706 */
707 public void testGetIndexedValues() {
708
709 Object value = null;
710
711
712
713 for (int i = 0; i < 5; i++) {
714
715 try {
716 value = PropertyUtils.getIndexedProperty
717 (bean, "dupProperty", i);
718 assertNotNull("dupProperty returned value " + i, value);
719 assertTrue("dupProperty returned String " + i,
720 value instanceof String);
721 assertEquals("dupProperty returned correct " + i,
722 "Dup " + i,
723 (String) value);
724 } catch (Throwable t) {
725 fail("dupProperty " + i + " threw " + t);
726 }
727
728 try {
729 value =
730 PropertyUtils.getIndexedProperty(bean, "intArray", i);
731 assertNotNull("intArray returned value " + i, value);
732 assertTrue("intArray returned Integer " + i,
733 value instanceof Integer);
734 assertEquals("intArray returned correct " + i, i * 10,
735 ((Integer) value).intValue());
736 } catch (Throwable t) {
737 fail("intArray " + i + " threw " + t);
738 }
739
740 try {
741 value =
742 PropertyUtils.getIndexedProperty(bean, "intIndexed", i);
743 assertNotNull("intIndexed returned value " + i, value);
744 assertTrue("intIndexed returned Integer " + i,
745 value instanceof Integer);
746 assertEquals("intIndexed returned correct " + i, i * 10,
747 ((Integer) value).intValue());
748 } catch (Throwable t) {
749 fail("intIndexed " + i + " threw " + t);
750 }
751
752 try {
753 value =
754 PropertyUtils.getIndexedProperty(bean, "listIndexed", i);
755 assertNotNull("listIndexed returned value " + i, value);
756 assertTrue("list returned String " + i,
757 value instanceof String);
758 assertEquals("listIndexed returned correct " + i,
759 "String " + i, (String) value);
760 } catch (Throwable t) {
761 fail("listIndexed " + i + " threw " + t);
762 }
763
764 try {
765 value =
766 PropertyUtils.getIndexedProperty(bean, "stringArray", i);
767 assertNotNull("stringArray returned value " + i, value);
768 assertTrue("stringArray returned String " + i,
769 value instanceof String);
770 assertEquals("stringArray returned correct " + i,
771 "String " + i, (String) value);
772 } catch (Throwable t) {
773 fail("stringArray " + i + " threw " + t);
774 }
775
776 try {
777 value =
778 PropertyUtils.getIndexedProperty(bean, "stringIndexed", i);
779 assertNotNull("stringIndexed returned value " + i, value);
780 assertTrue("stringIndexed returned String " + i,
781 value instanceof String);
782 assertEquals("stringIndexed returned correct " + i,
783 "String " + i, (String) value);
784 } catch (Throwable t) {
785 fail("stringIndexed " + i + " threw " + t);
786 }
787
788 }
789
790
791
792 for (int i = 0; i < 5; i++) {
793
794 try {
795 value = PropertyUtils.getIndexedProperty
796 (bean, "dupProperty[" + i + "]");
797 assertNotNull("dupProperty returned value " + i, value);
798 assertTrue("dupProperty returned String " + i,
799 value instanceof String);
800 assertEquals("dupProperty returned correct " + i,
801 "Dup " + i,
802 (String) value);
803 } catch (Throwable t) {
804 fail("dupProperty " + i + " threw " + t);
805 }
806
807 try {
808 value =
809 PropertyUtils.getIndexedProperty(bean,
810 "intArray[" + i + "]");
811 assertNotNull("intArray returned value " + i, value);
812 assertTrue("intArray returned Integer " + i,
813 value instanceof Integer);
814 assertEquals("intArray returned correct " + i, i * 10,
815 ((Integer) value).intValue());
816 } catch (Throwable t) {
817 fail("intArray " + i + " threw " + t);
818 }
819
820 try {
821 value =
822 PropertyUtils.getIndexedProperty(bean,
823 "intIndexed[" + i + "]");
824 assertNotNull("intIndexed returned value " + i, value);
825 assertTrue("intIndexed returned Integer " + i,
826 value instanceof Integer);
827 assertEquals("intIndexed returned correct " + i, i * 10,
828 ((Integer) value).intValue());
829 } catch (Throwable t) {
830 fail("intIndexed " + i + " threw " + t);
831 }
832
833 try {
834 value =
835 PropertyUtils.getIndexedProperty(bean,
836 "listIndexed[" + i + "]");
837 assertNotNull("listIndexed returned value " + i, value);
838 assertTrue("listIndexed returned String " + i,
839 value instanceof String);
840 assertEquals("listIndexed returned correct " + i,
841 "String " + i, (String) value);
842 } catch (Throwable t) {
843 fail("listIndexed " + i + " threw " + t);
844 }
845
846 try {
847 value =
848 PropertyUtils.getIndexedProperty(bean,
849 "stringArray[" + i + "]");
850 assertNotNull("stringArray returned value " + i, value);
851 assertTrue("stringArray returned String " + i,
852 value instanceof String);
853 assertEquals("stringArray returned correct " + i,
854 "String " + i, (String) value);
855 } catch (Throwable t) {
856 fail("stringArray " + i + " threw " + t);
857 }
858
859 try {
860 value =
861 PropertyUtils.getIndexedProperty(bean,
862 "stringIndexed[" + i + "]");
863 assertNotNull("stringIndexed returned value " + i, value);
864 assertTrue("stringIndexed returned String " + i,
865 value instanceof String);
866 assertEquals("stringIndexed returned correct " + i,
867 "String " + i, (String) value);
868 } catch (Throwable t) {
869 fail("stringIndexed " + i + " threw " + t);
870 }
871
872 }
873
874
875
876 try {
877 value =
878 PropertyUtils.getIndexedProperty(bean,
879 "dupProperty", -1);
880 fail("Should have thrown ArrayIndexOutOfBoundsException");
881 } catch (ArrayIndexOutOfBoundsException t) {
882
883 } catch (Throwable t) {
884 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
885 }
886
887 try {
888 value =
889 PropertyUtils.getIndexedProperty(bean,
890 "dupProperty", 5);
891 fail("Should have thrown ArrayIndexOutOfBoundsException");
892 } catch (ArrayIndexOutOfBoundsException t) {
893
894 } catch (Throwable t) {
895 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
896 }
897
898 try {
899 value =
900 PropertyUtils.getIndexedProperty(bean,
901 "intArray", -1);
902 fail("Should have thrown ArrayIndexOutOfBoundsException");
903 } catch (ArrayIndexOutOfBoundsException t) {
904
905 } catch (Throwable t) {
906 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
907 }
908
909 try {
910 value =
911 PropertyUtils.getIndexedProperty(bean,
912 "intArray", 5);
913 fail("Should have thrown ArrayIndexOutOfBoundsException");
914 } catch (ArrayIndexOutOfBoundsException t) {
915
916 } catch (Throwable t) {
917 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
918 }
919
920 try {
921 value =
922 PropertyUtils.getIndexedProperty(bean,
923 "intIndexed", -1);
924 fail("Should have thrown ArrayIndexOutOfBoundsException");
925 } catch (ArrayIndexOutOfBoundsException t) {
926
927 } catch (Throwable t) {
928 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
929 }
930
931 try {
932 value =
933 PropertyUtils.getIndexedProperty(bean,
934 "intIndexed", 5);
935 fail("Should have thrown ArrayIndexOutOfBoundsException");
936 } catch (ArrayIndexOutOfBoundsException t) {
937
938 } catch (Throwable t) {
939 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
940 }
941
942 try {
943 value =
944 PropertyUtils.getIndexedProperty(bean,
945 "listIndexed", -1);
946 fail("Should have thrown IndexOutOfBoundsException");
947 } catch (IndexOutOfBoundsException t) {
948
949 } catch (Throwable t) {
950 fail("Threw " + t + " instead of IndexOutOfBoundsException");
951 }
952
953 try {
954 value =
955 PropertyUtils.getIndexedProperty(bean,
956 "listIndexed", 5);
957 fail("Should have thrown IndexOutOfBoundsException");
958 } catch (IndexOutOfBoundsException t) {
959
960 } catch (Throwable t) {
961 fail("Threw " + t + " instead of IndexOutOfBoundsException");
962 }
963
964 try {
965 value =
966 PropertyUtils.getIndexedProperty(bean,
967 "stringArray", -1);
968 fail("Should have thrown ArrayIndexOutOfBoundsException");
969 } catch (ArrayIndexOutOfBoundsException t) {
970
971 } catch (Throwable t) {
972 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
973 }
974
975 try {
976 value =
977 PropertyUtils.getIndexedProperty(bean,
978 "stringArray", 5);
979 fail("Should have thrown ArrayIndexOutOfBoundsException");
980 } catch (ArrayIndexOutOfBoundsException t) {
981
982 } catch (Throwable t) {
983 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
984 }
985
986 try {
987 value =
988 PropertyUtils.getIndexedProperty(bean,
989 "stringIndexed", -1);
990 fail("Should have thrown ArrayIndexOutOfBoundsException");
991 } catch (ArrayIndexOutOfBoundsException t) {
992
993 } catch (Throwable t) {
994 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
995 }
996
997 try {
998 value =
999 PropertyUtils.getIndexedProperty(bean,
1000 "stringIndexed", 5);
1001 fail("Should have thrown ArrayIndexOutOfBoundsException");
1002 } catch (ArrayIndexOutOfBoundsException t) {
1003
1004 } catch (Throwable t) {
1005 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
1006 }
1007
1008 }
1009
1010
1011 /***
1012 * Test getting an indexed value out of a multi-dimensional array
1013 */
1014 public void testGetIndexedArray() {
1015 String[] firstArray = new String[] {"FIRST-1", "FIRST-2", "FIRST-3"};
1016 String[] secondArray = new String[] {"SECOND-1", "SECOND-2", "SECOND-3", "SECOND-4"};
1017 String[][] mainArray = {firstArray, secondArray};
1018 TestBean bean = new TestBean(mainArray);
1019 try {
1020 assertEquals("firstArray[0]", firstArray[0], PropertyUtils.getProperty(bean, "string2dArray[0][0]"));
1021 assertEquals("firstArray[1]", firstArray[1], PropertyUtils.getProperty(bean, "string2dArray[0][1]"));
1022 assertEquals("firstArray[2]", firstArray[2], PropertyUtils.getProperty(bean, "string2dArray[0][2]"));
1023 assertEquals("secondArray[0]", secondArray[0], PropertyUtils.getProperty(bean, "string2dArray[1][0]"));
1024 assertEquals("secondArray[1]", secondArray[1], PropertyUtils.getProperty(bean, "string2dArray[1][1]"));
1025 assertEquals("secondArray[2]", secondArray[2], PropertyUtils.getProperty(bean, "string2dArray[1][2]"));
1026 assertEquals("secondArray[3]", secondArray[3], PropertyUtils.getProperty(bean, "string2dArray[1][3]"));
1027 } catch (Throwable t) {
1028 fail("Threw " + t + "");
1029 }
1030 }
1031
1032 /***
1033 * Test getting an indexed value out of List of Lists
1034 */
1035 public void testGetIndexedList() {
1036 String[] firstArray = new String[] {"FIRST-1", "FIRST-2", "FIRST-3"};
1037 String[] secondArray = new String[] {"SECOND-1", "SECOND-2", "SECOND-3", "SECOND-4"};
1038 List mainList = new ArrayList();
1039 mainList.add(Arrays.asList(firstArray));
1040 mainList.add(Arrays.asList(secondArray));
1041 TestBean bean = new TestBean(mainList);
1042 try {
1043 assertEquals("firstArray[0]", firstArray[0], PropertyUtils.getProperty(bean, "listIndexed[0][0]"));
1044 assertEquals("firstArray[1]", firstArray[1], PropertyUtils.getProperty(bean, "listIndexed[0][1]"));
1045 assertEquals("firstArray[2]", firstArray[2], PropertyUtils.getProperty(bean, "listIndexed[0][2]"));
1046 assertEquals("secondArray[0]", secondArray[0], PropertyUtils.getProperty(bean, "listIndexed[1][0]"));
1047 assertEquals("secondArray[1]", secondArray[1], PropertyUtils.getProperty(bean, "listIndexed[1][1]"));
1048 assertEquals("secondArray[2]", secondArray[2], PropertyUtils.getProperty(bean, "listIndexed[1][2]"));
1049 assertEquals("secondArray[3]", secondArray[3], PropertyUtils.getProperty(bean, "listIndexed[1][3]"));
1050 } catch (Throwable t) {
1051 fail("Threw " + t + "");
1052 }
1053 }
1054
1055 /***
1056 * Test getting a value out of a mapped Map
1057 */
1058 public void testGetIndexedMap() {
1059 Map firstMap = new HashMap();
1060 firstMap.put("FIRST-KEY-1", "FIRST-VALUE-1");
1061 firstMap.put("FIRST-KEY-2", "FIRST-VALUE-2");
1062 Map secondMap = new HashMap();
1063 secondMap.put("SECOND-KEY-1", "SECOND-VALUE-1");
1064 secondMap.put("SECOND-KEY-2", "SECOND-VALUE-2");
1065
1066 List mainList = new ArrayList();
1067 mainList.add(firstMap);
1068 mainList.add(secondMap);
1069 TestBean bean = new TestBean(mainList);
1070 try {
1071 assertEquals("listIndexed[0](FIRST-KEY-1)", "FIRST-VALUE-1", PropertyUtils.getProperty(bean, "listIndexed[0](FIRST-KEY-1)"));
1072 assertEquals("listIndexed[0](FIRST-KEY-2)", "FIRST-VALUE-2", PropertyUtils.getProperty(bean, "listIndexed[0](FIRST-KEY-2)"));
1073 assertEquals("listIndexed[1](SECOND-KEY-1)", "SECOND-VALUE-1", PropertyUtils.getProperty(bean, "listIndexed[1](SECOND-KEY-1)"));
1074 assertEquals("listIndexed[1](SECOND-KEY-2)", "SECOND-VALUE-2", PropertyUtils.getProperty(bean, "listIndexed[1](SECOND-KEY-2)"));
1075 } catch (Throwable t) {
1076 fail("Threw " + t + "");
1077 }
1078 }
1079
1080 /***
1081 * Corner cases on getMappedProperty invalid arguments.
1082 */
1083 public void testGetMappedArguments() {
1084
1085
1086
1087 try {
1088 PropertyUtils.getMappedProperty(null, "mappedProperty",
1089 "First Key");
1090 fail("Should throw IllegalArgumentException 1");
1091 } catch (IllegalArgumentException e) {
1092
1093 } catch (Throwable t) {
1094 fail("Threw " + t + " instead of IllegalArgumentException 1");
1095 }
1096
1097 try {
1098 PropertyUtils.getMappedProperty(bean, null, "First Key");
1099 fail("Should throw IllegalArgumentException 2");
1100 } catch (IllegalArgumentException e) {
1101
1102 } catch (Throwable t) {
1103 fail("Threw " + t + " instead of IllegalArgumentException 2");
1104 }
1105
1106 try {
1107 PropertyUtils.getMappedProperty(bean, "mappedProperty", null);
1108 fail("Should throw IllegalArgumentException 3");
1109 } catch (IllegalArgumentException e) {
1110
1111 } catch (Throwable t) {
1112 fail("Threw " + t + " instead of IllegalArgumentException 3");
1113 }
1114
1115
1116
1117 try {
1118 PropertyUtils.getMappedProperty(null,
1119 "mappedProperty(First Key)");
1120 fail("Should throw IllegalArgumentException 4");
1121 } catch (IllegalArgumentException e) {
1122
1123 } catch (Throwable t) {
1124 fail("Threw " + t + " instead of IllegalArgumentException 4");
1125 }
1126
1127 try {
1128 PropertyUtils.getMappedProperty(bean, "(Second Key)");
1129 fail("Should throw IllegalArgumentException 5");
1130 } catch (NoSuchMethodException e) {
1131
1132 } catch (Throwable t) {
1133 fail("Threw " + t + " instead of NoSuchMethodException 5");
1134 }
1135
1136 try {
1137 PropertyUtils.getMappedProperty(bean, "mappedProperty");
1138 fail("Should throw IllegalArgumentException 6");
1139 } catch (IllegalArgumentException e) {
1140
1141 } catch (Throwable t) {
1142 fail("Threw " + t + " instead of IllegalArgumentException 6");
1143 }
1144
1145 }
1146
1147 /***
1148 * Test getting an indexed value out of a mapped array
1149 */
1150 public void testGetMappedArray() {
1151 TestBean bean = new TestBean();
1152 String[] array = new String[] {"abc", "def", "ghi"};
1153 bean.getMapProperty().put("mappedArray", array);
1154 try {
1155 assertEquals("abc", PropertyUtils.getProperty(bean, "mapProperty(mappedArray)[0]"));
1156 assertEquals("def", PropertyUtils.getProperty(bean, "mapProperty(mappedArray)[1]"));
1157 assertEquals("ghi", PropertyUtils.getProperty(bean, "mapProperty(mappedArray)[2]"));
1158 } catch (Throwable t) {
1159 fail("Threw " + t + "");
1160 }
1161 }
1162
1163 /***
1164 * Test getting an indexed value out of a mapped List
1165 */
1166 public void testGetMappedList() {
1167 TestBean bean = new TestBean();
1168 List list = new ArrayList();
1169 list.add("klm");
1170 list.add("nop");
1171 list.add("qrs");
1172 bean.getMapProperty().put("mappedList", list);
1173 try {
1174 assertEquals("klm", PropertyUtils.getProperty(bean, "mapProperty(mappedList)[0]"));
1175 assertEquals("nop", PropertyUtils.getProperty(bean, "mapProperty(mappedList)[1]"));
1176 assertEquals("qrs", PropertyUtils.getProperty(bean, "mapProperty(mappedList)[2]"));
1177 } catch (Throwable t) {
1178 fail("Threw " + t + "");
1179 }
1180 }
1181
1182 /***
1183 * Test getting a value out of a mapped Map
1184 */
1185 public void testGetMappedMap() {
1186 TestBean bean = new TestBean();
1187 Map map = new HashMap();
1188 map.put("sub-key-1", "sub-value-1");
1189 map.put("sub-key-2", "sub-value-2");
1190 map.put("sub-key-3", "sub-value-3");
1191 bean.getMapProperty().put("mappedMap", map);
1192 try {
1193 assertEquals("sub-value-1", PropertyUtils.getProperty(bean, "mapProperty(mappedMap)(sub-key-1)"));
1194 assertEquals("sub-value-2", PropertyUtils.getProperty(bean, "mapProperty(mappedMap)(sub-key-2)"));
1195 assertEquals("sub-value-3", PropertyUtils.getProperty(bean, "mapProperty(mappedMap)(sub-key-3)"));
1196 } catch (Throwable t) {
1197 fail("Threw " + t + "");
1198 }
1199 }
1200
1201 /***
1202 * Test getting mapped values with periods in the key.
1203 */
1204 public void testGetMappedPeriods() {
1205
1206 bean.setMappedProperty("key.with.a.dot", "Special Value");
1207 assertEquals("Can retrieve directly",
1208 "Special Value",
1209 bean.getMappedProperty("key.with.a.dot"));
1210 try {
1211 assertEquals("Can retrieve via getMappedProperty",
1212 "Special Value",
1213 PropertyUtils.getMappedProperty
1214 (bean, "mappedProperty", "key.with.a.dot"));
1215 } catch (Exception e) {
1216 fail("Thew exception: " + e);
1217 }
1218 try {
1219 assertEquals("Can retrieve via getNestedProperty",
1220 "Special Value",
1221 PropertyUtils.getNestedProperty
1222 (bean, "mappedProperty(key.with.a.dot)"));
1223 } catch (Exception e) {
1224 fail("Thew exception: " + e);
1225 }
1226
1227 bean.setMappedObjects("nested.property", new TestBean());
1228 assertNotNull("Can retrieve directly",
1229 bean.getMappedObjects("nested.property"));
1230 try {
1231 assertEquals("Can retrieve nested",
1232 "This is a string",
1233 PropertyUtils.getNestedProperty
1234 (bean,
1235 "mappedObjects(nested.property).stringProperty"));
1236 } catch (Exception e) {
1237 fail("Thew exception: " + e);
1238 }
1239
1240 try
1241 {
1242 assertEquals("Can't retrieved nested with mapped property",
1243 "Mapped Value",
1244 PropertyUtils.getNestedProperty(
1245 bean,"mappedNested.value(Mapped Key)"));
1246 } catch (Exception e)
1247 {
1248 fail("Thew exception: " + e);
1249 }
1250 }
1251
1252
1253 /***
1254 * Test getting mapped values with slashes in the key. This is different
1255 * from periods because slashes are not syntactically significant.
1256 */
1257 public void testGetMappedSlashes() {
1258
1259 bean.setMappedProperty("key/with/a/slash", "Special Value");
1260 assertEquals("Can retrieve directly",
1261 "Special Value",
1262 bean.getMappedProperty("key/with/a/slash"));
1263 try {
1264 assertEquals("Can retrieve via getMappedProperty",
1265 "Special Value",
1266 PropertyUtils.getMappedProperty
1267 (bean, "mappedProperty", "key/with/a/slash"));
1268 } catch (Exception e) {
1269 fail("Thew exception: " + e);
1270 }
1271 try {
1272 assertEquals("Can retrieve via getNestedProperty",
1273 "Special Value",
1274 PropertyUtils.getNestedProperty
1275 (bean, "mappedProperty(key/with/a/slash)"));
1276 } catch (Exception e) {
1277 fail("Thew exception: " + e);
1278 }
1279
1280 bean.setMappedObjects("nested/property", new TestBean());
1281 assertNotNull("Can retrieve directly",
1282 bean.getMappedObjects("nested/property"));
1283 try {
1284 assertEquals("Can retrieve nested",
1285 "This is a string",
1286 PropertyUtils.getNestedProperty
1287 (bean,
1288 "mappedObjects(nested/property).stringProperty"));
1289 } catch (Exception e) {
1290 fail("Thew exception: " + e);
1291 }
1292
1293 }
1294
1295
1296 /***
1297 * Positive and negative tests on getMappedProperty valid arguments.
1298 */
1299 public void testGetMappedValues() {
1300
1301 Object value = null;
1302
1303
1304
1305 try {
1306 value = PropertyUtils.getMappedProperty(bean, "mappedProperty",
1307 "First Key");
1308 assertEquals("Can find first value", "First Value", value);
1309 } catch (Throwable t) {
1310 fail("Finding first value threw " + t);
1311 }
1312
1313 try {
1314 value = PropertyUtils.getMappedProperty(bean, "mappedProperty",
1315 "Second Key");
1316 assertEquals("Can find second value", "Second Value", value);
1317 } catch (Throwable t) {
1318 fail("Finding second value threw " + t);
1319 }
1320
1321 try {
1322 value = PropertyUtils.getMappedProperty(bean, "mappedProperty",
1323 "Third Key");
1324 assertNull("Can not find third value", value);
1325 } catch (Throwable t) {
1326 fail("Finding third value threw " + t);
1327 }
1328
1329
1330
1331 try {
1332 value =
1333 PropertyUtils.getMappedProperty(bean,
1334 "mappedProperty(First Key)");
1335 assertEquals("Can find first value", "First Value", value);
1336 } catch (Throwable t) {
1337 fail("Finding first value threw " + t);
1338 }
1339
1340 try {
1341 value =
1342 PropertyUtils.getMappedProperty(bean,
1343 "mappedProperty(Second Key)");
1344 assertEquals("Can find second value", "Second Value", value);
1345 } catch (Throwable t) {
1346 fail("Finding second value threw " + t);
1347 }
1348
1349 try {
1350 value =
1351 PropertyUtils.getMappedProperty(bean,
1352 "mappedProperty(Third Key)");
1353 assertNull("Can not find third value", value);
1354 } catch (Throwable t) {
1355 fail("Finding third value threw " + t);
1356 }
1357
1358
1359
1360 try {
1361 value =
1362 PropertyUtils.getNestedProperty(bean,
1363 "mapProperty.First Key");
1364 assertEquals("Can find first value", "First Value", value);
1365 } catch (Throwable t) {
1366 fail("Finding first value threw " + t);
1367 }
1368
1369 try {
1370 value =
1371 PropertyUtils.getNestedProperty(bean,
1372 "mapProperty.Second Key");
1373 assertEquals("Can find second value", "Second Value", value);
1374 } catch (Throwable t) {
1375 fail("Finding second value threw " + t);
1376 }
1377
1378 try {
1379 value =
1380 PropertyUtils.getNestedProperty(bean,
1381 "mapProperty.Third Key");
1382 assertNull("Can not find third value", value);
1383 } catch (Throwable t) {
1384 fail("Finding third value threw " + t);
1385 }
1386
1387 }
1388
1389
1390 /***
1391 * Corner cases on getNestedProperty invalid arguments.
1392 */
1393 public void testGetNestedArguments() {
1394
1395 try {
1396 PropertyUtils.getNestedProperty(null, "stringProperty");
1397 fail("Should throw IllegalArgumentException 1");
1398 } catch (IllegalArgumentException e) {
1399
1400 } catch (Throwable t) {
1401 fail("Threw " + t + " instead of IllegalArgumentException 1");
1402 }
1403
1404 try {
1405 PropertyUtils.getNestedProperty(bean, null);
1406 fail("Should throw IllegalArgumentException 2");
1407 } catch (IllegalArgumentException e) {
1408
1409 } catch (Throwable t) {
1410 fail("Threw " + t + " instead of IllegalArgumentException 2");
1411 }
1412
1413 }
1414
1415
1416 /***
1417 * Test getNestedProperty on a boolean property.
1418 */
1419 public void testGetNestedBoolean() {
1420
1421 try {
1422 Object value =
1423 PropertyUtils.getNestedProperty
1424 (bean, "nested.booleanProperty");
1425 assertNotNull("Got a value", value);
1426 assertTrue("Got correct type", (value instanceof Boolean));
1427 assertTrue("Got correct value",
1428 ((Boolean) value).booleanValue() ==
1429 bean.getNested().getBooleanProperty());
1430 } catch (IllegalAccessException e) {
1431 fail("IllegalAccessException");
1432 } catch (IllegalArgumentException e) {
1433 fail("IllegalArgumentException");
1434 } catch (InvocationTargetException e) {
1435 fail("InvocationTargetException");
1436 } catch (NoSuchMethodException e) {
1437 fail("NoSuchMethodException");
1438 }
1439
1440 }
1441
1442
1443 /***
1444 * Test getNestedProperty on a double property.
1445 */
1446 public void testGetNestedDouble() {
1447
1448 try {
1449 Object value =
1450 PropertyUtils.getNestedProperty
1451 (bean, "nested.doubleProperty");
1452 assertNotNull("Got a value", value);
1453 assertTrue("Got correct type", (value instanceof Double));
1454 assertEquals("Got correct value",
1455 ((Double) value).doubleValue(),
1456 bean.getNested().getDoubleProperty(),
1457 0.005);
1458 } catch (IllegalAccessException e) {
1459 fail("IllegalAccessException");
1460 } catch (IllegalArgumentException e) {
1461 fail("IllegalArgumentException");
1462 } catch (InvocationTargetException e) {
1463 fail("InvocationTargetException");
1464 } catch (NoSuchMethodException e) {
1465 fail("NoSuchMethodException");
1466 }
1467
1468 }
1469
1470
1471 /***
1472 * Test getNestedProperty on a float property.
1473 */
1474 public void testGetNestedFloat() {
1475
1476 try {
1477 Object value =
1478 PropertyUtils.getNestedProperty
1479 (bean, "nested.floatProperty");
1480 assertNotNull("Got a value", value);
1481 assertTrue("Got correct type", (value instanceof Float));
1482 assertEquals("Got correct value",
1483 ((Float) value).floatValue(),
1484 bean.getNested().getFloatProperty(),
1485 (float) 0.005);
1486 } catch (IllegalAccessException e) {
1487 fail("IllegalAccessException");
1488 } catch (IllegalArgumentException e) {
1489 fail("IllegalArgumentException");
1490 } catch (InvocationTargetException e) {
1491 fail("InvocationTargetException");
1492 } catch (NoSuchMethodException e) {
1493 fail("NoSuchMethodException");
1494 }
1495
1496 }
1497
1498
1499 /***
1500 * Test getNestedProperty on an int property.
1501 */
1502 public void testGetNestedInt() {
1503
1504 try {
1505 Object value =
1506 PropertyUtils.getNestedProperty
1507 (bean, "nested.intProperty");
1508 assertNotNull("Got a value", value);
1509 assertTrue("Got correct type", (value instanceof Integer));
1510 assertEquals("Got correct value",
1511 ((Integer) value).intValue(),
1512 bean.getNested().getIntProperty());
1513 } catch (IllegalAccessException e) {
1514 fail("IllegalAccessException");
1515 } catch (IllegalArgumentException e) {
1516 fail("IllegalArgumentException");
1517 } catch (InvocationTargetException e) {
1518 fail("InvocationTargetException");
1519 } catch (NoSuchMethodException e) {
1520 fail("NoSuchMethodException");
1521 }
1522
1523 }
1524
1525
1526 /***
1527 * Test getNestedProperty on a long property.
1528 */
1529 public void testGetNestedLong() {
1530
1531 try {
1532 Object value =
1533 PropertyUtils.getNestedProperty
1534 (bean, "nested.longProperty");
1535 assertNotNull("Got a value", value);
1536 assertTrue("Got correct type", (value instanceof Long));
1537 assertEquals("Got correct value",
1538 ((Long) value).longValue(),
1539 bean.getNested().getLongProperty());
1540 } catch (IllegalAccessException e) {
1541 fail("IllegalAccessException");
1542 } catch (IllegalArgumentException e) {
1543 fail("IllegalArgumentException");
1544 } catch (InvocationTargetException e) {
1545 fail("InvocationTargetException");
1546 } catch (NoSuchMethodException e) {
1547 fail("NoSuchMethodException");
1548 }
1549
1550 }
1551
1552
1553 /***
1554 * Test getNestedProperty on a read-only String property.
1555 */
1556 public void testGetNestedReadOnly() {
1557
1558 try {
1559 Object value =
1560 PropertyUtils.getNestedProperty
1561 (bean, "nested.readOnlyProperty");
1562 assertNotNull("Got a value", value);
1563 assertTrue("Got correct type", (value instanceof String));
1564 assertEquals("Got correct value",
1565 (String) value,
1566 bean.getReadOnlyProperty());
1567 } catch (IllegalAccessException e) {
1568 fail("IllegalAccessException");
1569 } catch (IllegalArgumentException e) {
1570 fail("IllegalArgumentException");
1571 } catch (InvocationTargetException e) {
1572 fail("InvocationTargetException");
1573 } catch (NoSuchMethodException e) {
1574 fail("NoSuchMethodException");
1575 }
1576
1577 }
1578
1579
1580 /***
1581 * Test getNestedProperty on a short property.
1582 */
1583 public void testGetNestedShort() {
1584
1585 try {
1586 Object value =
1587 PropertyUtils.getNestedProperty
1588 (bean, "nested.shortProperty");
1589 assertNotNull("Got a value", value);
1590 assertTrue("Got correct type", (value instanceof Short));
1591 assertEquals("Got correct value",
1592 ((Short) value).shortValue(),
1593 bean.getNested().getShortProperty());
1594 } catch (IllegalAccessException e) {
1595 fail("IllegalAccessException");
1596 } catch (IllegalArgumentException e) {
1597 fail("IllegalArgumentException");
1598 } catch (InvocationTargetException e) {
1599 fail("InvocationTargetException");
1600 } catch (NoSuchMethodException e) {
1601 fail("NoSuchMethodException");
1602 }
1603
1604 }
1605
1606
1607 /***
1608 * Test getNestedProperty on a String property.
1609 */
1610 public void testGetNestedString() {
1611
1612 try {
1613 Object value =
1614 PropertyUtils.getNestedProperty
1615 (bean, "nested.stringProperty");
1616 assertNotNull("Got a value", value);
1617 assertTrue("Got correct type", (value instanceof String));
1618 assertEquals("Got correct value",
1619 ((String) value),
1620 bean.getNested().getStringProperty());
1621 } catch (IllegalAccessException e) {
1622 fail("IllegalAccessException");
1623 } catch (IllegalArgumentException e) {
1624 fail("IllegalArgumentException");
1625 } catch (InvocationTargetException e) {
1626 fail("InvocationTargetException");
1627 } catch (NoSuchMethodException e) {
1628 fail("NoSuchMethodException");
1629 }
1630
1631 }
1632
1633
1634 /***
1635 * Negative test getNestedProperty on an unknown property.
1636 */
1637 public void testGetNestedUnknown() {
1638
1639 try {
1640 PropertyUtils.getNestedProperty(bean, "nested.unknown");
1641 fail("Should have thrown NoSuchMethodException");
1642 } catch (IllegalAccessException e) {
1643 fail("IllegalAccessException");
1644 } catch (IllegalArgumentException e) {
1645 fail("IllegalArgumentException");
1646 } catch (InvocationTargetException e) {
1647 fail("InvocationTargetException");
1648 } catch (NoSuchMethodException e) {
1649
1650 }
1651
1652 }
1653
1654 /***
1655 * When a bean has a null property which is reference by the standard access language,
1656 * this should throw a NestedNullException.
1657 */
1658 public void testThrowNestedNull() throws Exception {
1659 NestedTestBean nestedBean = new NestedTestBean("base");
1660
1661
1662 try {
1663 NestedTestBean value = (NestedTestBean) PropertyUtils.getProperty(
1664 nestedBean,
1665 "simpleBeanProperty.indexedProperty[0]");
1666 fail("NestedNullException not thrown");
1667 } catch (NestedNullException e) {
1668
1669 }
1670 }
1671
1672 /***
1673 * Test getNestedProperty on a write-only String property.
1674 */
1675 public void testGetNestedWriteOnly() {
1676
1677 try {
1678 PropertyUtils.getNestedProperty(bean, "writeOnlyProperty");
1679 fail("Should have thrown NoSuchMethodException");
1680 } catch (IllegalAccessException e) {
1681 fail("IllegalAccessException");
1682 } catch (IllegalArgumentException e) {
1683 fail("IllegalArgumentException");
1684 } catch (InvocationTargetException e) {
1685 fail("InvocationTargetException");
1686 } catch (NoSuchMethodException e) {
1687
1688 }
1689
1690 }
1691
1692
1693 /***
1694 * Test getPropertyType() on all kinds of properties.
1695 */
1696 public void testGetPropertyType() {
1697
1698 Class clazz = null;
1699 int intArray[] = new int[0];
1700 String stringArray[] = new String[0];
1701
1702 try {
1703
1704
1705 clazz = PropertyUtils.getPropertyType(bean, "booleanProperty");
1706 assertEquals("booleanProperty type", Boolean.TYPE, clazz);
1707 clazz = PropertyUtils.getPropertyType(bean, "booleanSecond");
1708 assertEquals("booleanSecond type", Boolean.TYPE, clazz);
1709 clazz = PropertyUtils.getPropertyType(bean, "doubleProperty");
1710 assertEquals("doubleProperty type", Double.TYPE, clazz);
1711 clazz = PropertyUtils.getPropertyType(bean, "dupProperty");
1712 assertEquals("dupProperty type", String.class, clazz);
1713 clazz = PropertyUtils.getPropertyType(bean, "floatProperty");
1714 assertEquals("floatProperty type", Float.TYPE, clazz);
1715 clazz = PropertyUtils.getPropertyType(bean, "intArray");
1716 assertEquals("intArray type", intArray.getClass(), clazz);
1717 clazz = PropertyUtils.getPropertyType(bean, "intIndexed");
1718 assertEquals("intIndexed type", Integer.TYPE, clazz);
1719 clazz = PropertyUtils.getPropertyType(bean, "intProperty");
1720 assertEquals("intProperty type", Integer.TYPE, clazz);
1721 clazz = PropertyUtils.getPropertyType(bean, "listIndexed");
1722 assertEquals("listIndexed type", List.class, clazz);
1723 clazz = PropertyUtils.getPropertyType(bean, "longProperty");
1724 assertEquals("longProperty type", Long.TYPE, clazz);
1725 clazz = PropertyUtils.getPropertyType(bean, "mappedProperty");
1726 assertEquals("mappedProperty type", String.class, clazz);
1727 clazz = PropertyUtils.getPropertyType(bean, "mappedIntProperty");
1728 assertEquals("mappedIntProperty type", Integer.TYPE, clazz);
1729 clazz = PropertyUtils.getPropertyType(bean, "readOnlyProperty");
1730 assertEquals("readOnlyProperty type", String.class, clazz);
1731 clazz = PropertyUtils.getPropertyType(bean, "shortProperty");
1732 assertEquals("shortProperty type", Short.TYPE, clazz);
1733 clazz = PropertyUtils.getPropertyType(bean, "stringArray");
1734 assertEquals("stringArray type", stringArray.getClass(), clazz);
1735 clazz = PropertyUtils.getPropertyType(bean, "stringIndexed");
1736 assertEquals("stringIndexed type", String.class, clazz);
1737 clazz = PropertyUtils.getPropertyType(bean, "stringProperty");
1738 assertEquals("stringProperty type", String.class, clazz);
1739 clazz = PropertyUtils.getPropertyType(bean, "writeOnlyProperty");
1740 assertEquals("writeOnlyProperty type", String.class, clazz);
1741
1742
1743 clazz = PropertyUtils.getPropertyType(bean, "nested.booleanProperty");
1744 assertEquals("booleanProperty type", Boolean.TYPE, clazz);
1745 clazz = PropertyUtils.getPropertyType(bean, "nested.booleanSecond");
1746 assertEquals("booleanSecond type", Boolean.TYPE, clazz);
1747 clazz = PropertyUtils.getPropertyType(bean, "nested.doubleProperty");
1748 assertEquals("doubleProperty type", Double.TYPE, clazz);
1749 clazz = PropertyUtils.getPropertyType(bean, "nested.dupProperty");
1750 assertEquals("dupProperty type", String.class, clazz);
1751 clazz = PropertyUtils.getPropertyType(bean, "nested.floatProperty");
1752 assertEquals("floatProperty type", Float.TYPE, clazz);
1753 clazz = PropertyUtils.getPropertyType(bean, "nested.intArray");
1754 assertEquals("intArray type", intArray.getClass(), clazz);
1755 clazz = PropertyUtils.getPropertyType(bean, "nested.intIndexed");
1756 assertEquals("intIndexed type", Integer.TYPE, clazz);
1757 clazz = PropertyUtils.getPropertyType(bean, "nested.intProperty");
1758 assertEquals("intProperty type", Integer.TYPE, clazz);
1759 clazz = PropertyUtils.getPropertyType(bean, "nested.listIndexed");
1760 assertEquals("listIndexed type", List.class, clazz);
1761 clazz = PropertyUtils.getPropertyType(bean, "nested.longProperty");
1762 assertEquals("longProperty type", Long.TYPE, clazz);
1763 clazz = PropertyUtils.getPropertyType(bean, "nested.mappedProperty");
1764 assertEquals("mappedProperty type", String.class, clazz);
1765 clazz = PropertyUtils.getPropertyType(bean, "nested.mappedIntProperty");
1766 assertEquals("mappedIntProperty type", Integer.TYPE, clazz);
1767 clazz = PropertyUtils.getPropertyType(bean, "nested.readOnlyProperty");
1768 assertEquals("readOnlyProperty type", String.class, clazz);
1769 clazz = PropertyUtils.getPropertyType(bean, "nested.shortProperty");
1770 assertEquals("shortProperty type", Short.TYPE, clazz);
1771 clazz = PropertyUtils.getPropertyType(bean, "nested.stringArray");
1772 assertEquals("stringArray type", stringArray.getClass(), clazz);
1773 clazz = PropertyUtils.getPropertyType(bean, "nested.stringIndexed");
1774 assertEquals("stringIndexed type", String.class, clazz);
1775 clazz = PropertyUtils.getPropertyType(bean, "nested.stringProperty");
1776 assertEquals("stringProperty type", String.class, clazz);
1777 clazz = PropertyUtils.getPropertyType(bean, "nested.writeOnlyProperty");
1778 assertEquals("writeOnlyProperty type", String.class, clazz);
1779
1780 } catch (Exception e) {
1781 fail("Exception: " + e.getMessage());
1782 }
1783
1784 }
1785
1786
1787 /***
1788 * Test getting accessible property reader methods for a specified
1789 * list of properties of our standard test bean.
1790 */
1791 public void testGetReadMethodBasic() {
1792
1793 testGetReadMethod(bean, properties, TEST_BEAN_CLASS);
1794
1795 }
1796
1797
1798 /***
1799 * Test getting accessible property reader methods for a specified
1800 * list of properties of a package private subclass of our standard
1801 * test bean.
1802 */
1803 public void testGetReadMethodPackageSubclass() {
1804
1805 testGetReadMethod(beanPackageSubclass, properties, TEST_BEAN_CLASS);
1806
1807 }
1808
1809
1810 /***
1811 * Test getting accessible property reader methods for a specified
1812 * list of properties that are declared either directly or via
1813 * implemented interfaces.
1814 */
1815 public void testGetReadMethodPublicInterface() {
1816
1817
1818
1819 testGetReadMethod(beanPrivate,
1820 new String[]{ "bar" },
1821 PRIVATE_DIRECT_CLASS);
1822 testGetReadMethod(beanPrivate,
1823 new String[]{ "baz" },
1824 PRIVATE_INDIRECT_CLASS);
1825
1826
1827
1828
1829 testGetReadMethod(beanPrivateSubclass,
1830 new String[]{ "bar" },
1831 PRIVATE_DIRECT_CLASS);
1832 testGetReadMethod(beanPrivateSubclass,
1833 new String[]{ "baz" },
1834 PRIVATE_INDIRECT_CLASS);
1835
1836
1837
1838 PropertyDescriptor pd[] =
1839 PropertyUtils.getPropertyDescriptors(beanPrivate);
1840 int n = -1;
1841 for (int i = 0; i < pd.length; i++) {
1842 if ("foo".equals(pd[i].getName())) {
1843 n = i;
1844 break;
1845 }
1846 }
1847 assertTrue("Found foo descriptor", n >= 0);
1848 Method reader = pd[n].getReadMethod();
1849 assertNotNull("Found foo read method", reader);
1850 Object value = null;
1851 try {
1852 value = reader.invoke(beanPrivate, new Class[0]);
1853 fail("Foo reader did throw IllegalAccessException");
1854 } catch (IllegalAccessException e) {
1855
1856 } catch (Throwable t) {
1857 fail("Invoke foo reader: " + t);
1858 }
1859
1860 }
1861
1862
1863 /***
1864 * Test getting accessible property reader methods for a specified
1865 * list of properties of a public subclass of our standard test bean.
1866 */
1867 public void testGetReadMethodPublicSubclass() {
1868
1869 testGetReadMethod(beanPublicSubclass, properties, TEST_BEAN_CLASS);
1870
1871 }
1872
1873
1874 /***
1875 * Corner cases on getSimpleProperty invalid arguments.
1876 */
1877 public void testGetSimpleArguments() {
1878
1879 try {
1880 PropertyUtils.getSimpleProperty(null, "stringProperty");
1881 fail("Should throw IllegalArgumentException 1");
1882 } catch (IllegalArgumentException e) {
1883
1884 } catch (Throwable t) {
1885 fail("Threw " + t + " instead of IllegalArgumentException 1");
1886 }
1887
1888 try {
1889 PropertyUtils.getSimpleProperty(bean, null);
1890 fail("Should throw IllegalArgumentException 2");
1891 } catch (IllegalArgumentException e) {
1892
1893 } catch (Throwable t) {
1894 fail("Threw " + t + " instead of IllegalArgumentException 2");
1895 }
1896
1897 }
1898
1899
1900 /***
1901 * Test getSimpleProperty on a boolean property.
1902 */
1903 public void testGetSimpleBoolean() {
1904
1905 try {
1906 Object value =
1907 PropertyUtils.getSimpleProperty(bean,
1908 "booleanProperty");
1909 assertNotNull("Got a value", value);
1910 assertTrue("Got correct type", (value instanceof Boolean));
1911 assertTrue("Got correct value",
1912 ((Boolean) value).booleanValue() ==
1913 bean.getBooleanProperty());
1914 } catch (IllegalAccessException e) {
1915 fail("IllegalAccessException");
1916 } catch (IllegalArgumentException e) {
1917 fail("IllegalArgumentException");
1918 } catch (InvocationTargetException e) {
1919 fail("InvocationTargetException");
1920 } catch (NoSuchMethodException e) {
1921 fail("NoSuchMethodException");
1922 }
1923
1924 }
1925
1926
1927 /***
1928 * Test getSimpleProperty on a double property.
1929 */
1930 public void testGetSimpleDouble() {
1931
1932 try {
1933 Object value =
1934 PropertyUtils.getSimpleProperty(bean,
1935 "doubleProperty");
1936 assertNotNull("Got a value", value);
1937 assertTrue("Got correct type", (value instanceof Double));
1938 assertEquals("Got correct value",
1939 ((Double) value).doubleValue(),
1940 bean.getDoubleProperty(), 0.005);
1941 } catch (IllegalAccessException e) {
1942 fail("IllegalAccessException");
1943 } catch (IllegalArgumentException e) {
1944 fail("IllegalArgumentException");
1945 } catch (InvocationTargetException e) {
1946 fail("InvocationTargetException");
1947 } catch (NoSuchMethodException e) {
1948 fail("NoSuchMethodException");
1949 }
1950
1951 }
1952
1953
1954 /***
1955 * Test getSimpleProperty on a float property.
1956 */
1957 public void testGetSimpleFloat() {
1958
1959 try {
1960 Object value =
1961 PropertyUtils.getSimpleProperty(bean,
1962 "floatProperty");
1963 assertNotNull("Got a value", value);
1964 assertTrue("Got correct type", (value instanceof Float));
1965 assertEquals("Got correct value",
1966 ((Float) value).floatValue(),
1967 bean.getFloatProperty(),
1968 (float) 0.005);
1969 } catch (IllegalAccessException e) {
1970 fail("IllegalAccessException");
1971 } catch (IllegalArgumentException e) {
1972 fail("IllegalArgumentException");
1973 } catch (InvocationTargetException e) {
1974 fail("InvocationTargetException");
1975 } catch (NoSuchMethodException e) {
1976 fail("NoSuchMethodException");
1977 }
1978
1979 }
1980
1981
1982 /***
1983 * Negative test getSimpleProperty on an indexed property.
1984 */
1985 public void testGetSimpleIndexed() {
1986
1987 Object value = null;
1988 try {
1989 value = PropertyUtils.getSimpleProperty(bean,
1990 "intIndexed[0]");
1991 fail("Should have thrown IllegalArgumentException");
1992 } catch (IllegalAccessException e) {
1993 fail("IllegalAccessException");
1994 } catch (IllegalArgumentException e) {
1995
1996 } catch (InvocationTargetException e) {
1997 fail("InvocationTargetException");
1998 } catch (NoSuchMethodException e) {
1999 fail("NoSuchMethodException");
2000 }
2001
2002 }
2003
2004
2005 /***
2006 * Test getSimpleProperty on an int property.
2007 */
2008 public void testGetSimpleInt() {
2009
2010 try {
2011 Object value =
2012 PropertyUtils.getSimpleProperty(bean,
2013 "intProperty");
2014 assertNotNull("Got a value", value);
2015 assertTrue("Got correct type", (value instanceof Integer));
2016 assertEquals("Got correct value",
2017 ((Integer) value).intValue(),
2018 bean.getIntProperty());
2019 } catch (IllegalAccessException e) {
2020 fail("IllegalAccessException");
2021 } catch (IllegalArgumentException e) {
2022 fail("IllegalArgumentException");
2023 } catch (InvocationTargetException e) {
2024 fail("InvocationTargetException");
2025 } catch (NoSuchMethodException e) {
2026 fail("NoSuchMethodException");
2027 }
2028
2029 }
2030
2031
2032 /***
2033 * Test getSimpleProperty on a long property.
2034 */
2035 public void testGetSimpleLong() {
2036
2037 try {
2038 Object value =
2039 PropertyUtils.getSimpleProperty(bean,
2040 "longProperty");
2041 assertNotNull("Got a value", value);
2042 assertTrue("Got correct type", (value instanceof Long));
2043 assertEquals("Got correct value",
2044 ((Long) value).longValue(),
2045 bean.getLongProperty());
2046 } catch (IllegalAccessException e) {
2047 fail("IllegalAccessException");
2048 } catch (IllegalArgumentException e) {
2049 fail("IllegalArgumentException");
2050 } catch (InvocationTargetException e) {
2051 fail("InvocationTargetException");
2052 } catch (NoSuchMethodException e) {
2053 fail("NoSuchMethodException");
2054 }
2055
2056 }
2057
2058
2059 /***
2060 * Negative test getSimpleProperty on a nested property.
2061 */
2062 public void testGetSimpleNested() {
2063
2064 Object value = null;
2065 try {
2066 value = PropertyUtils.getSimpleProperty(bean,
2067 "nested.stringProperty");
2068 fail("Should have thrown IllegaArgumentException");
2069 } catch (IllegalAccessException e) {
2070 fail("IllegalAccessException");
2071 } catch (IllegalArgumentException e) {
2072
2073 } catch (InvocationTargetException e) {
2074 fail("InvocationTargetException");
2075 } catch (NoSuchMethodException e) {
2076 fail("NoSuchMethodException");
2077 }
2078
2079 }
2080
2081
2082 /***
2083 * Test getSimpleProperty on a read-only String property.
2084 */
2085 public void testGetSimpleReadOnly() {
2086
2087 try {
2088 Object value =
2089 PropertyUtils.getSimpleProperty(bean,
2090 "readOnlyProperty");
2091 assertNotNull("Got a value", value);
2092 assertTrue("Got correct type", (value instanceof String));
2093 assertEquals("Got correct value",
2094 (String) value,
2095 bean.getReadOnlyProperty());
2096 } catch (IllegalAccessException e) {
2097 fail("IllegalAccessException");
2098 } catch (IllegalArgumentException e) {
2099 fail("IllegalArgumentException");
2100 } catch (InvocationTargetException e) {
2101 fail("InvocationTargetException");
2102 } catch (NoSuchMethodException e) {
2103 fail("NoSuchMethodException");
2104 }
2105
2106 }
2107
2108
2109 /***
2110 * Test getSimpleProperty on a short property.
2111 */
2112 public void testGetSimpleShort() {
2113
2114 try {
2115 Object value =
2116 PropertyUtils.getSimpleProperty(bean,
2117 "shortProperty");
2118 assertNotNull("Got a value", value);
2119 assertTrue("Got correct type", (value instanceof Short));
2120 assertEquals("Got correct value",
2121 ((Short) value).shortValue(),
2122 bean.getShortProperty());
2123 } catch (IllegalAccessException e) {
2124 fail("IllegalAccessException");
2125 } catch (IllegalArgumentException e) {
2126 fail("IllegalArgumentException");
2127 } catch (InvocationTargetException e) {
2128 fail("InvocationTargetException");
2129 } catch (NoSuchMethodException e) {
2130 fail("NoSuchMethodException");
2131 }
2132
2133 }
2134
2135
2136 /***
2137 * Test getSimpleProperty on a String property.
2138 */
2139 public void testGetSimpleString() {
2140
2141 try {
2142 Object value =
2143 PropertyUtils.getSimpleProperty(bean,
2144 "stringProperty");
2145 assertNotNull("Got a value", value);
2146 assertTrue("Got correct type", (value instanceof String));
2147 assertEquals("Got correct value",
2148 (String) value,
2149 bean.getStringProperty());
2150 } catch (IllegalAccessException e) {
2151 fail("IllegalAccessException");
2152 } catch (IllegalArgumentException e) {
2153 fail("IllegalArgumentException");
2154 } catch (InvocationTargetException e) {
2155 fail("InvocationTargetException");
2156 } catch (NoSuchMethodException e) {
2157 fail("NoSuchMethodException");
2158 }
2159
2160 }
2161
2162
2163 /***
2164 * Negative test getSimpleProperty on an unknown property.
2165 */
2166 public void testGetSimpleUnknown() {
2167
2168 try {
2169 PropertyUtils.getSimpleProperty(bean, "unknown");
2170 fail("Should have thrown NoSuchMethodException");
2171 } catch (IllegalAccessException e) {
2172 fail("IllegalAccessException");
2173 } catch (IllegalArgumentException e) {
2174 fail("IllegalArgumentException");
2175 } catch (InvocationTargetException e) {
2176 fail("InvocationTargetException");
2177 } catch (NoSuchMethodException e) {
2178
2179 assertEquals("Unknown property 'unknown' on class '" +
2180 bean.getClass() + "'", e.getMessage() );
2181 }
2182
2183 }
2184
2185
2186 /***
2187 * Test getSimpleProperty on a write-only String property.
2188 */
2189 public void testGetSimpleWriteOnly() {
2190
2191 try {
2192 PropertyUtils.getSimpleProperty(bean, "writeOnlyProperty");
2193 fail("Should have thrown NoSuchMethodException");
2194 } catch (IllegalAccessException e) {
2195 fail("IllegalAccessException");
2196 } catch (IllegalArgumentException e) {
2197 fail("IllegalArgumentException");
2198 } catch (InvocationTargetException e) {
2199 fail("InvocationTargetException");
2200 } catch (NoSuchMethodException e) {
2201
2202 assertEquals("Property 'writeOnlyProperty' has no getter method in class '" +
2203 bean.getClass() + "'", e.getMessage() );
2204 }
2205
2206 }
2207
2208
2209 /***
2210 * Test getting accessible property writer methods for a specified
2211 * list of properties of our standard test bean.
2212 */
2213 public void testGetWriteMethodBasic() {
2214
2215 testGetWriteMethod(bean, properties, TEST_BEAN_CLASS);
2216
2217 }
2218
2219
2220 /***
2221 * Test getting accessible property writer methods for a specified
2222 * list of properties of a package private subclass of our standard
2223 * test bean.
2224 */
2225 public void testGetWriteMethodPackageSubclass() {
2226
2227 testGetWriteMethod(beanPackageSubclass, properties, TEST_BEAN_CLASS);
2228
2229 }
2230
2231
2232 /***
2233 * Test getting accessible property writer methods for a specified
2234 * list of properties of a public subclass of our standard test bean.
2235 */
2236 public void testGetWriteMethodPublicSubclass() {
2237
2238 testGetWriteMethod(beanPublicSubclass, properties, TEST_BEAN_CLASS);
2239
2240 }
2241
2242 /***
2243 * Test isReadable() method.
2244 */
2245 public void testIsReadable() {
2246 TestBean bean = new TestBean();
2247 String property = null;
2248 try {
2249 property = "stringProperty";
2250 assertTrue("Property " + property +" isReadable expeced TRUE", PropertyUtils.isReadable(bean, property));
2251 } catch (Throwable t) {
2252 fail("Property " + property +" isReadable Threw exception: " + t);
2253 }
2254 try {
2255 property = "stringIndexed";
2256 assertTrue("Property " + property +" isReadable expeced TRUE", PropertyUtils.isReadable(bean, property));
2257 } catch (Throwable t) {
2258 fail("Property " + property +" isReadable Threw exception: " + t);
2259 }
2260 try {
2261 property = "mappedProperty";
2262 assertTrue("Property " + property +" isReadable expeced TRUE", PropertyUtils.isReadable(bean, property));
2263 } catch (Throwable t) {
2264 fail("Property " + property +" isReadable Threw exception: " + t);
2265 }
2266
2267 }
2268
2269 /***
2270 * Test isWriteable() method.
2271 */
2272 public void testIsWriteable() {
2273 TestBean bean = new TestBean();
2274 String property = null;
2275 try {
2276 property = "stringProperty";
2277 assertTrue("Property " + property +" isWriteable expeced TRUE", PropertyUtils.isWriteable(bean, property));
2278 } catch (Throwable t) {
2279 fail("Property " + property +" isWriteable Threw exception: " + t);
2280 }
2281 try {
2282 property = "stringIndexed";
2283 assertTrue("Property " + property +" isWriteable expeced TRUE", PropertyUtils.isWriteable(bean, property));
2284 } catch (Throwable t) {
2285 fail("Property " + property +" isWriteable Threw exception: " + t);
2286 }
2287 try {
2288 property = "mappedProperty";
2289 assertTrue("Property " + property +" isWriteable expeced TRUE", PropertyUtils.isWriteable(bean, property));
2290 } catch (Throwable t) {
2291 fail("Property " + property +" isWriteable Threw exception: " + t);
2292 }
2293
2294 }
2295
2296
2297 /***
2298 * Test the mappedPropertyType of MappedPropertyDescriptor.
2299 */
2300 public void testMappedPropertyType() throws Exception {
2301
2302 MappedPropertyDescriptor desc;
2303
2304
2305 desc = (MappedPropertyDescriptor)
2306 PropertyUtils.getPropertyDescriptor(bean,
2307 "mappedProperty");
2308 assertEquals(String.class, desc.getMappedPropertyType());
2309
2310
2311 desc = (MappedPropertyDescriptor)
2312 PropertyUtils.getPropertyDescriptor(bean,
2313 "mappedIntProperty");
2314 assertEquals(Integer.TYPE, desc.getMappedPropertyType());
2315
2316 }
2317
2318
2319 /***
2320 * Corner cases on setIndexedProperty invalid arguments.
2321 */
2322 public void testSetIndexedArguments() {
2323
2324
2325
2326 try {
2327 PropertyUtils.setIndexedProperty(null, "intArray", 0,
2328 new Integer(1));
2329 fail("Should throw IllegalArgumentException 1");
2330 } catch (IllegalArgumentException e) {
2331
2332 } catch (Throwable t) {
2333 fail("Threw " + t + " instead of IllegalArgumentException 1");
2334 }
2335
2336 try {
2337 PropertyUtils.setIndexedProperty(bean, null, 0,
2338 new Integer(1));
2339 fail("Should throw IllegalArgumentException 2");
2340 } catch (IllegalArgumentException e) {
2341
2342 } catch (Throwable t) {
2343 fail("Threw " + t + " instead of IllegalArgumentException 2");
2344 }
2345
2346
2347
2348 try {
2349 PropertyUtils.setIndexedProperty(null,
2350 "intArray[0]",
2351 new Integer(1));
2352 fail("Should throw IllegalArgumentException 3");
2353 } catch (IllegalArgumentException e) {
2354
2355 } catch (Throwable t) {
2356 fail("Threw " + t + " instead of IllegalArgumentException 3");
2357 }
2358
2359 try {
2360 PropertyUtils.setIndexedProperty(bean, "[0]",
2361 new Integer(1));
2362 fail("Should throw NoSuchMethodException 4");
2363 } catch (NoSuchMethodException e) {
2364
2365 } catch (Throwable t) {
2366 fail("Threw " + t + " instead of NoSuchMethodException 4");
2367 }
2368
2369 try {
2370 PropertyUtils.setIndexedProperty(bean, "intArray",
2371 new Integer(1));
2372 fail("Should throw IllegalArgumentException 5");
2373 } catch (IllegalArgumentException e) {
2374
2375 } catch (Throwable t) {
2376 fail("Threw " + t + " instead of IllegalArgumentException 5");
2377 }
2378
2379
2380
2381 try {
2382 PropertyUtils.setIndexedProperty(null, "intIndexed", 0,
2383 new Integer(1));
2384 fail("Should throw IllegalArgumentException 1");
2385 } catch (IllegalArgumentException e) {
2386
2387 } catch (Throwable t) {
2388 fail("Threw " + t + " instead of IllegalArgumentException 1");
2389 }
2390
2391 try {
2392 PropertyUtils.setIndexedProperty(bean, null, 0,
2393 new Integer(1));
2394 fail("Should throw IllegalArgumentException 2");
2395 } catch (IllegalArgumentException e) {
2396
2397 } catch (Throwable t) {
2398 fail("Threw " + t + " instead of IllegalArgumentException 2");
2399 }
2400
2401
2402
2403 try {
2404 PropertyUtils.setIndexedProperty(null,
2405 "intIndexed[0]",
2406 new Integer(1));
2407 fail("Should throw IllegalArgumentException 3");
2408 } catch (IllegalArgumentException e) {
2409
2410 } catch (Throwable t) {
2411 fail("Threw " + t + " instead of IllegalArgumentException 3");
2412 }
2413
2414 try {
2415 PropertyUtils.setIndexedProperty(bean, "[0]",
2416 new Integer(1));
2417 fail("Should throw NoSuchMethodException 4");
2418 } catch (NoSuchMethodException e) {
2419
2420 } catch (Throwable t) {
2421 fail("Threw " + t + " instead of NoSuchMethodException 4");
2422 }
2423
2424 try {
2425 PropertyUtils.setIndexedProperty(bean, "intIndexed",
2426 new Integer(1));
2427 fail("Should throw IllegalArgumentException 5");
2428 } catch (IllegalArgumentException e) {
2429
2430 } catch (Throwable t) {
2431 fail("Threw " + t + " instead of IllegalArgumentException 5");
2432 }
2433
2434 }
2435
2436 /***
2437 * Test setting an indexed value out of a multi-dimensional array
2438 */
2439 public void testSetIndexedArray() {
2440 String[] firstArray = new String[] {"FIRST-1", "FIRST-2", "FIRST-3"};
2441 String[] secondArray = new String[] {"SECOND-1", "SECOND-2", "SECOND-3", "SECOND-4"};
2442 String[][] mainArray = {firstArray, secondArray};
2443 TestBean bean = new TestBean(mainArray);
2444 assertEquals("BEFORE", "SECOND-3", bean.getString2dArray(1)[2]);
2445 try {
2446 PropertyUtils.setProperty(bean, "string2dArray[1][2]", "SECOND-3-UPDATED");
2447 } catch (Throwable t) {
2448 fail("Threw " + t + "");
2449 }
2450 assertEquals("AFTER", "SECOND-3-UPDATED", bean.getString2dArray(1)[2]);
2451 }
2452
2453 /***
2454 * Test setting an indexed value out of List of Lists
2455 */
2456 public void testSetIndexedList() {
2457 String[] firstArray = new String[] {"FIRST-1", "FIRST-2", "FIRST-3"};
2458 String[] secondArray = new String[] {"SECOND-1", "SECOND-2", "SECOND-3", "SECOND-4"};
2459 List mainList = new ArrayList();
2460 mainList.add(Arrays.asList(firstArray));
2461 mainList.add(Arrays.asList(secondArray));
2462 TestBean bean = new TestBean(mainList);
2463 assertEquals("BEFORE", "SECOND-4", ((List)bean.getListIndexed().get(1)).get(3));
2464 try {
2465 PropertyUtils.setProperty(bean, "listIndexed[1][3]", "SECOND-4-UPDATED");
2466 } catch (Throwable t) {
2467 fail("Threw " + t + "");
2468 }
2469 assertEquals("AFTER", "SECOND-4-UPDATED", ((List)bean.getListIndexed().get(1)).get(3));
2470 }
2471
2472 /***
2473 * Test setting a value out of a mapped Map
2474 */
2475 public void testSetIndexedMap() {
2476 Map firstMap = new HashMap();
2477 firstMap.put("FIRST-KEY-1", "FIRST-VALUE-1");
2478 firstMap.put("FIRST-KEY-2", "FIRST-VALUE-2");
2479 Map secondMap = new HashMap();
2480 secondMap.put("SECOND-KEY-1", "SECOND-VALUE-1");
2481 secondMap.put("SECOND-KEY-2", "SECOND-VALUE-2");
2482
2483 List mainList = new ArrayList();
2484 mainList.add(firstMap);
2485 mainList.add(secondMap);
2486 TestBean bean = new TestBean(mainList);
2487
2488 assertEquals("BEFORE", null, ((Map)bean.getListIndexed().get(0)).get("FIRST-NEW-KEY"));
2489 assertEquals("BEFORE", "SECOND-VALUE-1", ((Map)bean.getListIndexed().get(1)).get("SECOND-KEY-1"));
2490 try {
2491 PropertyUtils.setProperty(bean, "listIndexed[0](FIRST-NEW-KEY)", "FIRST-NEW-VALUE");
2492 PropertyUtils.setProperty(bean, "listIndexed[1](SECOND-KEY-1)", "SECOND-VALUE-1-UPDATED");
2493 } catch (Throwable t) {
2494 fail("Threw " + t + "");
2495 }
2496 assertEquals("BEFORE", "FIRST-NEW-VALUE", ((Map)bean.getListIndexed().get(0)).get("FIRST-NEW-KEY"));
2497 assertEquals("AFTER", "SECOND-VALUE-1-UPDATED", ((Map)bean.getListIndexed().get(1)).get("SECOND-KEY-1"));
2498 }
2499
2500
2501 /***
2502 * Positive and negative tests on setIndexedProperty valid arguments.
2503 */
2504 public void testSetIndexedValues() {
2505
2506 Object value = null;
2507
2508
2509
2510 try {
2511 PropertyUtils.setIndexedProperty(bean,
2512 "dupProperty", 0,
2513 "New 0");
2514 value =
2515 PropertyUtils.getIndexedProperty(bean,
2516 "dupProperty", 0);
2517 assertNotNull("Returned new value 0", value);
2518 assertTrue("Returned String new value 0",
2519 value instanceof String);
2520 assertEquals("Returned correct new value 0", "New 0",
2521 (String) value);
2522 } catch (Throwable t) {
2523 fail("Threw " + t);
2524 }
2525
2526 try {
2527 PropertyUtils.setIndexedProperty(bean,
2528 "intArray", 0,
2529 new Integer(1));
2530 value =
2531 PropertyUtils.getIndexedProperty(bean,
2532 "intArray", 0);
2533 assertNotNull("Returned new value 0", value);
2534 assertTrue("Returned Integer new value 0",
2535 value instanceof Integer);
2536 assertEquals("Returned correct new value 0", 1,
2537 ((Integer) value).intValue());
2538 } catch (Throwable t) {
2539 fail("Threw " + t);
2540 }
2541
2542 try {
2543 PropertyUtils.setIndexedProperty(bean,
2544 "intIndexed", 1,
2545 new Integer(11));
2546 value =
2547 PropertyUtils.getIndexedProperty(bean,
2548 "intIndexed", 1);
2549 assertNotNull("Returned new value 1", value);
2550 assertTrue("Returned Integer new value 1",
2551 value instanceof Integer);
2552 assertEquals("Returned correct new value 1", 11,
2553 ((Integer) value).intValue());
2554 } catch (Throwable t) {
2555 fail("Threw " + t);
2556 }
2557
2558 try {
2559 PropertyUtils.setIndexedProperty(bean,
2560 "listIndexed", 2,
2561 "New Value 2");
2562 value =
2563 PropertyUtils.getIndexedProperty(bean,
2564 "listIndexed", 2);
2565 assertNotNull("Returned new value 2", value);
2566 assertTrue("Returned String new value 2",
2567 value instanceof String);
2568 assertEquals("Returned correct new value 2", "New Value 2",
2569 (String) value);
2570 } catch (Throwable t) {
2571 fail("Threw " + t);
2572 }
2573
2574 try {
2575 PropertyUtils.setIndexedProperty(bean,
2576 "stringArray", 2,
2577 "New Value 2");
2578 value =
2579 PropertyUtils.getIndexedProperty(bean,
2580 "stringArray", 2);
2581 assertNotNull("Returned new value 2", value);
2582 assertTrue("Returned String new value 2",
2583 value instanceof String);
2584 assertEquals("Returned correct new value 2", "New Value 2",
2585 (String) value);
2586 } catch (Throwable t) {
2587 fail("Threw " + t);
2588 }
2589
2590 try {
2591 PropertyUtils.setIndexedProperty(bean,
2592 "stringArray", 3,
2593 "New Value 3");
2594 value =
2595 PropertyUtils.getIndexedProperty(bean,
2596 "stringArray", 3);
2597 assertNotNull("Returned new value 3", value);
2598 assertTrue("Returned String new value 3",
2599 value instanceof String);
2600 assertEquals("Returned correct new value 3", "New Value 3",
2601 (String) value);
2602 } catch (Throwable t) {
2603 fail("Threw " + t);
2604 }
2605
2606
2607
2608 try {
2609 PropertyUtils.setIndexedProperty(bean,
2610 "dupProperty[4]",
2611 "New 4");
2612 value =
2613 PropertyUtils.getIndexedProperty(bean,
2614 "dupProperty[4]");
2615 assertNotNull("Returned new value 4", value);
2616 assertTrue("Returned String new value 4",
2617 value instanceof String);
2618 assertEquals("Returned correct new value 4", "New 4",
2619 (String) value);
2620 } catch (Throwable t) {
2621 fail("Threw " + t);
2622 }
2623
2624 try {
2625 PropertyUtils.setIndexedProperty(bean,
2626 "intArray[4]",
2627 new Integer(1));
2628 value =
2629 PropertyUtils.getIndexedProperty(bean,
2630 "intArray[4]");
2631 assertNotNull("Returned new value 4", value);
2632 assertTrue("Returned Integer new value 4",
2633 value instanceof Integer);
2634 assertEquals("Returned correct new value 4", 1,
2635 ((Integer) value).intValue());
2636 } catch (Throwable t) {
2637 fail("Threw " + t);
2638 }
2639
2640 try {
2641 PropertyUtils.setIndexedProperty(bean,
2642 "intIndexed[3]",
2643 new Integer(11));
2644 value =
2645 PropertyUtils.getIndexedProperty(bean,
2646 "intIndexed[3]");
2647 assertNotNull("Returned new value 5", value);
2648 assertTrue("Returned Integer new value 5",
2649 value instanceof Integer);
2650 assertEquals("Returned correct new value 5", 11,
2651 ((Integer) value).intValue());
2652 } catch (Throwable t) {
2653 fail("Threw " + t);
2654 }
2655
2656 try {
2657 PropertyUtils.setIndexedProperty(bean,
2658 "listIndexed[1]",
2659 "New Value 2");
2660 value =
2661 PropertyUtils.getIndexedProperty(bean,
2662 "listIndexed[1]");
2663 assertNotNull("Returned new value 6", value);
2664 assertTrue("Returned String new value 6",
2665 value instanceof String);
2666 assertEquals("Returned correct new value 6", "New Value 2",
2667 (String) value);
2668 } catch (Throwable t) {
2669 fail("Threw " + t);
2670 }
2671
2672 try {
2673 PropertyUtils.setIndexedProperty(bean,
2674 "stringArray[1]",
2675 "New Value 2");
2676 value =
2677 PropertyUtils.getIndexedProperty(bean,
2678 "stringArray[2]");
2679 assertNotNull("Returned new value 6", value);
2680 assertTrue("Returned String new value 6",
2681 value instanceof String);
2682 assertEquals("Returned correct new value 6", "New Value 2",
2683 (String) value);
2684 } catch (Throwable t) {
2685 fail("Threw " + t);
2686 }
2687
2688 try {
2689 PropertyUtils.setIndexedProperty(bean,
2690 "stringArray[0]",
2691 "New Value 3");
2692 value =
2693 PropertyUtils.getIndexedProperty(bean,
2694 "stringArray[0]");
2695 assertNotNull("Returned new value 7", value);
2696 assertTrue("Returned String new value 7",
2697 value instanceof String);
2698 assertEquals("Returned correct new value 7", "New Value 3",
2699 (String) value);
2700 } catch (Throwable t) {
2701 fail("Threw " + t);
2702 }
2703
2704
2705
2706 try {
2707 PropertyUtils.setIndexedProperty(bean,
2708 "dupProperty", -1,
2709 "New -1");
2710 fail("Should have thrown ArrayIndexOutOfBoundsException");
2711 } catch (ArrayIndexOutOfBoundsException t) {
2712
2713 } catch (Throwable t) {
2714 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
2715 }
2716
2717 try {
2718 PropertyUtils.setIndexedProperty(bean,
2719 "dupProperty", 5,
2720 "New 5");
2721 fail("Should have thrown ArrayIndexOutOfBoundsException");
2722 } catch (ArrayIndexOutOfBoundsException t) {
2723
2724 } catch (Throwable t) {
2725 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
2726 }
2727
2728 try {
2729 PropertyUtils.setIndexedProperty(bean,
2730 "intArray", -1,
2731 new Integer(0));
2732 fail("Should have thrown ArrayIndexOutOfBoundsException");
2733 } catch (ArrayIndexOutOfBoundsException t) {
2734
2735 } catch (Throwable t) {
2736 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
2737 }
2738
2739 try {
2740 PropertyUtils.setIndexedProperty(bean,
2741 "intArray", 5,
2742 new Integer(0));
2743 fail("Should have thrown ArrayIndexOutOfBoundsException");
2744 } catch (ArrayIndexOutOfBoundsException t) {
2745
2746 } catch (Throwable t) {
2747 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
2748 }
2749
2750 try {
2751 PropertyUtils.setIndexedProperty(bean,
2752 "intIndexed", -1,
2753 new Integer(0));
2754 fail("Should have thrown ArrayIndexOutOfBoundsException");
2755 } catch (ArrayIndexOutOfBoundsException t) {
2756
2757 } catch (Throwable t) {
2758 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
2759 }
2760
2761 try {
2762 PropertyUtils.setIndexedProperty(bean,
2763 "intIndexed", 5,
2764 new Integer(0));
2765 fail("Should have thrown ArrayIndexOutOfBoundsException");
2766 } catch (ArrayIndexOutOfBoundsException t) {
2767
2768 } catch (Throwable t) {
2769 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
2770 }
2771
2772 try {
2773 PropertyUtils.setIndexedProperty(bean,
2774 "listIndexed", 5,
2775 "New String");
2776 fail("Should have thrown IndexOutOfBoundsException");
2777 } catch (IndexOutOfBoundsException t) {
2778
2779 } catch (Throwable t) {
2780 fail("Threw " + t + " instead of IndexOutOfBoundsException");
2781 }
2782
2783 try {
2784 PropertyUtils.setIndexedProperty(bean,
2785 "listIndexed", -1,
2786 "New String");
2787 fail("Should have thrown IndexOutOfBoundsException");
2788 } catch (IndexOutOfBoundsException t) {
2789
2790 } catch (Throwable t) {
2791 fail("Threw " + t + " instead of IndexOutOfBoundsException");
2792 }
2793
2794 try {
2795 PropertyUtils.setIndexedProperty(bean,
2796 "stringArray", -1,
2797 "New String");
2798 fail("Should have thrown ArrayIndexOutOfBoundsException");
2799 } catch (ArrayIndexOutOfBoundsException t) {
2800
2801 } catch (Throwable t) {
2802 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
2803 }
2804
2805 try {
2806 PropertyUtils.setIndexedProperty(bean,
2807 "stringArray", 5,
2808 "New String");
2809 fail("Should have thrown ArrayIndexOutOfBoundsException");
2810 } catch (ArrayIndexOutOfBoundsException t) {
2811
2812 } catch (Throwable t) {
2813 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
2814 }
2815
2816 try {
2817 PropertyUtils.setIndexedProperty(bean,
2818 "stringIndexed", -1,
2819 "New String");
2820 fail("Should have thrown ArrayIndexOutOfBoundsException");
2821 } catch (ArrayIndexOutOfBoundsException t) {
2822
2823 } catch (Throwable t) {
2824 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
2825 }
2826
2827 try {
2828 PropertyUtils.setIndexedProperty(bean,
2829 "stringIndexed", 5,
2830 "New String");
2831 fail("Should have thrown ArrayIndexOutOfBoundsException");
2832 } catch (ArrayIndexOutOfBoundsException t) {
2833
2834 } catch (Throwable t) {
2835 fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException");
2836 }
2837
2838 }
2839
2840
2841 /***
2842 * Corner cases on getMappedProperty invalid arguments.
2843 */
2844 public void testSetMappedArguments() {
2845
2846
2847
2848 try {
2849 PropertyUtils.setMappedProperty(null, "mappedProperty",
2850 "First Key", "First Value");
2851 fail("Should throw IllegalArgumentException 1");
2852 } catch (IllegalArgumentException e) {
2853
2854 } catch (Throwable t) {
2855 fail("Threw " + t + " instead of IllegalArgumentException 1");
2856 }
2857
2858 try {
2859 PropertyUtils.setMappedProperty(bean, null, "First Key",
2860 "First Value");
2861 fail("Should throw IllegalArgumentException 2");
2862 } catch (IllegalArgumentException e) {
2863
2864 } catch (Throwable t) {
2865 fail("Threw " + t + " instead of IllegalArgumentException 2");
2866 }
2867
2868 try {
2869 PropertyUtils.setMappedProperty(bean, "mappedProperty", null,
2870 "First Value");
2871 fail("Should throw IllegalArgumentException 3");
2872 } catch (IllegalArgumentException e) {
2873
2874 } catch (Throwable t) {
2875 fail("Threw " + t + " instead of IllegalArgumentException 3");
2876 }
2877
2878
2879
2880 try {
2881 PropertyUtils.setMappedProperty(null,
2882 "mappedProperty(First Key)",
2883 "First Value");
2884 fail("Should throw IllegalArgumentException 4");
2885 } catch (IllegalArgumentException e) {
2886
2887 } catch (Throwable t) {
2888 fail("Threw " + t + " instead of IllegalArgumentException 4");
2889 }
2890
2891 try {
2892 PropertyUtils.setMappedProperty(bean, "(Second Key)",
2893 "Second Value");
2894 fail("Should throw IllegalArgumentException 5");
2895 } catch (NoSuchMethodException e) {
2896
2897 } catch (Throwable t) {
2898 fail("Threw " + t + " instead of NoSuchMethodException 5");
2899 }
2900
2901 try {
2902 PropertyUtils.setMappedProperty(bean, "mappedProperty",
2903 "Third Value");
2904 fail("Should throw IllegalArgumentException 6");
2905 } catch (IllegalArgumentException e) {
2906
2907 } catch (Throwable t) {
2908 fail("Threw " + t + " instead of IllegalArgumentException 6");
2909 }
2910
2911 }
2912
2913
2914 /***
2915 * Test setting an indexed value out of a mapped array
2916 */
2917 public void testSetMappedArray() {
2918 TestBean bean = new TestBean();
2919 String[] array = new String[] {"abc", "def", "ghi"};
2920 bean.getMapProperty().put("mappedArray", array);
2921
2922 assertEquals("BEFORE", "def", ((String[])bean.getMapProperty().get("mappedArray"))[1]);
2923 try {
2924 PropertyUtils.setProperty(bean, "mapProperty(mappedArray)[1]", "DEF-UPDATED");
2925 } catch (Throwable t) {
2926 fail("Threw " + t + "");
2927 }
2928 assertEquals("AFTER", "DEF-UPDATED", ((String[])bean.getMapProperty().get("mappedArray"))[1]);
2929 }
2930
2931 /***
2932 * Test setting an indexed value out of a mapped List
2933 */
2934 public void testSetMappedList() {
2935 TestBean bean = new TestBean();
2936 List list = new ArrayList();
2937 list.add("klm");
2938 list.add("nop");
2939 list.add("qrs");
2940 bean.getMapProperty().put("mappedList", list);
2941
2942 assertEquals("BEFORE", "klm", ((List)bean.getMapProperty().get("mappedList")).get(0));
2943 try {
2944 PropertyUtils.setProperty(bean, "mapProperty(mappedList)[0]", "KLM-UPDATED");
2945 } catch (Throwable t) {
2946 fail("Threw " + t + "");
2947 }
2948 assertEquals("AFTER", "KLM-UPDATED", ((List)bean.getMapProperty().get("mappedList")).get(0));
2949 }
2950
2951 /***
2952 * Test setting a value out of a mapped Map
2953 */
2954 public void testSetMappedMap() {
2955 TestBean bean = new TestBean();
2956 Map map = new HashMap();
2957 map.put("sub-key-1", "sub-value-1");
2958 map.put("sub-key-2", "sub-value-2");
2959 map.put("sub-key-3", "sub-value-3");
2960 bean.getMapProperty().put("mappedMap", map);
2961
2962 assertEquals("BEFORE", "sub-value-3", ((Map)bean.getMapProperty().get("mappedMap")).get("sub-key-3"));
2963 try {
2964 PropertyUtils.setProperty(bean, "mapProperty(mappedMap)(sub-key-3)", "SUB-KEY-3-UPDATED");
2965 } catch (Throwable t) {
2966 fail("Threw " + t + "");
2967 }
2968 assertEquals("AFTER", "SUB-KEY-3-UPDATED", ((Map)bean.getMapProperty().get("mappedMap")).get("sub-key-3"));
2969 }
2970
2971 /***
2972 * Positive and negative tests on setMappedProperty valid arguments.
2973 */
2974 public void testSetMappedValues() {
2975
2976 Object value = null;
2977
2978
2979
2980 try {
2981 value = PropertyUtils.getMappedProperty(bean, "mappedProperty",
2982 "Fourth Key");
2983 assertNull("Can not find fourth value", value);
2984 } catch (Throwable t) {
2985 fail("Finding fourth value threw " + t);
2986 }
2987
2988 try {
2989 PropertyUtils.setMappedProperty(bean, "mappedProperty",
2990 "Fourth Key", "Fourth Value");
2991 } catch (Throwable t) {
2992 fail("Setting fourth value threw " + t);
2993 }
2994
2995 try {
2996 value = PropertyUtils.getMappedProperty(bean, "mappedProperty",
2997 "Fourth Key");
2998 assertEquals("Can find fourth value", "Fourth Value", value);
2999 } catch (Throwable t) {
3000 fail("Finding fourth value threw " + t);
3001 }
3002
3003
3004
3005 try {
3006 value =
3007 PropertyUtils.getMappedProperty(bean,
3008 "mappedProperty(Fifth Key)");
3009 assertNull("Can not find fifth value", value);
3010 } catch (Throwable t) {
3011 fail("Finding fifth value threw " + t);
3012 }
3013
3014 try {
3015 PropertyUtils.setMappedProperty(bean,
3016 "mappedProperty(Fifth Key)",
3017 "Fifth Value");
3018 } catch (Throwable t) {
3019 fail("Setting fifth value threw " + t);
3020 }
3021
3022 try {
3023 value =
3024 PropertyUtils.getMappedProperty(bean,
3025 "mappedProperty(Fifth Key)");
3026 assertEquals("Can find fifth value", "Fifth Value", value);
3027 } catch (Throwable t) {
3028 fail("Finding fifth value threw " + t);
3029 }
3030
3031
3032
3033 try {
3034 value =
3035 PropertyUtils.getNestedProperty(bean,
3036 "mapProperty.Sixth Key");
3037 assertNull("Can not find sixth value", value);
3038 } catch (Throwable t) {
3039 fail("Finding fifth value threw " + t);
3040 }
3041
3042 try {
3043 PropertyUtils.setNestedProperty(bean,
3044 "mapProperty.Sixth Key",
3045 "Sixth Value");
3046 } catch (Throwable t) {
3047 fail("Setting sixth value threw " + t);
3048 }
3049
3050 try {
3051 value =
3052 PropertyUtils.getNestedProperty(bean,
3053 "mapProperty.Sixth Key");
3054 assertEquals("Can find sixth value", "Sixth Value", value);
3055 } catch (Throwable t) {
3056 fail("Finding sixth value threw " + t);
3057 }
3058
3059 }
3060
3061 /***
3062 * Test setting mapped values with periods in the key.
3063 */
3064 public void testSetMappedPeriods() {
3065
3066
3067
3068 bean.setMappedProperty("key.with.a.dot", "Special Value");
3069 assertEquals("Can retrieve directly (A)",
3070 "Special Value",
3071 bean.getMappedProperty("key.with.a.dot"));
3072
3073 try {
3074 PropertyUtils.setMappedProperty(bean, "mappedProperty", "key.with.a.dot", "Updated Special Value");
3075 assertEquals("Check set via setMappedProperty",
3076 "Updated Special Value",
3077 bean.getMappedProperty("key.with.a.dot"));
3078 } catch (Exception e) {
3079 fail("Thew exception: " + e);
3080 }
3081
3082
3083 bean.setMappedProperty("key.with.a.dot", "Special Value");
3084 assertEquals("Can retrieve directly (B)",
3085 "Special Value",
3086 bean.getMappedProperty("key.with.a.dot"));
3087 try {
3088 PropertyUtils.setNestedProperty(bean, "mappedProperty(key.with.a.dot)", "Updated Special Value");
3089 assertEquals("Check set via setNestedProperty (B)",
3090 "Updated Special Value",
3091 bean.getMappedProperty("key.with.a.dot"));
3092 } catch (Exception e) {
3093 fail("Thew exception: " + e);
3094 }
3095
3096
3097
3098 TestBean testBean = new TestBean();
3099 bean.setMappedObjects("nested.property", testBean);
3100 assertEquals("Can retrieve directly (C)",
3101 "This is a string",
3102 testBean.getStringProperty());
3103 try {
3104 PropertyUtils.setNestedProperty(bean, "mappedObjects(nested.property).stringProperty",
3105 "Updated String Value");
3106 assertEquals("Check set via setNestedProperty (C)",
3107 "Updated String Value",
3108 testBean.getStringProperty());
3109 } catch (Exception e) {
3110 fail("Thew exception: " + e);
3111 }
3112
3113
3114 bean.getNested().setMappedProperty("Mapped Key", "Nested Mapped Value");
3115 try {
3116 assertEquals("Can retrieve via getNestedProperty (D)",
3117 "Nested Mapped Value",
3118 PropertyUtils.getNestedProperty(
3119 bean,"nested.mappedProperty(Mapped Key)"));
3120 PropertyUtils.setNestedProperty(bean, "nested.mappedProperty(Mapped Key)",
3121 "Updated Nested Mapped Value");
3122 assertEquals("Check set via setNestedProperty (D)",
3123 "Updated Nested Mapped Value",
3124 PropertyUtils.getNestedProperty(
3125 bean,"nested.mappedProperty(Mapped Key)"));
3126 } catch (Exception e) {
3127 fail("Thew exception: " + e);
3128 }
3129 }
3130
3131
3132 /***
3133 * Corner cases on setNestedProperty invalid arguments.
3134 */
3135 public void testSetNestedArguments() {
3136
3137 try {
3138 PropertyUtils.setNestedProperty(null, "stringProperty", "");
3139 fail("Should throw IllegalArgumentException 1");
3140 } catch (IllegalArgumentException e) {
3141
3142 } catch (Throwable t) {
3143 fail("Threw " + t + " instead of IllegalArgumentException 1");
3144 }
3145
3146 try {
3147 PropertyUtils.setNestedProperty(bean, null, "");
3148 fail("Should throw IllegalArgumentException 2");
3149 } catch (IllegalArgumentException e) {
3150
3151 } catch (Throwable t) {
3152 fail("Threw " + t + " instead of IllegalArgumentException 2");
3153 }
3154
3155 }
3156
3157
3158 /***
3159 * Test setNextedProperty on a boolean property.
3160 */
3161 public void testSetNestedBoolean() {
3162
3163 try {
3164 boolean oldValue = bean.getNested().getBooleanProperty();
3165 boolean newValue = !oldValue;
3166 PropertyUtils.setNestedProperty(bean,
3167 "nested.booleanProperty",
3168 new Boolean(newValue));
3169 assertTrue("Matched new value",
3170 newValue ==
3171 bean.getNested().getBooleanProperty());
3172 } catch (IllegalAccessException e) {
3173 fail("IllegalAccessException");
3174 } catch (IllegalArgumentException e) {
3175 fail("IllegalArgumentException");
3176 } catch (InvocationTargetException e) {
3177 fail("InvocationTargetException");
3178 } catch (NoSuchMethodException e) {
3179 fail("NoSuchMethodException");
3180 }
3181
3182 }
3183
3184
3185 /***
3186 * Test setNestedProperty on a double property.
3187 */
3188 public void testSetNestedDouble() {
3189
3190 try {
3191 double oldValue = bean.getNested().getDoubleProperty();
3192 double newValue = oldValue + 1.0;
3193 PropertyUtils.setNestedProperty(bean,
3194 "nested.doubleProperty",
3195 new Double(newValue));
3196 assertEquals("Matched new value",
3197 newValue,
3198 bean.getNested().getDoubleProperty(),
3199 0.005);
3200 } catch (IllegalAccessException e) {
3201 fail("IllegalAccessException");
3202 } catch (IllegalArgumentException e) {
3203 fail("IllegalArgumentException");
3204 } catch (InvocationTargetException e) {
3205 fail("InvocationTargetException");
3206 } catch (NoSuchMethodException e) {
3207 fail("NoSuchMethodException");
3208 }
3209
3210 }
3211
3212
3213 /***
3214 * Test setNestedProperty on a float property.
3215 */
3216 public void testSetNestedFloat() {
3217
3218 try {
3219 float oldValue = bean.getNested().getFloatProperty();
3220 float newValue = oldValue + (float) 1.0;
3221 PropertyUtils.setNestedProperty(bean,
3222 "nested.floatProperty",
3223 new Float(newValue));
3224 assertEquals("Matched new value",
3225 newValue,
3226 bean.getNested().getFloatProperty(),
3227 (float) 0.005);
3228 } catch (IllegalAccessException e) {
3229 fail("IllegalAccessException");
3230 } catch (IllegalArgumentException e) {
3231 fail("IllegalArgumentException");
3232 } catch (InvocationTargetException e) {
3233 fail("InvocationTargetException");
3234 } catch (NoSuchMethodException e) {
3235 fail("NoSuchMethodException");
3236 }
3237
3238 }
3239
3240
3241 /***
3242 * Test setNestedProperty on a int property.
3243 */
3244 public void testSetNestedInt() {
3245
3246 try {
3247 int oldValue = bean.getNested().getIntProperty();
3248 int newValue = oldValue + 1;
3249 PropertyUtils.setNestedProperty(bean,
3250 "nested.intProperty",
3251 new Integer(newValue));
3252 assertEquals("Matched new value",
3253 newValue,
3254 bean.getNested().getIntProperty());
3255 } catch (IllegalAccessException e) {
3256 fail("IllegalAccessException");
3257 } catch (IllegalArgumentException e) {
3258 fail("IllegalArgumentException");
3259 } catch (InvocationTargetException e) {
3260 fail("InvocationTargetException");
3261 } catch (NoSuchMethodException e) {
3262 fail("NoSuchMethodException");
3263 }
3264
3265 }
3266
3267
3268 /***
3269 * Test setNestedProperty on a long property.
3270 */
3271 public void testSetNestedLong() {
3272
3273 try {
3274 long oldValue = bean.getNested().getLongProperty();
3275 long newValue = oldValue + 1;
3276 PropertyUtils.setNestedProperty(bean,
3277 "nested.longProperty",
3278 new Long(newValue));
3279 assertEquals("Matched new value",
3280 newValue,
3281 bean.getNested().getLongProperty());
3282 } catch (IllegalAccessException e) {
3283 fail("IllegalAccessException");
3284 } catch (IllegalArgumentException e) {
3285 fail("IllegalArgumentException");
3286 } catch (InvocationTargetException e) {
3287 fail("InvocationTargetException");
3288 } catch (NoSuchMethodException e) {
3289 fail("NoSuchMethodException");
3290 }
3291
3292 }
3293
3294
3295 /***
3296 * Test setNestedProperty on a read-only String property.
3297 */
3298 public void testSetNestedReadOnly() {
3299
3300 try {
3301 String oldValue = bean.getNested().getWriteOnlyPropertyValue();
3302 String newValue = oldValue + " Extra Value";
3303 PropertyUtils.setNestedProperty(bean,
3304 "nested.readOnlyProperty",
3305 newValue);
3306 fail("Should have thrown NoSuchMethodException");
3307 } catch (IllegalAccessException e) {
3308 fail("IllegalAccessException");
3309 } catch (IllegalArgumentException e) {
3310 fail("IllegalArgumentException");
3311 } catch (InvocationTargetException e) {
3312 fail("InvocationTargetException");
3313 } catch (NoSuchMethodException e) {
3314
3315 }
3316
3317 }
3318
3319
3320 /***
3321 * Test setNestedProperty on a short property.
3322 */
3323 public void testSetNestedShort() {
3324
3325 try {
3326 short oldValue = bean.getNested().getShortProperty();
3327 short newValue = oldValue;
3328 newValue++;
3329 PropertyUtils.setNestedProperty(bean,
3330 "nested.shortProperty",
3331 new Short(newValue));
3332 assertEquals("Matched new value",
3333 newValue,
3334 bean.getNested().getShortProperty());
3335 } catch (IllegalAccessException e) {
3336 fail("IllegalAccessException");
3337 } catch (IllegalArgumentException e) {
3338 fail("IllegalArgumentException");
3339 } catch (InvocationTargetException e) {
3340 fail("InvocationTargetException");
3341 } catch (NoSuchMethodException e) {
3342 fail("NoSuchMethodException");
3343 }
3344
3345 }
3346
3347
3348 /***
3349 * Test setNestedProperty on a String property.
3350 */
3351 public void testSetNestedString() {
3352
3353 try {
3354 String oldValue = bean.getNested().getStringProperty();
3355 String newValue = oldValue + " Extra Value";
3356 PropertyUtils.setNestedProperty(bean,
3357 "nested.stringProperty",
3358 newValue);
3359 assertEquals("Matched new value",
3360 newValue,
3361 bean.getNested().getStringProperty());
3362 } catch (IllegalAccessException e) {
3363 fail("IllegalAccessException");
3364 } catch (IllegalArgumentException e) {
3365 fail("IllegalArgumentException");
3366 } catch (InvocationTargetException e) {
3367 fail("InvocationTargetException");
3368 } catch (NoSuchMethodException e) {
3369 fail("NoSuchMethodException");
3370 }
3371
3372 }
3373
3374
3375 /***
3376 * Test setNestedProperty on an unknown property name.
3377 */
3378 public void testSetNestedUnknown() {
3379
3380 try {
3381 String newValue = "New String Value";
3382 PropertyUtils.setNestedProperty(bean,
3383 "nested.unknown",
3384 newValue);
3385 fail("Should have thrown NoSuchMethodException");
3386 } catch (IllegalAccessException e) {
3387 fail("IllegalAccessException");
3388 } catch (IllegalArgumentException e) {
3389 fail("IllegalArgumentException");
3390 } catch (InvocationTargetException e) {
3391 fail("InvocationTargetException");
3392 } catch (NoSuchMethodException e) {
3393
3394 }
3395
3396 }
3397
3398
3399 /***
3400 * Test setNestedProperty on a write-only String property.
3401 */
3402 public void testSetNestedWriteOnly() {
3403
3404 try {
3405 String oldValue = bean.getNested().getWriteOnlyPropertyValue();
3406 String newValue = oldValue + " Extra Value";
3407 PropertyUtils.setNestedProperty(bean,
3408 "nested.writeOnlyProperty",
3409 newValue);
3410 assertEquals("Matched new value",
3411 newValue,
3412 bean.getNested().getWriteOnlyPropertyValue());
3413 } catch (IllegalAccessException e) {
3414 fail("IllegalAccessException");
3415 } catch (IllegalArgumentException e) {
3416 fail("IllegalArgumentException");
3417 } catch (InvocationTargetException e) {
3418 fail("InvocationTargetException");
3419 } catch (NoSuchMethodException e) {
3420 fail("NoSuchMethodException");
3421 }
3422
3423 }
3424
3425
3426 /***
3427 * Corner cases on setSimpleProperty invalid arguments.
3428 */
3429 public void testSetSimpleArguments() {
3430
3431 try {
3432 PropertyUtils.setSimpleProperty(null, "stringProperty", "");
3433 fail("Should throw IllegalArgumentException 1");
3434 } catch (IllegalArgumentException e) {
3435
3436 } catch (Throwable t) {
3437 fail("Threw " + t + " instead of IllegalArgumentException 1");
3438 }
3439
3440 try {
3441 PropertyUtils.setSimpleProperty(bean, null, "");
3442 fail("Should throw IllegalArgumentException 2");
3443 } catch (IllegalArgumentException e) {
3444
3445 } catch (Throwable t) {
3446 fail("Threw " + t + " instead of IllegalArgumentException 2");
3447 }
3448
3449 }
3450
3451
3452 /***
3453 * Test setSimpleProperty on a boolean property.
3454 */
3455 public void testSetSimpleBoolean() {
3456
3457 try {
3458 boolean oldValue = bean.getBooleanProperty();
3459 boolean newValue = !oldValue;
3460 PropertyUtils.setSimpleProperty(bean,
3461 "booleanProperty",
3462 new Boolean(newValue));
3463 assertTrue("Matched new value",
3464 newValue ==
3465 bean.getBooleanProperty());
3466 } catch (IllegalAccessException e) {
3467 fail("IllegalAccessException");
3468 } catch (IllegalArgumentException e) {
3469 fail("IllegalArgumentException");
3470 } catch (InvocationTargetException e) {
3471 fail("InvocationTargetException");
3472 } catch (NoSuchMethodException e) {
3473 fail("NoSuchMethodException");
3474 }
3475
3476 }
3477
3478
3479 /***
3480 * Test setSimpleProperty on a double property.
3481 */
3482 public void testSetSimpleDouble() {
3483
3484 try {
3485 double oldValue = bean.getDoubleProperty();
3486 double newValue = oldValue + 1.0;
3487 PropertyUtils.setSimpleProperty(bean,
3488 "doubleProperty",
3489 new Double(newValue));
3490 assertEquals("Matched new value",
3491 newValue,
3492 bean.getDoubleProperty(),
3493 0.005);
3494 } catch (IllegalAccessException e) {
3495 fail("IllegalAccessException");
3496 } catch (IllegalArgumentException e) {
3497 fail("IllegalArgumentException");
3498 } catch (InvocationTargetException e) {
3499 fail("InvocationTargetException");
3500 } catch (NoSuchMethodException e) {
3501 fail("NoSuchMethodException");
3502 }
3503
3504 }
3505
3506
3507 /***
3508 * Test setSimpleProperty on a float property.
3509 */
3510 public void testSetSimpleFloat() {
3511
3512 try {
3513 float oldValue = bean.getFloatProperty();
3514 float newValue = oldValue + (float) 1.0;
3515 PropertyUtils.setSimpleProperty(bean,
3516 "floatProperty",
3517 new Float(newValue));
3518 assertEquals("Matched new value",
3519 newValue,
3520 bean.getFloatProperty(),
3521 (float) 0.005);
3522 } catch (IllegalAccessException e) {
3523 fail("IllegalAccessException");
3524 } catch (IllegalArgumentException e) {
3525 fail("IllegalArgumentException");
3526 } catch (InvocationTargetException e) {
3527 fail("InvocationTargetException");
3528 } catch (NoSuchMethodException e) {
3529 fail("NoSuchMethodException");
3530 }
3531
3532 }
3533
3534
3535 /***
3536 * Negative test setSimpleProperty on an indexed property.
3537 */
3538 public void testSetSimpleIndexed() {
3539
3540 try {
3541 PropertyUtils.setSimpleProperty(bean,
3542 "stringIndexed[0]",
3543 "New String Value");
3544 fail("Should have thrown IllegalArgumentException");
3545 } catch (IllegalAccessException e) {
3546 fail("IllegalAccessException");
3547 } catch (IllegalArgumentException e) {
3548
3549 } catch (InvocationTargetException e) {
3550 fail("InvocationTargetException");
3551 } catch (NoSuchMethodException e) {
3552 fail("NoSuchMethodException");
3553 }
3554
3555 }
3556
3557
3558 /***
3559 * Test setSimpleProperty on a int property.
3560 */
3561 public void testSetSimpleInt() {
3562
3563 try {
3564 int oldValue = bean.getIntProperty();
3565 int newValue = oldValue + 1;
3566 PropertyUtils.setSimpleProperty(bean,
3567 "intProperty",
3568 new Integer(newValue));
3569 assertEquals("Matched new value",
3570 newValue,
3571 bean.getIntProperty());
3572 } catch (IllegalAccessException e) {
3573 fail("IllegalAccessException");
3574 } catch (IllegalArgumentException e) {
3575 fail("IllegalArgumentException");
3576 } catch (InvocationTargetException e) {
3577 fail("InvocationTargetException");
3578 } catch (NoSuchMethodException e) {
3579 fail("NoSuchMethodException");
3580 }
3581
3582 }
3583
3584
3585 /***
3586 * Test setSimpleProperty on a long property.
3587 */
3588 public void testSetSimpleLong() {
3589
3590 try {
3591 long oldValue = bean.getLongProperty();
3592 long newValue = oldValue + 1;
3593 PropertyUtils.setSimpleProperty(bean,
3594 "longProperty",
3595 new Long(newValue));
3596 assertEquals("Matched new value",
3597 newValue,
3598 bean.getLongProperty());
3599 } catch (IllegalAccessException e) {
3600 fail("IllegalAccessException");
3601 } catch (IllegalArgumentException e) {
3602 fail("IllegalArgumentException");
3603 } catch (InvocationTargetException e) {
3604 fail("InvocationTargetException");
3605 } catch (NoSuchMethodException e) {
3606 fail("NoSuchMethodException");
3607 }
3608
3609 }
3610
3611
3612 /***
3613 * Negative test setSimpleProperty on a nested property.
3614 */
3615 public void testSetSimpleNested() {
3616
3617 try {
3618 PropertyUtils.setSimpleProperty(bean,
3619 "nested.stringProperty",
3620 "New String Value");
3621 fail("Should have thrown IllegalArgumentException");
3622 } catch (IllegalAccessException e) {
3623 fail("IllegalAccessException");
3624 } catch (IllegalArgumentException e) {
3625
3626 } catch (InvocationTargetException e) {
3627 fail("InvocationTargetException");
3628 } catch (NoSuchMethodException e) {
3629 fail("NoSuchMethodException");
3630 }
3631
3632 }
3633
3634
3635 /***
3636 * Test setSimpleProperty on a read-only String property.
3637 */
3638 public void testSetSimpleReadOnly() {
3639
3640 try {
3641 String oldValue = bean.getWriteOnlyPropertyValue();
3642 String newValue = oldValue + " Extra Value";
3643 PropertyUtils.setSimpleProperty(bean,
3644 "readOnlyProperty",
3645 newValue);
3646 fail("Should have thrown NoSuchMethodException");
3647 } catch (IllegalAccessException e) {
3648 fail("IllegalAccessException");
3649 } catch (IllegalArgumentException e) {
3650 fail("IllegalArgumentException");
3651 } catch (InvocationTargetException e) {
3652 fail("InvocationTargetException");
3653 } catch (NoSuchMethodException e) {
3654
3655 assertEquals("Property 'readOnlyProperty' has no setter method in class '" +
3656 bean.getClass() + "'", e.getMessage() );
3657 }
3658
3659 }
3660
3661
3662 /***
3663 * Test setSimpleProperty on a short property.
3664 */
3665 public void testSetSimpleShort() {
3666
3667 try {
3668 short oldValue = bean.getShortProperty();
3669 short newValue = oldValue;
3670 newValue++;
3671 PropertyUtils.setSimpleProperty(bean,
3672 "shortProperty",
3673 new Short(newValue));
3674 assertEquals("Matched new value",
3675 newValue,
3676 bean.getShortProperty());
3677 } catch (IllegalAccessException e) {
3678 fail("IllegalAccessException");
3679 } catch (IllegalArgumentException e) {
3680 fail("IllegalArgumentException");
3681 } catch (InvocationTargetException e) {
3682 fail("InvocationTargetException");
3683 } catch (NoSuchMethodException e) {
3684 fail("NoSuchMethodException");
3685 }
3686
3687 }
3688
3689
3690 /***
3691 * Test setSimpleProperty on a String property.
3692 */
3693 public void testSetSimpleString() {
3694
3695 try {
3696 String oldValue = bean.getStringProperty();
3697 String newValue = oldValue + " Extra Value";
3698 PropertyUtils.setSimpleProperty(bean,
3699 "stringProperty",
3700 newValue);
3701 assertEquals("Matched new value",
3702 newValue,
3703 bean.getStringProperty());
3704 } catch (IllegalAccessException e) {
3705 fail("IllegalAccessException");
3706 } catch (IllegalArgumentException e) {
3707 fail("IllegalArgumentException");
3708 } catch (InvocationTargetException e) {
3709 fail("InvocationTargetException");
3710 } catch (NoSuchMethodException e) {
3711 fail("NoSuchMethodException");
3712 }
3713
3714 }
3715
3716
3717 /***
3718 * Test setSimpleProperty on an unknown property name.
3719 */
3720 public void testSetSimpleUnknown() {
3721
3722 try {
3723 String newValue = "New String Value";
3724 PropertyUtils.setSimpleProperty(bean,
3725 "unknown",
3726 newValue);
3727 fail("Should have thrown NoSuchMethodException");
3728 } catch (IllegalAccessException e) {
3729 fail("IllegalAccessException");
3730 } catch (IllegalArgumentException e) {
3731 fail("IllegalArgumentException");
3732 } catch (InvocationTargetException e) {
3733 fail("InvocationTargetException");
3734 } catch (NoSuchMethodException e) {
3735
3736 assertEquals("Unknown property 'unknown' on class '" +
3737 bean.getClass() + "'", e.getMessage() );
3738 }
3739
3740 }
3741
3742
3743 /***
3744 * Test setSimpleProperty on a write-only String property.
3745 */
3746 public void testSetSimpleWriteOnly() {
3747
3748 try {
3749 String oldValue = bean.getWriteOnlyPropertyValue();
3750 String newValue = oldValue + " Extra Value";
3751 PropertyUtils.setSimpleProperty(bean,
3752 "writeOnlyProperty",
3753 newValue);
3754 assertEquals("Matched new value",
3755 newValue,
3756 bean.getWriteOnlyPropertyValue());
3757 } catch (IllegalAccessException e) {
3758 fail("IllegalAccessException");
3759 } catch (IllegalArgumentException e) {
3760 fail("IllegalArgumentException");
3761 } catch (InvocationTargetException e) {
3762 fail("InvocationTargetException");
3763 } catch (NoSuchMethodException e) {
3764 fail("NoSuchMethodException");
3765 }
3766
3767 }
3768
3769
3770
3771
3772
3773 /***
3774 * Base for testGetDescriptorXxxxx() series of tests.
3775 *
3776 * @param name Name of the property to be retrieved
3777 * @param read Expected name of the read method (or null)
3778 * @param write Expected name of the write method (or null)
3779 */
3780 protected void testGetDescriptorBase(String name, String read,
3781 String write) {
3782
3783 try {
3784 PropertyDescriptor pd =
3785 PropertyUtils.getPropertyDescriptor(bean, name);
3786 if ((read != null) || (write != null)) {
3787 assertNotNull("Got descriptor", pd);
3788 } else {
3789 assertNull("Got descriptor", pd);
3790 return;
3791 }
3792 Method rm = pd.getReadMethod();
3793 if (read != null) {
3794 assertNotNull("Got read method", rm);
3795 assertEquals("Got correct read method",
3796 rm.getName(), read);
3797 } else {
3798 assertNull("Got read method", rm);
3799 }
3800 Method wm = pd.getWriteMethod();
3801 if (write != null) {
3802 assertNotNull("Got write method", wm);
3803 assertEquals("Got correct write method",
3804 wm.getName(), write);
3805 } else {
3806 assertNull("Got write method", wm);
3807 }
3808 } catch (IllegalAccessException e) {
3809 fail("IllegalAccessException");
3810 } catch (InvocationTargetException e) {
3811 fail("InvocationTargetException");
3812 } catch (NoSuchMethodException e) {
3813 fail("NoSuchMethodException");
3814 }
3815
3816 }
3817
3818
3819 /***
3820 * Base for testGetReadMethod() series of tests.
3821 *
3822 * @param bean Bean for which to retrieve read methods.
3823 * @param properties Property names to search for
3824 * @param className Class name where this method should be defined
3825 */
3826 protected void testGetReadMethod(Object bean, String properties[],
3827 String className) {
3828
3829 PropertyDescriptor pd[] =
3830 PropertyUtils.getPropertyDescriptors(bean);
3831 for (int i = 0; i < properties.length; i++) {
3832
3833
3834 if (properties[i].equals("intIndexed"))
3835 continue;
3836 if (properties[i].equals("stringIndexed"))
3837 continue;
3838 if (properties[i].equals("writeOnlyProperty"))
3839 continue;
3840 int n = -1;
3841 for (int j = 0; j < pd.length; j++) {
3842 if (properties[i].equals(pd[j].getName())) {
3843 n = j;
3844 break;
3845 }
3846 }
3847 assertTrue("PropertyDescriptor for " + properties[i],
3848 n >= 0);
3849
3850
3851 Method reader = PropertyUtils.getReadMethod(pd[n]);
3852 assertNotNull("Reader for " + properties[i],
3853 reader);
3854 Class clazz = reader.getDeclaringClass();
3855 assertNotNull("Declaring class for " + properties[i],
3856 clazz);
3857 assertEquals("Correct declaring class for " + properties[i],
3858 clazz.getName(),
3859 className);
3860
3861
3862 try {
3863 reader.invoke(bean, new Class[0]);
3864 } catch (Throwable t) {
3865 fail("Call for " + properties[i] + ": " + t);
3866 }
3867
3868 }
3869
3870 }
3871
3872
3873 /***
3874 * Base for testGetWriteMethod() series of tests.
3875 *
3876 * @param bean Bean for which to retrieve write methods.
3877 * @param properties Property names to search for
3878 * @param className Class name where this method should be defined
3879 */
3880 protected void testGetWriteMethod(Object bean, String properties[],
3881 String className) {
3882
3883
3884 PropertyDescriptor pd[] =
3885 PropertyUtils.getPropertyDescriptors(bean);
3886 for (int i = 0; i < properties.length; i++) {
3887
3888
3889 if (properties[i].equals("intIndexed"))
3890 continue;
3891 if (properties[i].equals("listIndexed"))
3892 continue;
3893 if (properties[i].equals("nested"))
3894 continue;
3895 if (properties[i].equals("readOnlyProperty"))
3896 continue;
3897 if (properties[i].equals("stringIndexed"))
3898 continue;
3899 int n = -1;
3900 for (int j = 0; j < pd.length; j++) {
3901 if (properties[i].equals(pd[j].getName())) {
3902 n = j;
3903 break;
3904 }
3905 }
3906 assertTrue("PropertyDescriptor for " + properties[i],
3907 n >= 0);
3908
3909
3910 Method writer = PropertyUtils.getWriteMethod(pd[n]);
3911 assertNotNull("Writer for " + properties[i],
3912 writer);
3913 Class clazz = writer.getDeclaringClass();
3914 assertNotNull("Declaring class for " + properties[i],
3915 clazz);
3916 assertEquals("Correct declaring class for " + properties[i],
3917 clazz.getName(),
3918 className);
3919
3920 }
3921
3922 }
3923
3924 public void testNestedWithIndex() throws Exception
3925 {
3926 NestedTestBean nestedBean = new NestedTestBean("base");
3927 nestedBean.init();
3928 nestedBean.getSimpleBeanProperty().init();
3929
3930 NestedTestBean
3931
3932
3933
3934 value = (NestedTestBean) PropertyUtils.getProperty(
3935 nestedBean,
3936 "indexedProperty[0]");
3937 assertEquals("Cannot get simple index(1)", "Bean@0", value.getName());
3938 assertEquals("Bug in NestedTestBean", "NOT SET", value.getTestString());
3939
3940 value = (NestedTestBean) PropertyUtils.getProperty(
3941 nestedBean,
3942 "indexedProperty[1]");
3943 assertEquals("Cannot get simple index(1)", "Bean@1", value.getName());
3944 assertEquals("Bug in NestedTestBean", "NOT SET", value.getTestString());
3945
3946 String
3947 prop = (String) PropertyUtils.getProperty(
3948 nestedBean,
3949 "indexedProperty[0].testString");
3950 assertEquals("Get property on indexes failed (1)", "NOT SET", prop);
3951
3952 prop = (String) PropertyUtils.getProperty(
3953 nestedBean,
3954 "indexedProperty[1].testString");
3955 assertEquals("Get property on indexes failed (2)", "NOT SET", prop);
3956
3957 PropertyUtils.setProperty(
3958 nestedBean,
3959 "indexedProperty[0].testString",
3960 "Test#1");
3961 assertEquals(
3962 "Cannot set property on indexed bean (1)",
3963 "Test#1",
3964 nestedBean.getIndexedProperty(0).getTestString());
3965
3966 PropertyUtils.setProperty(
3967 nestedBean,
3968 "indexedProperty[1].testString",
3969 "Test#2");
3970 assertEquals(
3971 "Cannot set property on indexed bean (2)",
3972 "Test#2",
3973 nestedBean.getIndexedProperty(1).getTestString());
3974
3975
3976
3977
3978 value = (NestedTestBean) PropertyUtils.getProperty(
3979 nestedBean,
3980 "simpleBeanProperty");
3981 assertEquals("Cannot get simple bean", "Simple Property Bean", value.getName());
3982 assertEquals("Bug in NestedTestBean", "NOT SET", value.getTestString());
3983
3984 value = (NestedTestBean) PropertyUtils.getProperty(
3985 nestedBean,
3986 "simpleBeanProperty.indexedProperty[3]");
3987 assertEquals("Cannot get index property on property", "Bean@3", value.getName());
3988 assertEquals("Bug in NestedTestBean", "NOT SET", value.getTestString());
3989
3990 PropertyUtils.setProperty(
3991 nestedBean,
3992 "simpleBeanProperty.indexedProperty[3].testString",
3993 "Test#3");
3994 assertEquals(
3995 "Cannot set property on indexed property on property",
3996 "Test#3",
3997 nestedBean.getSimpleBeanProperty().getIndexedProperty(3).getTestString());
3998 }
3999
4000 /*** Text case for setting properties on inner classes */
4001 public void testGetSetInnerBean() throws Exception {
4002 BeanWithInnerBean bean = new BeanWithInnerBean();
4003
4004 PropertyUtils.setProperty(bean, "innerBean.fish(loiterTimer)", "5");
4005 String out = (String) PropertyUtils.getProperty(bean.getInnerBean(), "fish(loiterTimer)");
4006 assertEquals(
4007 "(1) Inner class property set/get property failed.",
4008 "5",
4009 out);
4010
4011 out = (String) PropertyUtils.getProperty(bean, "innerBean.fish(loiterTimer)");
4012
4013 assertEquals(
4014 "(2) Inner class property set/get property failed.",
4015 "5",
4016 out);
4017 }
4018
4019 /*** Text case for setting properties on parent */
4020 public void testGetSetParentBean() throws Exception {
4021
4022 SonOfAlphaBean bean = new SonOfAlphaBean("Roger");
4023
4024 String out = (String) PropertyUtils.getProperty(bean, "name");
4025 assertEquals(
4026 "(1) Get/Set On Parent.",
4027 "Roger",
4028 out);
4029
4030 PropertyUtils.setProperty(bean, "name", "abcd");
4031 assertEquals(
4032 "(2) Get/Set On Parent.",
4033 "abcd",
4034 bean.getName());
4035 }
4036
4037 public void testSetNoGetter() throws Exception
4038 {
4039 BetaBean bean = new BetaBean("Cedric");
4040
4041
4042 bean.setNoGetterProperty("Sigma");
4043 assertEquals("BetaBean test failed", "Sigma", bean.getSecret());
4044
4045 assertNotNull("Descriptor is null", PropertyUtils.getPropertyDescriptor(bean, "noGetterProperty"));
4046
4047 BeanUtils.setProperty(bean, "noGetterProperty", "Omega");
4048 assertEquals("Cannot set no-getter property", "Omega", bean.getSecret());
4049
4050
4051 MappedPropertyDescriptor descriptor
4052 = new MappedPropertyDescriptor("noGetterMappedProperty", BetaBean.class);
4053
4054 assertNotNull("Map Descriptor is null", PropertyUtils.getPropertyDescriptor(bean, "noGetterMappedProperty"));
4055
4056 PropertyUtils.setMappedProperty(bean, "noGetterMappedProperty", "Epsilon", "Epsilon");
4057 assertEquals("Cannot set mapped no-getter property", "MAP:Epsilon", bean.getSecret());
4058 }
4059
4060 /***
4061 * There is an issue in setNestedProperty/getNestedProperty when the
4062 * target bean is a map and the name string requests mapped or indexed
4063 * operations on a field. These are not supported for fields of a Map,
4064 * but it's an easy mistake to make and this test case ensures that an
4065 * appropriate exception is thrown when a user does this.
4066 * <p>
4067 * The problem is with passing strings of form "a(b)" or "a[3]" to
4068 * setNestedProperty or getNestedProperty when the target bean they
4069 * are applied to implements Map. These strings are actually requesting
4070 * "the result of calling mapped method a on the target object with
4071 * a parameter of b" or "the result of calling indexed method a on the
4072 * target object with a parameter of 3". And these requests are not valid
4073 * when the target is a Map as a Map only supports calling get(fieldName)
4074 * or put(fieldName), neither of which can be further indexed with a
4075 * string or an integer.
4076 * <p>
4077 * However it is likely that some users will assume that "a[3]" when applied
4078 * to a map will be equivalent to (map.get("a"))[3] with the appropriate
4079 * typecasting, or for "a(b)" to be equivalent to map.get("a").get("b").
4080 * <p>
4081 * Here we verify that an exception is thrown if the user makes this
4082 * mistake.
4083 */
4084 public void testNestedPropertyKeyOrIndexOnBeanImplementingMap() throws Exception {
4085 HashMap map = new HashMap();
4086 HashMap submap = new HashMap();
4087 BetaBean betaBean1 = new BetaBean("test1");
4088 BetaBean betaBean2 = new BetaBean("test2");
4089
4090
4091 PropertyUtils.setNestedProperty(map, "submap", submap);
4092
4093
4094 PropertyUtils.setNestedProperty(map, "submap.beta1", betaBean1);
4095 assertEquals("Unexpected keys in map", "submap", keysToString(map));
4096 assertEquals("Unexpected keys in submap", "beta1", keysToString(submap));
4097
4098 try {
4099
4100
4101
4102
4103
4104
4105 PropertyUtils.setNestedProperty(map, "submap(beta2)", betaBean2);
4106
4107
4108
4109
4110
4111
4112 fail("Exception not thrown for invalid setNestedProperty syntax");
4113 } catch(IllegalArgumentException ex) {
4114
4115
4116
4117 int index = ex.getMessage().indexOf(
4118 "Indexed or mapped properties are not supported");
4119 assertTrue("Unexpected exception message", index>=0);
4120 }
4121
4122 try {
4123
4124
4125
4126
4127
4128
4129 Object o = PropertyUtils.getNestedProperty(map, "submap[3]");
4130
4131
4132
4133
4134
4135
4136 fail("Exception not thrown for invalid setNestedProperty syntax");
4137 } catch(IllegalArgumentException ex) {
4138
4139
4140
4141 int index = ex.getMessage().indexOf(
4142 "Indexed or mapped properties are not supported");
4143 assertTrue("Unexpected exception message", index>=0);
4144 }
4145 }
4146
4147 /***
4148 * Returns a single string containing all the keys in the map,
4149 * sorted in alphabetical order and separated by ", ".
4150 * <p>
4151 * If there are no keys, an empty string is returned.
4152 */
4153 private String keysToString(Map map) {
4154 Object[] mapKeys = map.keySet().toArray();
4155 java.util.Arrays.sort(mapKeys);
4156 StringBuffer buf = new StringBuffer();
4157 for(int i=0; i<mapKeys.length; ++i) {
4158 if (i != 0)
4159 buf.append(", ");
4160 buf.append(mapKeys[i]);
4161 }
4162 return buf.toString();
4163 }
4164
4165 /***
4166 * This tests to see that classes that implement Map always have their
4167 * custom properties ignored.
4168 * <p>
4169 * Note that this behaviour has changed several times over past releases
4170 * of beanutils, breaking backwards compatibility each time. Here's hoping
4171 * that the current 1.7.1 release is the last time this behaviour changes!
4172 */
4173 public void testMapExtensionDefault() throws Exception {
4174 ExtendMapBean bean = new ExtendMapBean();
4175
4176
4177 bean.setUnusuallyNamedProperty("bean value");
4178 assertEquals("Set property direct failed", "bean value", bean.getUnusuallyNamedProperty());
4179 assertNull("Get on unset map property failed",
4180 PropertyUtils.getNestedProperty(bean, "unusuallyNamedProperty"));
4181
4182
4183
4184 PropertyUtils.setSimpleProperty(bean, "unusuallyNamedProperty", "new value");
4185 assertEquals("Set property on map failed (1)", "new value", bean.getUnusuallyNamedProperty());
4186 assertNull("Get on unset map property failed",
4187 PropertyUtils.getNestedProperty(bean, "unusuallyNamedProperty"));
4188
4189
4190
4191 PropertyUtils.setProperty(bean, "unusuallyNamedProperty", "next value");
4192 assertEquals(
4193 "setNestedProperty on map not visible to getNestedProperty",
4194 "next value",
4195 PropertyUtils.getNestedProperty(bean, "unusuallyNamedProperty"));
4196 assertEquals(
4197 "Set nested property on map unexpected affected simple property",
4198 "new value",
4199 bean.getUnusuallyNamedProperty());
4200 }
4201
4202 /***
4203 * This tests to see that it is possible to subclass PropertyUtilsBean
4204 * and change the behaviour of setNestedProperty/getNestedProperty when
4205 * dealing with objects that implement Map.
4206 */
4207 public void testMapExtensionCustom() throws Exception {
4208 PropsFirstPropertyUtilsBean utilsBean = new PropsFirstPropertyUtilsBean();
4209 ExtendMapBean bean = new ExtendMapBean();
4210
4211
4212 bean.setUnusuallyNamedProperty("bean value");
4213 assertEquals("Set property direct failed", "bean value", bean.getUnusuallyNamedProperty());
4214
4215
4216 utilsBean.setSimpleProperty(bean, "unusuallyNamedProperty", "new value");
4217 assertEquals("Set property on map failed (1)", "new value", bean.getUnusuallyNamedProperty());
4218
4219
4220
4221 utilsBean.setProperty(bean, "unusuallyNamedProperty", "next value");
4222 assertEquals("Set property on map failed (2)", "next value", bean.getUnusuallyNamedProperty());
4223 assertEquals("setNestedProperty on non-simple property failed",
4224 "next value",
4225 utilsBean.getNestedProperty(bean, "unusuallyNamedProperty"));
4226
4227
4228
4229 utilsBean.setProperty(bean, "mapProperty", "value1");
4230 assertEquals("setNestedProperty on non-simple property failed",
4231 "value1", utilsBean.getNestedProperty(bean, "mapProperty"));
4232
4233 HashMap myMap = new HashMap();
4234 myMap.put("thebean", bean);
4235 utilsBean.getNestedProperty(myMap, "thebean.mapitem");
4236 utilsBean.getNestedProperty(myMap, "thebean(mapitem)");
4237 }
4238
4239 /***
4240 * Test {@link PropertyUtilsBean}'s invoke method throwing an IllegalArgumentException
4241 * and check that the "cause" has been properly initialized for JDK 1.4+
4242 * See BEANUTILS-266 for changes and reason for test
4243 */
4244 public void testExceptionFromInvoke() throws Exception {
4245 if (isPre14JVM()) {
4246 return;
4247 }
4248 try {
4249 PropertyUtils.setSimpleProperty(bean, "intProperty","XXX");
4250 } catch(IllegalArgumentException t) {
4251 Throwable cause = (Throwable)PropertyUtils.getProperty(t, "cause");
4252 assertNotNull("Cause not found", cause);
4253 assertTrue("Expected cause to be IllegalArgumentException, but was: " + cause.getClass(),
4254 cause instanceof IllegalArgumentException);
4255
4256
4257 } catch(Throwable t) {
4258 fail("Expected IllegalArgumentException, but threw " + t);
4259 }
4260 }
4261
4262 /***
4263 * Test for JDK 1.4
4264 */
4265 private boolean isPre14JVM() {
4266 String version = System.getProperty("java.specification.version");
4267 StringTokenizer tokenizer = new StringTokenizer(version,".");
4268 if (tokenizer.nextToken().equals("1")) {
4269 String minorVersion = tokenizer.nextToken();
4270 if (minorVersion.equals("0")) return true;
4271 if (minorVersion.equals("1")) return true;
4272 if (minorVersion.equals("2")) return true;
4273 if (minorVersion.equals("3")) return true;
4274 }
4275 return false;
4276 }
4277 }