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    *      https://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.beanutils2;
19  
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertNotNull;
22  import static org.junit.jupiter.api.Assumptions.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.beanutils2.bugs.other.Jira492IndexedListsSupport;
30  import org.junit.jupiter.api.AfterEach;
31  import org.junit.jupiter.api.BeforeEach;
32  import org.junit.jupiter.api.Test;
33  
34  /**
35   * <p>
36   * Test Case for the Indexed Properties.
37   * </p>
38   */
39  
40  public class IndexedPropertyTest {
41  
42      /**
43       * The test bean for each test.
44       */
45      private IndexedTestBean bean;
46      private BeanUtilsBean beanUtilsBean;
47      private PropertyUtilsBean propertyUtilsBean;
48      private String[] testArray;
49      private String[] newArray;
50      private List<String> testList;
51      private List<Object> newList;
52      private ArrayList<Object> arrayList;
53  
54      /**
55       * Sets up instance variables required by this test case.
56       */
57      @BeforeEach
58      public void setUp() {
59  
60          // BeanUtils
61          beanUtilsBean = new BeanUtilsBean();
62          propertyUtilsBean = beanUtilsBean.getPropertyUtils();
63  
64          // initialize Arrays and Lists
65          testArray = new String[] { "array-0", "array-1", "array-2" };
66          newArray = new String[] { "newArray-0", "newArray-1", "newArray-2" };
67  
68          testList = new ArrayList<>();
69          testList.add("list-0");
70          testList.add("list-1");
71          testList.add("list-2");
72  
73          newList = new ArrayList<>();
74          newList.add("newList-0");
75          newList.add("newList-1");
76          newList.add("newList-2");
77  
78          arrayList = new ArrayList<>();
79          arrayList.add("arrayList-0");
80          arrayList.add("arrayList-1");
81          arrayList.add("arrayList-2");
82  
83          // initialize Test Bean properties
84          bean = new IndexedTestBean();
85          bean.setStringArray(testArray);
86          bean.setStringList(testList);
87          bean.setArrayList(arrayList);
88      }
89  
90      /**
91       * Tear down instance variables required by this test case.
92       */
93      @AfterEach
94      public void tearDown() {
95          bean = null;
96      }
97  
98      /**
99       * Test IndexedPropertyDescriptor for an Array
100      */
101     @Test
102     public void testArrayIndexedPropertyDescriptor() throws Exception {
103         final PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "stringArray");
104         assertNotNull(descriptor, "No Array Descriptor");
105         assertEquals(IndexedPropertyDescriptor.class, descriptor.getClass(), "Not IndexedPropertyDescriptor");
106         assertEquals(testArray.getClass(), descriptor.getPropertyType(), "PropertyDescriptor Type invalid");
107     }
108 
109     /**
110      * Test Indexed Read Method for an Array
111      */
112     @Test
113     public void testArrayIndexedReadMethod() throws Exception {
114         final IndexedPropertyDescriptor descriptor = (IndexedPropertyDescriptor) propertyUtilsBean.getPropertyDescriptor(bean, "stringArray");
115         assertNotNull(descriptor.getIndexedReadMethod(), "No Array Indexed Read Method");
116     }
117 
118     /**
119      * Test Indexed Write Method for an Array
120      */
121     @Test
122     public void testArrayIndexedWriteMethod() throws Exception {
123         final IndexedPropertyDescriptor descriptor = (IndexedPropertyDescriptor) propertyUtilsBean.getPropertyDescriptor(bean, "stringArray");
124         assertNotNull(descriptor.getIndexedWriteMethod(), "No Array Indexed Write Method");
125     }
126 
127     /**
128      * Test IndexedPropertyDescriptor for an ArrayList
129      */
130     @Test
131     public void testArrayListIndexedPropertyDescriptor() throws Exception {
132         final PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "arrayList");
133         assertNotNull(descriptor, "No ArrayList Descriptor");
134         if (Jira492IndexedListsSupport.supportsIndexedLists()) {
135             assertEquals(IndexedPropertyDescriptor.class, descriptor.getClass(), "Not IndexedPropertyDescriptor");
136         }
137         assertEquals(ArrayList.class, descriptor.getPropertyType(), "PropertyDescriptor Type invalid");
138     }
139 
140     /**
141      * Test Read Method for an ArrayList
142      */
143     @Test
144     public void testArrayListReadMethod() throws Exception {
145         final PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "arrayList");
146         assertNotNull(descriptor.getReadMethod(), "No ArrayList Read Method");
147     }
148 
149     /**
150      * Test Write Method for an ArrayList
151      */
152     @Test
153     public void testArrayListWriteMethod() throws Exception {
154         final PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "arrayList");
155         assertNotNull(descriptor.getWriteMethod(), "No ArrayList Write Method");
156     }
157 
158     /**
159      * Test Read Method for an Array
160      */
161     @Test
162     public void testArrayReadMethod() throws Exception {
163         final PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "stringArray");
164         assertNotNull(descriptor.getReadMethod(), "No Array Read Method");
165     }
166 
167     /**
168      * Test Write Method for an Array
169      */
170     @Test
171     public void testArrayWriteMethod() throws Exception {
172         final PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "stringArray");
173         assertNotNull(descriptor.getWriteMethod(), "No Array Write Method");
174     }
175 
176     /**
177      * Test getting an array property
178      */
179     @Test
180     public void testGetArray() throws Exception {
181         assertEquals(testArray, propertyUtilsBean.getProperty(bean, "stringArray"));
182     }
183 
184     /**
185      * Test getting an array property as a String
186      *
187      * NOTE: Why does retrieving array just return the first element in the array, whereas retrieving a List returns a comma separated list of all the elements?
188      */
189     @Test
190     public void testGetArrayAsString() throws Exception {
191         assertEquals("array-0", beanUtilsBean.getProperty(bean, "stringArray"));
192     }
193 
194     /**
195      * Test getting an indexed item of an Array using getProperty("name[x]")
196      */
197     @Test
198     public void testGetArrayItemA() throws Exception {
199         assertEquals("array-1", beanUtilsBean.getProperty(bean, "stringArray[1]"));
200     }
201 
202     /**
203      * Test getting an indexed item of an Array using getIndexedProperty("name")
204      */
205     @Test
206     public void testGetArrayItemB() throws Exception {
207         assertEquals("array-1", beanUtilsBean.getIndexedProperty(bean, "stringArray", 1));
208     }
209 
210     /**
211      * Test getting an ArrayList
212      */
213     @Test
214     public void testGetArrayList() throws Exception {
215         assertEquals(arrayList, propertyUtilsBean.getProperty(bean, "arrayList"));
216     }
217 
218     /**
219      * Test getting a List
220      *
221      * JDK 1.3.1_04: Test Passes JDK 1.4.2_05: Test Fails - fails NoSuchMethodException, i.e. reason as testListReadMethod() failed.
222      */
223     @Test
224     public void testGetList() throws Exception {
225         assertEquals(testList, propertyUtilsBean.getProperty(bean, "stringList"));
226     }
227 
228     /**
229      * Test getting a List property as a String
230      *
231      * JDK 1.3.1_04: Test Passes JDK 1.4.2_05: Test Fails - fails NoSuchMethodException, i.e. reason as testListReadMethod() failed.
232      */
233     @Test
234     public void testGetListAsString() throws Exception {
235         assertEquals("list-0", beanUtilsBean.getProperty(bean, "stringList"));
236     }
237 
238     /**
239      * Test getting an indexed item of a List using getProperty("name[x]")
240      */
241     @Test
242     public void testGetListItemA() throws Exception {
243         assertEquals("list-1", beanUtilsBean.getProperty(bean, "stringList[1]"));
244     }
245 
246     /**
247      * Test getting an indexed item of a List using getIndexedProperty("name")
248      */
249     @Test
250     public void testGetListItemB() throws Exception {
251         assertEquals("list-1", beanUtilsBean.getIndexedProperty(bean, "stringList", 1));
252     }
253 
254     /**
255      * Test IndexedPropertyDescriptor for a List
256      */
257     @Test
258     public void testListIndexedPropertyDescriptor() throws Exception {
259         final PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "stringList");
260         assertNotNull(descriptor, "No List Descriptor");
261         if (Jira492IndexedListsSupport.supportsIndexedLists()) {
262             // BEANUTILS-492 - can't assume lists are handled as arrays in Java 8+
263             assertEquals(IndexedPropertyDescriptor.class, descriptor.getClass(), "Not IndexedPropertyDescriptor");
264         }
265         assertEquals(List.class, descriptor.getPropertyType(), "PropertyDescriptor Type invalid");
266     }
267 
268     /**
269      * Test Indexed Read Method for a List
270      */
271     @Test
272     public void testListIndexedReadMethod() throws Exception {
273         final PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "stringList");
274         assertNotNull(descriptor, "stringList descriptor not found");
275         assumeTrue(Jira492IndexedListsSupport.supportsIndexedLists(), "JDK does not support index bean properties on java.util.List");
276         assertNotNull(((IndexedPropertyDescriptor) descriptor).getIndexedReadMethod(), "No List Indexed Read Method");
277     }
278 
279     /**
280      * Test Indexed Write Method for a List
281      */
282     @Test
283     public void testListIndexedWriteMethod() throws Exception {
284         final PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "stringList");
285         assertNotNull(descriptor, "stringList descriptor not found");
286         assumeTrue(Jira492IndexedListsSupport.supportsIndexedLists(), "JDK does not support index bean properties on java.util.List");
287         assertNotNull(((IndexedPropertyDescriptor) descriptor).getIndexedWriteMethod(), "No List Indexed Write Method");
288     }
289 
290     /**
291      * Test Read Method for a List
292      *
293      * JDK 1.3.1_04: Test Passes JDK 1.4.2_05: Test Fails - getter which returns java.util.List not returned by IndexedPropertyDescriptor.getReadMethod();
294      */
295     @Test
296     public void testListReadMethod() throws Exception {
297         final PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "stringList");
298         assertNotNull(descriptor.getReadMethod(), "No List Read Method");
299     }
300 
301     /**
302      * Test Write Method for a List
303      *
304      * JDK 1.3.1_04: Test Passes JDK 1.4.2_05: Test Fails - setter which java.util.List argument not returned by IndexedPropertyDescriptor.getWriteMethod();
305      */
306     @Test
307     public void testListWriteMethod() throws Exception {
308         final PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(bean, "stringList");
309         assertNotNull(descriptor.getWriteMethod(), "No List Write Method");
310     }
311 
312     /**
313      * Test setting an Array property
314      *
315      * JDK 1.3.1_04 and 1.4.2_05: Test Fails - IllegalArgumentException can't invoke setter, argument type mismatch
316      *
317      * Fails because of a bug in BeanUtilsBean.setProperty() method. Value is always converted to the array's component type which in this case is a String.
318      * Then it calls the setStringArray(String[]) passing a String rather than String[] causing this exception. If there isn't an "index" value then the
319      * PropertyType (rather than IndexedPropertyType) should be used.
320      */
321     @Test
322     public void testSetArray() throws Exception {
323         beanUtilsBean.setProperty(bean, "stringArray", newArray);
324         final Object value = bean.getStringArray();
325         assertEquals(newArray.getClass(), value.getClass(), "Type is different");
326         final String[] array = (String[]) value;
327         assertEquals(newArray.length, array.length, "Array Length is different");
328         for (int i = 0; i < array.length; i++) {
329             assertEquals(newArray[i], array[i], "Element " + i + " is different");
330         }
331     }
332 
333     /**
334      * Test setting an indexed item of an Array using setProperty("name[x]", value)
335      */
336     @Test
337     public void testSetArrayItemA() throws Exception {
338         beanUtilsBean.setProperty(bean, "stringArray[1]", "modified-1");
339         assertEquals("modified-1", bean.getStringArray(1));
340     }
341 
342     /**
343      * Test setting an indexed item of an Array using setIndexedProperty("name", value)
344      */
345     @Test
346     public void testSetArrayItemB() throws Exception {
347         propertyUtilsBean.setIndexedProperty(bean, "stringArray", 1, "modified-1");
348         assertEquals("modified-1", bean.getStringArray(1));
349     }
350 
351     /**
352      * Test setting an ArrayList property
353      */
354     @Test
355     public void testSetArrayList() throws Exception {
356         beanUtilsBean.setProperty(bean, "arrayList", newList);
357         final Object value = bean.getArrayList();
358         assertEquals(newList.getClass(), value.getClass(), "Type is different");
359         final List<?> list = (List<?>) value;
360         assertEquals(newList.size(), list.size(), "List size is different");
361         for (int i = 0; i < list.size(); i++) {
362             assertEquals(newList.get(i), list.get(i), "Element " + i + " is different");
363         }
364     }
365 
366     /**
367      * Test setting a List property
368      *
369      * JDK 1.3.1_04: Test Passes JDK 1.4.2_05: Test Fails - setter which returns java.util.List not returned by IndexedPropertyDescriptor.getWriteMethod() -
370      * therefore setProperty does nothing and values remain unchanged.
371      */
372     @Test
373     public void testSetList() throws Exception {
374         beanUtilsBean.setProperty(bean, "stringList", newList);
375         final Object value = bean.getStringList();
376         assertEquals(newList.getClass(), value.getClass(), "Type is different");
377         final List<?> list = (List<?>) value;
378         assertEquals(newList.size(), list.size(), "List size is different");
379         for (int i = 0; i < list.size(); i++) {
380             assertEquals(newList.get(i), list.get(i), "Element " + i + " is different");
381         }
382     }
383 
384     /**
385      * Test setting an indexed item of a List using setProperty("name[x]", value)
386      */
387     @Test
388     public void testSetListItemA() throws Exception {
389         beanUtilsBean.setProperty(bean, "stringList[1]", "modified-1");
390         assertEquals("modified-1", bean.getStringList(1));
391     }
392 
393     /**
394      * Test setting an indexed item of a List using setIndexedProperty("name", value)
395      */
396     @Test
397     public void testSetListItemB() throws Exception {
398         propertyUtilsBean.setIndexedProperty(bean, "stringList", 1, "modified-1");
399         assertEquals("modified-1", bean.getStringList(1));
400     }
401 
402 }