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