View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.beanutils;
19  
20  import static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.assertNotNull;
22  import static org.junit.Assume.assumeTrue;
23  
24  import java.beans.IndexedPropertyDescriptor;
25  import java.beans.PropertyDescriptor;
26  import java.util.ArrayList;
27  import java.util.List;
28  
29  import org.apache.commons.beanutils.bugs.other.Jira492IndexedListsSupport;
30  import org.junit.After;
31  import org.junit.Before;
32  import org.junit.Test;
33  
34  
35  /**
36   * <p>Test Case for the Indexed Properties.</p>
37   *
38   * @version $Id$
39   */
40  
41  public class IndexedPropertyTestCase {
42  
43      // ---------------------------------------------------- Instance Variables
44  
45      /**
46       * The test bean for each test.
47       */
48      private IndexedTestBean bean = null;
49      private BeanUtilsBean beanUtilsBean;
50      private PropertyUtilsBean propertyUtilsBean;
51      private String[] testArray;
52      private String[] newArray;
53      private List<String> testList;
54      private List<Object> newList;
55      private ArrayList<Object> arrayList;
56  
57  
58      // -------------------------------------------------- Overall Test Methods
59  
60  
61      /**
62       * Set up instance variables required by this test case.
63       */
64      @Before
65      public void setUp() {
66  
67          // BeanUtils
68          beanUtilsBean = new BeanUtilsBean();
69          propertyUtilsBean = beanUtilsBean.getPropertyUtils();
70  
71          // initialize Arrays and Lists
72          testArray= new String[] {"array-0", "array-1", "array-2"};
73          newArray = new String[]  {"newArray-0", "newArray-1", "newArray-2"};
74  
75          testList = new ArrayList<String>();
76          testList.add("list-0");
77          testList.add("list-1");
78          testList.add("list-2");
79  
80          newList = new ArrayList<Object>();
81          newList.add("newList-0");
82          newList.add("newList-1");
83          newList.add("newList-2");
84  
85          arrayList = new ArrayList<Object>();
86          arrayList.add("arrayList-0");
87          arrayList.add("arrayList-1");
88          arrayList.add("arrayList-2");
89  
90          // initialize Test Bean  properties
91          bean = new IndexedTestBean();
92          bean.setStringArray(testArray);
93          bean.setStringList(testList);
94          bean.setArrayList(arrayList);
95      }
96  
97      /**
98       * Tear down instance variables required by this test case.
99       */
100     @After
101     public void tearDown() {
102         bean = null;
103     }
104 
105 
106     // ------------------------------------------------ Individual Test Methods
107 
108     /**
109      * Test IndexedPropertyDescriptor for an Array
110      */
111     @Test
112     public void testArrayIndexedPropertyDescriptor() throws Exception {
113         final PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "stringArray");
114         assertNotNull("No Array Descriptor", descriptor);
115         assertEquals("Not IndexedPropertyDescriptor",
116                      IndexedPropertyDescriptor.class,
117                      descriptor.getClass());
118         assertEquals("PropertDescriptor Type invalid",
119                      testArray.getClass(),
120                      descriptor.getPropertyType());
121     }
122 
123     /**
124      * Test IndexedPropertyDescriptor for a List
125      */
126     @Test
127     public void testListIndexedPropertyDescriptor() throws Exception {
128         final PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "stringList");
129         assertNotNull("No List Descriptor", descriptor);
130         if (Jira492IndexedListsSupport.supportsIndexedLists()) {
131             // BEANUTILS-492 - can't assume lists are handled as arrays in Java 8+
132             assertEquals("Not IndexedPropertyDescriptor",
133                          IndexedPropertyDescriptor.class, descriptor.getClass());
134         }
135         assertEquals("PropertDescriptor Type invalid",
136                      List.class,
137                      descriptor.getPropertyType());
138     }
139 
140     /**
141      * Test IndexedPropertyDescriptor for an ArrayList
142      */
143     @Test
144     public void testArrayListIndexedPropertyDescriptor() throws Exception {
145         final PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "arrayList");
146         assertNotNull("No ArrayList Descriptor", descriptor);
147         if (Jira492IndexedListsSupport.supportsIndexedLists()) {
148             assertEquals("Not IndexedPropertyDescriptor",
149                     IndexedPropertyDescriptor.class, descriptor.getClass());
150         }
151         assertEquals("PropertDescriptor Type invalid",
152                      ArrayList.class,
153                      descriptor.getPropertyType());
154     }
155 
156     /**
157      * Test Read Method for an Array
158      */
159     @Test
160     public void testArrayReadMethod() throws Exception {
161         final PropertyDescriptor descriptor =
162              (PropertyDescriptor)propertyUtilsBean.getPropertyDescriptor(bean, "stringArray");
163         assertNotNull("No Array Read Method", descriptor.getReadMethod());
164     }
165 
166     /**
167      * Test Write Method for an Array
168      */
169     @Test
170     public void testArrayWriteMethod() throws Exception {
171         final PropertyDescriptor descriptor =
172              (PropertyDescriptor)propertyUtilsBean.getPropertyDescriptor(bean, "stringArray");
173         assertNotNull("No Array Write Method", descriptor.getWriteMethod());
174     }
175 
176     /**
177      * Test Indexed Read Method for an Array
178      */
179     @Test
180     public void testArrayIndexedReadMethod() throws Exception {
181         final IndexedPropertyDescriptor descriptor =
182              (IndexedPropertyDescriptor)propertyUtilsBean.getPropertyDescriptor(bean, "stringArray");
183         assertNotNull("No Array Indexed Read Method", descriptor.getIndexedReadMethod());
184     }
185 
186     /**
187      * Test Indexed Write Method for an Array
188      */
189     @Test
190     public void testArrayIndexedWriteMethod() throws Exception {
191         final IndexedPropertyDescriptor descriptor =
192              (IndexedPropertyDescriptor)propertyUtilsBean.getPropertyDescriptor(bean, "stringArray");
193         assertNotNull("No Array Indexed Write Method", descriptor.getIndexedWriteMethod());
194     }
195 
196     /**
197      * Test Read Method for a List
198      *
199      * JDK 1.3.1_04: Test Passes
200      * JDK 1.4.2_05: Test Fails - getter which returns java.util.List not returned
201      *                            by IndexedPropertyDescriptor.getReadMethod();
202      */
203     @Test
204     public void testListReadMethod() throws Exception {
205         final PropertyDescriptor descriptor =
206              (PropertyDescriptor)propertyUtilsBean.getPropertyDescriptor(bean, "stringList");
207         assertNotNull("No List Read Method", descriptor.getReadMethod());
208     }
209 
210     /**
211      * Test Write Method for a List
212      *
213      * JDK 1.3.1_04: Test Passes
214      * JDK 1.4.2_05: Test Fails - setter whith java.util.List argument not returned
215      *                            by IndexedPropertyDescriptor.getWriteMethod();
216      */
217     @Test
218     public void testListWriteMethod() throws Exception {
219         final PropertyDescriptor descriptor =
220              (PropertyDescriptor)propertyUtilsBean.getPropertyDescriptor(bean, "stringList");
221         assertNotNull("No List Write Method", descriptor.getWriteMethod());
222     }
223 
224     /**
225      * Test Indexed Read Method for a List
226      */
227     @Test
228     public void testListIndexedReadMethod() throws Exception {
229         final PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "stringList");
230         assertNotNull("stringList descriptor not found", descriptor);
231         assumeTrue("JDK does not support index bean properties on java.util.List",
232                 Jira492IndexedListsSupport.supportsIndexedLists());
233         assertNotNull("No List Indexed Read Method",  ((IndexedPropertyDescriptor)descriptor).getIndexedReadMethod());
234     }
235 
236     /**
237      * Test Indexed Write Method for a List
238      */
239     @Test
240     public void testListIndexedWriteMethod() throws Exception {
241         final PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "stringList");
242         assertNotNull("stringList descriptor not found", descriptor);
243         assumeTrue("JDK does not support index bean properties on java.util.List",
244                 Jira492IndexedListsSupport.supportsIndexedLists());
245         assertNotNull("No List Indexed Write Method", ((IndexedPropertyDescriptor)descriptor).getIndexedWriteMethod());
246     }
247 
248     /**
249      * Test Read Method for an ArrayList
250      */
251     @Test
252     public void testArrayListReadMethod() throws Exception {
253         final PropertyDescriptor descriptor =
254              (PropertyDescriptor)propertyUtilsBean.getPropertyDescriptor(bean, "arrayList");
255         assertNotNull("No ArrayList Read Method", descriptor.getReadMethod());
256     }
257 
258     /**
259      * Test Write Method for an ArrayList
260      */
261     @Test
262     public void testArrayListWriteMethod() throws Exception {
263         final PropertyDescriptor descriptor =
264              propertyUtilsBean.getPropertyDescriptor(bean, "arrayList");
265         assertNotNull("No ArrayList Write Method", descriptor.getWriteMethod());
266     }
267 
268     /**
269      * Test getting an array property
270      */
271     @Test
272     public void testGetArray() throws Exception {
273         assertEquals(testArray,
274                      propertyUtilsBean.getProperty(bean, "stringArray"));
275     }
276 
277     /**
278      * Test getting an array property as a String
279      *
280      * NOTE: Why does retrieving array just return the first element in the array, whereas
281      *       retrieveing a List returns a comma separated list of all the elements?
282      */
283     @Test
284     public void testGetArrayAsString() throws Exception {
285         assertEquals("array-0",
286                      beanUtilsBean.getProperty(bean, "stringArray"));
287     }
288 
289     /**
290      * Test getting an indexed item of an Array using getProperty("name[x]")
291      */
292     @Test
293     public void testGetArrayItemA() throws Exception {
294         assertEquals("array-1",
295                      beanUtilsBean.getProperty(bean, "stringArray[1]"));
296     }
297 
298     /**
299      * Test getting an indexed item of an Array using getIndexedProperty("name")
300      */
301     @Test
302     public void testGetArrayItemB() throws Exception {
303         assertEquals("array-1",
304                      beanUtilsBean.getIndexedProperty(bean, "stringArray", 1));
305     }
306 
307     /**
308      * Test getting a List
309      *
310      * JDK 1.3.1_04: Test Passes
311      * JDK 1.4.2_05: Test Fails - fails NoSuchMethodException, i.e. reason as testListReadMethod()
312      *                            failed.
313      */
314     @Test
315     public void testGetList() throws Exception {
316         assertEquals(testList,
317                      propertyUtilsBean.getProperty(bean, "stringList"));
318     }
319 
320     /**
321      * Test getting a List property as a String
322      *
323      * JDK 1.3.1_04: Test Passes
324      * JDK 1.4.2_05: Test Fails - fails NoSuchMethodException, i.e. reason as testListReadMethod()
325      *                            failed.
326      */
327     @Test
328     public void testGetListAsString() throws Exception {
329         assertEquals("list-0",
330                      beanUtilsBean.getProperty(bean, "stringList"));
331     }
332 
333     /**
334      * Test getting an indexed item of a List using getProperty("name[x]")
335      */
336     @Test
337     public void testGetListItemA() throws Exception {
338         assertEquals("list-1",
339                      beanUtilsBean.getProperty(bean, "stringList[1]"));
340     }
341 
342     /**
343      * Test getting an indexed item of a List using getIndexedProperty("name")
344      */
345     @Test
346     public void testGetListItemB() throws Exception {
347         assertEquals("list-1",
348                      beanUtilsBean.getIndexedProperty(bean, "stringList", 1));
349     }
350 
351     /**
352      * Test setting an Array property
353      *
354      * JDK 1.3.1_04 and 1.4.2_05: Test Fails - IllegalArgumentException can't invoke setter, argument type mismatch
355      *
356      * Fails because of a bug in BeanUtilsBean.setProperty() method. Value is always converted to the array's component
357      * type which in this case is a String. Then it calls the setStringArray(String[]) passing a String rather than
358      * String[] causing this exception. If there isn't an "index" value then the PropertyType (rather than
359      * IndexedPropertyType) should be used.
360      *
361      */
362     @Test
363     public void testSetArray() throws Exception {
364         beanUtilsBean.setProperty(bean, "stringArray", newArray);
365         final Object value = bean.getStringArray();
366         assertEquals("Type is different", newArray.getClass(), value.getClass());
367         final String[] array = (String[])value;
368         assertEquals("Array Length is different", newArray.length, array.length);
369         for (int i = 0; i < array.length; i++) {
370             assertEquals("Element " + i + " is different", newArray[i], array[i]);
371         }
372     }
373 
374 
375     /**
376      * Test setting an indexed item of an Array using setProperty("name[x]", value)
377      */
378     @Test
379     public void testSetArrayItemA() throws Exception {
380         beanUtilsBean.setProperty(bean, "stringArray[1]", "modified-1");
381         assertEquals("modified-1", bean.getStringArray(1));
382     }
383 
384     /**
385      * Test setting an indexed item of an Array using setIndexedProperty("name", value)
386      */
387     @Test
388     public void testSetArrayItemB() throws Exception {
389         propertyUtilsBean.setIndexedProperty(bean, "stringArray", 1, "modified-1");
390         assertEquals("modified-1", bean.getStringArray(1));
391     }
392 
393     /**
394      * Test setting a List property
395      *
396      * JDK 1.3.1_04: Test Passes
397      * JDK 1.4.2_05: Test Fails - setter which returns java.util.List not returned
398      *                            by IndexedPropertyDescriptor.getWriteMethod() - therefore
399      *                            setProperty does nothing and values remain unchanged.
400      */
401     @Test
402     public void testSetList() throws Exception {
403         beanUtilsBean.setProperty(bean, "stringList", newList);
404         final Object value = bean.getStringList();
405         assertEquals("Type is different", newList.getClass(), value.getClass());
406         final List<?> list  = (List<?>)value;
407         assertEquals("List size is different", newList.size(), list.size());
408         for (int i = 0; i < list.size(); i++) {
409             assertEquals("Element " + i + " is different", newList.get(i), list.get(i));
410         }
411     }
412 
413 
414     /**
415      * Test setting an indexed item of a List using setProperty("name[x]", value)
416      */
417     @Test
418     public void testSetListItemA() throws Exception {
419         beanUtilsBean.setProperty(bean, "stringList[1]", "modified-1");
420         assertEquals("modified-1", bean.getStringList(1));
421     }
422 
423     /**
424      * Test setting an indexed item of a List using setIndexedProperty("name", value)
425      */
426     @Test
427     public void testSetListItemB() throws Exception {
428         propertyUtilsBean.setIndexedProperty(bean, "stringList", 1, "modified-1");
429         assertEquals("modified-1", bean.getStringList(1));
430     }
431 
432 
433     /**
434      * Test getting an ArrayList
435      */
436     @Test
437     public void testGetArrayList() throws Exception {
438         assertEquals(arrayList,
439                      propertyUtilsBean.getProperty(bean, "arrayList"));
440     }
441 
442     /**
443      * Test setting an ArrayList property
444      */
445     @Test
446     public void testSetArrayList() throws Exception {
447         beanUtilsBean.setProperty(bean, "arrayList", newList);
448         final Object value = bean.getArrayList();
449         assertEquals("Type is different", newList.getClass(), value.getClass());
450         final List<?> list  = (List<?>)value;
451         assertEquals("List size is different", newList.size(), list.size());
452         for (int i = 0; i < list.size(); i++) {
453             assertEquals("Element " + i + " is different", newList.get(i), list.get(i));
454         }
455     }
456 
457 }