| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.commons.beanutils2; |
| |
| import java.beans.IntrospectionException; |
| import java.beans.PropertyDescriptor; |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.apache.commons.beanutils2.priv.PrivateBeanFactory; |
| import org.apache.commons.beanutils2.priv.PrivateDirect; |
| import org.apache.commons.beanutils2.priv.PublicSubBean; |
| |
| import junit.framework.Test; |
| import junit.framework.TestCase; |
| import junit.framework.TestSuite; |
| |
| /** |
| * <p>Test Case for the PropertyUtils class. The majority of these tests use |
| * instances of the TestBean class, so be sure to update the tests if you |
| * change the characteristics of that class.</p> |
| * |
| * <p>So far, this test case has tests for the following methods of the |
| * {@code PropertyUtils} class:</p> |
| * <ul> |
| * <li>getIndexedProperty(Object,String)</li> |
| * <li>getIndexedProperty(Object,String,int)</li> |
| * <li>getMappedProperty(Object,String)</li> |
| * <li>getMappedProperty(Object,String,String</li> |
| * <li>getNestedProperty(Object,String)</li> |
| * <li>getPropertyDescriptor(Object,String)</li> |
| * <li>getPropertyDescriptors(Object)</li> |
| * <li>getPropertyType(Object,String)</li> |
| * <li>getSimpleProperty(Object,String)</li> |
| * <li>setIndexedProperty(Object,String,Object)</li> |
| * <li>setIndexedProperty(Object,String,String,Object)</li> |
| * <li>setMappedProperty(Object,String,Object)</li> |
| * <li>setMappedProperty(Object,String,String,Object)</li> |
| * <li>setNestedProperty(Object,String,Object)</li> |
| * <li>setSimpleProperty(Object,String,Object)</li> |
| * </ul> |
| * |
| */ |
| |
| public class PropertyUtilsTestCase extends TestCase { |
| |
| |
| |
| /** |
| * The fully qualified class name of our private directly |
| * implemented interface. |
| */ |
| private static final String PRIVATE_DIRECT_CLASS = |
| "org.apache.commons.beanutils2.priv.PrivateDirect"; |
| |
| /** |
| * The fully qualified class name of our private indirectly |
| * implemented interface. |
| */ |
| private static final String PRIVATE_INDIRECT_CLASS = |
| "org.apache.commons.beanutils2.priv.PrivateIndirect"; |
| |
| /** |
| * The fully qualified class name of our test bean class. |
| */ |
| private static final String TEST_BEAN_CLASS = |
| "org.apache.commons.beanutils2.TestBean"; |
| |
| /** |
| * The basic test bean for each test. |
| */ |
| protected TestBean bean = null; |
| |
| /** |
| * The "package private subclass" test bean for each test. |
| */ |
| protected TestBeanPackageSubclass beanPackageSubclass = null; |
| |
| /** |
| * The test bean for private access tests. |
| */ |
| protected PrivateDirect beanPrivate = null; |
| |
| /** |
| * The test bean for private access tests of subclasses. |
| */ |
| protected PrivateDirect beanPrivateSubclass = null; |
| |
| /** |
| * The "public subclass" test bean for each test. |
| */ |
| protected TestBeanPublicSubclass beanPublicSubclass = null; |
| |
| /** |
| * The set of properties that should be described. |
| */ |
| protected String[] describes = |
| { "booleanProperty", |
| "booleanSecond", |
| "doubleProperty", |
| "floatProperty", |
| "intArray", |
| // "intIndexed", |
| "intProperty", |
| "listIndexed", |
| "longProperty", |
| // "mappedObjects", |
| // "mappedProperty", |
| // "mappedIntProperty", |
| "nested", |
| "nullProperty", |
| // "readOnlyProperty", |
| "shortProperty", |
| "stringArray", |
| // "stringIndexed", |
| "stringProperty" |
| }; |
| |
| /** |
| * The set of property names we expect to have returned when calling |
| * {@code getPropertyDescriptors()}. You should update this list |
| * when new properties are added to TestBean. |
| */ |
| protected final static String[] properties = { |
| "booleanProperty", |
| "booleanSecond", |
| "doubleProperty", |
| "dupProperty", |
| "floatProperty", |
| "intArray", |
| "intIndexed", |
| "intProperty", |
| "listIndexed", |
| "longProperty", |
| "nested", |
| "nullProperty", |
| "readOnlyProperty", |
| "shortProperty", |
| "stringArray", |
| "stringIndexed", |
| "stringProperty", |
| "writeOnlyProperty", |
| }; |
| |
| |
| |
| /** |
| * Construct a new instance of this test case. |
| * |
| * @param name Name of the test case |
| */ |
| public PropertyUtilsTestCase(final String name) { |
| |
| super(name); |
| |
| } |
| |
| |
| |
| /** |
| * Set up instance variables required by this test case. |
| */ |
| @Override |
| public void setUp() { |
| |
| bean = new TestBean(); |
| beanPackageSubclass = new TestBeanPackageSubclass(); |
| beanPrivate = PrivateBeanFactory.create(); |
| beanPrivateSubclass = PrivateBeanFactory.createSubclass(); |
| beanPublicSubclass = new TestBeanPublicSubclass(); |
| |
| final DynaProperty[] properties = new DynaProperty[] { |
| new DynaProperty("stringProperty", String.class), |
| new DynaProperty("nestedBean", TestBean.class), |
| new DynaProperty("nullDynaBean", DynaBean.class) |
| }; |
| final BasicDynaClass dynaClass = new BasicDynaClass("nestedDynaBean", BasicDynaBean.class, properties); |
| final BasicDynaBean nestedDynaBean = new BasicDynaBean(dynaClass); |
| nestedDynaBean.set("nestedBean", bean); |
| bean.setNestedDynaBean(nestedDynaBean); |
| PropertyUtils.clearDescriptors(); |
| } |
| |
| /** |
| * Return the tests included in this test suite. |
| */ |
| public static Test suite() { |
| |
| return new TestSuite(PropertyUtilsTestCase.class); |
| |
| } |
| |
| /** |
| * Tear down instance variables required by this test case. |
| */ |
| @Override |
| public void tearDown() { |
| |
| bean = null; |
| beanPackageSubclass = null; |
| beanPrivate = null; |
| beanPrivateSubclass = null; |
| beanPublicSubclass = null; |
| |
| PropertyUtils.resetBeanIntrospectors(); |
| } |
| |
| |
| |
| /** |
| * Test copyProperties() when the origin is a a {@code Map}. |
| */ |
| public void testCopyPropertiesMap() { |
| |
| final Map<String, Object> map = new HashMap<>(); |
| map.put("booleanProperty", Boolean.FALSE); |
| map.put("doubleProperty", new Double(333.0)); |
| map.put("dupProperty", new String[] { "New 0", "New 1", "New 2" }); |
| map.put("floatProperty", new Float((float) 222.0)); |
| map.put("intArray", new int[] { 0, 100, 200 }); |
| map.put("intProperty", new Integer(111)); |
| map.put("longProperty", new Long(444)); |
| map.put("shortProperty", new Short((short) 555)); |
| map.put("stringProperty", "New String Property"); |
| |
| try { |
| PropertyUtils.copyProperties(bean, map); |
| } catch (final Throwable t) { |
| fail("Threw " + t.toString()); |
| } |
| |
| // Scalar properties |
| assertEquals("booleanProperty", false, |
| bean.getBooleanProperty()); |
| assertEquals("doubleProperty", 333.0, |
| bean.getDoubleProperty(), 0.005); |
| assertEquals("floatProperty", (float) 222.0, |
| bean.getFloatProperty(), (float) 0.005); |
| assertEquals("intProperty", 111, |
| bean.getIntProperty()); |
| assertEquals("longProperty", 444, |
| bean.getLongProperty()); |
| assertEquals("shortProperty", (short) 555, |
| bean.getShortProperty()); |
| assertEquals("stringProperty", "New String Property", |
| bean.getStringProperty()); |
| |
| // Indexed Properties |
| final String[] dupProperty = bean.getDupProperty(); |
| assertNotNull("dupProperty present", dupProperty); |
| assertEquals("dupProperty length", 3, dupProperty.length); |
| assertEquals("dupProperty[0]", "New 0", dupProperty[0]); |
| assertEquals("dupProperty[1]", "New 1", dupProperty[1]); |
| assertEquals("dupProperty[2]", "New 2", dupProperty[2]); |
| final int[] intArray = bean.getIntArray(); |
| assertNotNull("intArray present", intArray); |
| assertEquals("intArray length", 3, intArray.length); |
| assertEquals("intArray[0]", 0, intArray[0]); |
| assertEquals("intArray[1]", 100, intArray[1]); |
| assertEquals("intArray[2]", 200, intArray[2]); |
| |
| } |
| |
| /** |
| * Test the describe() method. |
| */ |
| public void testDescribe() { |
| |
| Map<String, Object> map = null; |
| try { |
| map = PropertyUtils.describe(bean); |
| } catch (final Exception e) { |
| fail("Threw exception " + e); |
| } |
| |
| // Verify existence of all the properties that should be present |
| for (final String describe : describes) { |
| assertTrue("Property '" + describe + "' is present", |
| map.containsKey(describe)); |
| } |
| assertTrue("Property 'writeOnlyProperty' is not present", |
| !map.containsKey("writeOnlyProperty")); |
| |
| // Verify the values of scalar properties |
| assertEquals("Value of 'booleanProperty'", |
| Boolean.TRUE, map.get("booleanProperty")); |
| assertEquals("Value of 'doubleProperty'", |
| new Double(321.0), map.get("doubleProperty")); |
| assertEquals("Value of 'floatProperty'", |
| new Float((float) 123.0), map.get("floatProperty")); |
| assertEquals("Value of 'intProperty'", |
| new Integer(123), map.get("intProperty")); |
| assertEquals("Value of 'longProperty'", |
| new Long(321), map.get("longProperty")); |
| assertEquals("Value of 'shortProperty'", |
| new Short((short) 987), map.get("shortProperty")); |
| assertEquals("Value of 'stringProperty'", |
| "This is a string", |
| (String) map.get("stringProperty")); |
| |
| } |
| |
| /** |
| * Corner cases on getPropertyDescriptor invalid arguments. |
| */ |
| public void testGetDescriptorArguments() { |
| |
| try { |
| PropertyUtils.getPropertyDescriptor(null, "stringProperty"); |
| fail("Should throw IllegalArgumentException 1"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 1"); |
| } |
| |
| try { |
| PropertyUtils.getPropertyDescriptor(bean, null); |
| fail("Should throw IllegalArgumentException 2"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 2"); |
| } |
| |
| } |
| |
| /** |
| * Positive getPropertyDescriptor on property {@code booleanProperty}. |
| */ |
| public void testGetDescriptorBoolean() { |
| |
| testGetDescriptorBase("booleanProperty", "getBooleanProperty", |
| "setBooleanProperty"); |
| |
| } |
| |
| /** |
| * Positive getPropertyDescriptor on property {@code doubleProperty}. |
| */ |
| public void testGetDescriptorDouble() { |
| |
| testGetDescriptorBase("doubleProperty", "getDoubleProperty", |
| "setDoubleProperty"); |
| |
| } |
| |
| /** |
| * Positive getPropertyDescriptor on property {@code floatProperty}. |
| */ |
| public void testGetDescriptorFloat() { |
| |
| testGetDescriptorBase("floatProperty", "getFloatProperty", |
| "setFloatProperty"); |
| |
| } |
| |
| /** |
| * Positive getPropertyDescriptor on property {@code intProperty}. |
| */ |
| public void testGetDescriptorInt() { |
| |
| testGetDescriptorBase("intProperty", "getIntProperty", |
| "setIntProperty"); |
| |
| } |
| |
| /** |
| * <p>Negative tests on an invalid property with two different boolean |
| * getters (which is fine, according to the JavaBeans spec) but a |
| * String setter instead of a boolean setter.</p> |
| * |
| * <p>Although one could logically argue that this combination of method |
| * signatures should not identify a property at all, there is a sentence |
| * in Section 8.3.1 making it clear that the behavior tested for here |
| * is correct: "If we find only one of these methods, then we regard |
| * it as defining either a read-only or write-only property called |
| * <em><property-name></em>.</p> |
| */ |
| public void testGetDescriptorInvalidBoolean() throws Exception { |
| |
| final PropertyDescriptor pd = |
| PropertyUtils.getPropertyDescriptor(bean, "invalidBoolean"); |
| assertNotNull("invalidBoolean is a property", pd); |
| assertNotNull("invalidBoolean has a getter method", |
| pd.getReadMethod()); |
| assertNull("invalidBoolean has no write method", |
| pd.getWriteMethod()); |
| assertTrue("invalidBoolean getter method is isInvalidBoolean or getInvalidBoolean", |
| Arrays.asList("isInvalidBoolean", "getInvalidBoolean") |
| .contains(pd.getReadMethod().getName())); |
| } |
| |
| /** |
| * Positive getPropertyDescriptor on property {@code longProperty}. |
| */ |
| public void testGetDescriptorLong() { |
| |
| testGetDescriptorBase("longProperty", "getLongProperty", |
| "setLongProperty"); |
| |
| } |
| |
| /** |
| * Test getting mapped descriptor with periods in the key. |
| */ |
| public void testGetDescriptorMappedPeriods() { |
| |
| bean.getMappedIntProperty("xyz"); // initializes mappedIntProperty |
| |
| PropertyDescriptor desc; |
| final Integer testIntegerValue = new Integer(1234); |
| |
| bean.setMappedIntProperty("key.with.a.dot", testIntegerValue.intValue()); |
| assertEquals("Can retrieve directly", |
| testIntegerValue, |
| new Integer(bean.getMappedIntProperty("key.with.a.dot"))); |
| try { |
| desc = PropertyUtils.getPropertyDescriptor |
| (bean, "mappedIntProperty(key.with.a.dot)"); |
| assertEquals("Check descriptor type (A)", |
| Integer.TYPE, |
| ((MappedPropertyDescriptor)desc).getMappedPropertyType()); |
| } catch (final Exception e) { |
| fail("Threw exception (A): " + e); |
| } |
| |
| bean.setMappedObjects("nested.property", new TestBean(testIntegerValue.intValue())); |
| assertEquals("Can retrieve directly", |
| testIntegerValue, |
| new Integer(((TestBean)bean.getMappedObjects("nested.property")).getIntProperty())); |
| try { |
| desc = PropertyUtils.getPropertyDescriptor |
| (bean, "mappedObjects(nested.property).intProperty"); |
| assertEquals("Check descriptor type (B)", |
| Integer.TYPE, |
| desc.getPropertyType()); |
| } catch (final Exception e) { |
| fail("Threw exception (B): " + e); |
| } |
| } |
| |
| /** |
| * Positive getPropertyDescriptor on property |
| * {@code readOnlyProperty}. |
| */ |
| public void testGetDescriptorReadOnly() { |
| |
| testGetDescriptorBase("readOnlyProperty", "getReadOnlyProperty", |
| null); |
| |
| } |
| |
| /** |
| * Positive getPropertyDescriptor on property {@code booleanSecond} |
| * that uses an "is" method as the getter. |
| */ |
| public void testGetDescriptorSecond() { |
| |
| testGetDescriptorBase("booleanSecond", "isBooleanSecond", |
| "setBooleanSecond"); |
| |
| } |
| |
| /** |
| * Positive getPropertyDescriptor on property {@code shortProperty}. |
| */ |
| public void testGetDescriptorShort() { |
| |
| testGetDescriptorBase("shortProperty", "getShortProperty", |
| "setShortProperty"); |
| |
| } |
| |
| /** |
| * Positive getPropertyDescriptor on property {@code stringProperty}. |
| */ |
| public void testGetDescriptorString() { |
| |
| testGetDescriptorBase("stringProperty", "getStringProperty", |
| "setStringProperty"); |
| |
| } |
| |
| /** |
| * Negative getPropertyDescriptor on property {@code unknown}. |
| */ |
| public void testGetDescriptorUnknown() { |
| |
| testGetDescriptorBase("unknown", null, null); |
| |
| } |
| |
| /** |
| * Positive getPropertyDescriptor on property |
| * {@code writeOnlyProperty}. |
| */ |
| public void testGetDescriptorWriteOnly() { |
| |
| testGetDescriptorBase("writeOnlyProperty", null, |
| "setWriteOnlyProperty"); |
| |
| } |
| |
| /** |
| * Positive test for getPropertyDescriptors(). Each property name |
| * listed in {@code properties} should be returned exactly once. |
| */ |
| public void testGetDescriptors() { |
| |
| final PropertyDescriptor[] pd = |
| PropertyUtils.getPropertyDescriptors(bean); |
| assertNotNull("Got descriptors", pd); |
| final int[] count = new int[properties.length]; |
| for (final PropertyDescriptor element : pd) { |
| final String name = element.getName(); |
| for (int j = 0; j < properties.length; j++) { |
| if (name.equals(properties[j])) { |
| count[j]++; |
| } |
| } |
| } |
| for (int j = 0; j < properties.length; j++) { |
| if (count[j] < 0) { |
| fail("Missing property " + properties[j]); |
| } else if (count[j] > 1) { |
| fail("Duplicate property " + properties[j]); |
| } |
| } |
| |
| } |
| |
| /** |
| * Corner cases on getPropertyDescriptors invalid arguments. |
| */ |
| public void testGetDescriptorsArguments() { |
| |
| try { |
| PropertyUtils.getPropertyDescriptors(null); |
| fail("Should throw IllegalArgumentException"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException"); |
| } |
| |
| } |
| |
| /** |
| * Corner cases on getIndexedProperty invalid arguments. |
| */ |
| public void testGetIndexedArguments() { |
| |
| // Use explicit index argument |
| |
| try { |
| PropertyUtils.getIndexedProperty(null, "intArray", 0); |
| fail("Should throw IllegalArgumentException 1"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 1"); |
| } |
| |
| try { |
| PropertyUtils.getIndexedProperty(bean, null, 0); |
| fail("Should throw IllegalArgumentException 2"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 2"); |
| } |
| |
| // Use index expression |
| |
| try { |
| PropertyUtils.getIndexedProperty(null, |
| "intArray[0]"); |
| fail("Should throw IllegalArgumentException 3"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 3"); |
| } |
| |
| try { |
| PropertyUtils.getIndexedProperty(bean, "[0]"); |
| fail("Should throw NoSuchMethodException 4"); |
| } catch (final NoSuchMethodException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of NoSuchMethodException 4"); |
| } |
| |
| try { |
| PropertyUtils.getIndexedProperty(bean, "intArray"); |
| fail("Should throw IllegalArgumentException 5"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 5"); |
| } |
| |
| // Use explicit index argument |
| |
| try { |
| PropertyUtils.getIndexedProperty(null, "intIndexed", 0); |
| fail("Should throw IllegalArgumentException 1"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 1"); |
| } |
| |
| try { |
| PropertyUtils.getIndexedProperty(bean, null, 0); |
| fail("Should throw IllegalArgumentException 2"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 2"); |
| } |
| |
| // Use index expression |
| |
| try { |
| PropertyUtils.getIndexedProperty(null, |
| "intIndexed[0]"); |
| fail("Should throw IllegalArgumentException 3"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 3"); |
| } |
| |
| try { |
| PropertyUtils.getIndexedProperty(bean, "[0]"); |
| fail("Should throw NoSuchMethodException 4"); |
| } catch (final NoSuchMethodException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of NoSuchMethodException 4"); |
| } |
| |
| try { |
| PropertyUtils.getIndexedProperty(bean, "intIndexed"); |
| fail("Should throw IllegalArgumentException 5"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 5"); |
| } |
| |
| } |
| |
| /** |
| * Positive and negative tests on getIndexedProperty valid arguments. |
| */ |
| public void testGetIndexedValues() { |
| |
| Object value = null; |
| |
| // Use explicit key argument |
| |
| for (int i = 0; i < 5; i++) { |
| |
| try { |
| value = PropertyUtils.getIndexedProperty |
| (bean, "dupProperty", i); |
| assertNotNull("dupProperty returned value " + i, value); |
| assertTrue("dupProperty returned String " + i, |
| value instanceof String); |
| assertEquals("dupProperty returned correct " + i, |
| "Dup " + i, |
| (String) value); |
| } catch (final Throwable t) { |
| fail("dupProperty " + i + " threw " + t); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, "intArray", i); |
| assertNotNull("intArray returned value " + i, value); |
| assertTrue("intArray returned Integer " + i, |
| value instanceof Integer); |
| assertEquals("intArray returned correct " + i, i * 10, |
| ((Integer) value).intValue()); |
| } catch (final Throwable t) { |
| fail("intArray " + i + " threw " + t); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, "intIndexed", i); |
| assertNotNull("intIndexed returned value " + i, value); |
| assertTrue("intIndexed returned Integer " + i, |
| value instanceof Integer); |
| assertEquals("intIndexed returned correct " + i, i * 10, |
| ((Integer) value).intValue()); |
| } catch (final Throwable t) { |
| fail("intIndexed " + i + " threw " + t); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, "listIndexed", i); |
| assertNotNull("listIndexed returned value " + i, value); |
| assertTrue("list returned String " + i, |
| value instanceof String); |
| assertEquals("listIndexed returned correct " + i, |
| "String " + i, (String) value); |
| } catch (final Throwable t) { |
| fail("listIndexed " + i + " threw " + t); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, "stringArray", i); |
| assertNotNull("stringArray returned value " + i, value); |
| assertTrue("stringArray returned String " + i, |
| value instanceof String); |
| assertEquals("stringArray returned correct " + i, |
| "String " + i, (String) value); |
| } catch (final Throwable t) { |
| fail("stringArray " + i + " threw " + t); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, "stringIndexed", i); |
| assertNotNull("stringIndexed returned value " + i, value); |
| assertTrue("stringIndexed returned String " + i, |
| value instanceof String); |
| assertEquals("stringIndexed returned correct " + i, |
| "String " + i, (String) value); |
| } catch (final Throwable t) { |
| fail("stringIndexed " + i + " threw " + t); |
| } |
| |
| } |
| |
| // Use key expression |
| |
| for (int i = 0; i < 5; i++) { |
| |
| try { |
| value = PropertyUtils.getIndexedProperty |
| (bean, "dupProperty[" + i + "]"); |
| assertNotNull("dupProperty returned value " + i, value); |
| assertTrue("dupProperty returned String " + i, |
| value instanceof String); |
| assertEquals("dupProperty returned correct " + i, |
| "Dup " + i, |
| (String) value); |
| } catch (final Throwable t) { |
| fail("dupProperty " + i + " threw " + t); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "intArray[" + i + "]"); |
| assertNotNull("intArray returned value " + i, value); |
| assertTrue("intArray returned Integer " + i, |
| value instanceof Integer); |
| assertEquals("intArray returned correct " + i, i * 10, |
| ((Integer) value).intValue()); |
| } catch (final Throwable t) { |
| fail("intArray " + i + " threw " + t); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "intIndexed[" + i + "]"); |
| assertNotNull("intIndexed returned value " + i, value); |
| assertTrue("intIndexed returned Integer " + i, |
| value instanceof Integer); |
| assertEquals("intIndexed returned correct " + i, i * 10, |
| ((Integer) value).intValue()); |
| } catch (final Throwable t) { |
| fail("intIndexed " + i + " threw " + t); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "listIndexed[" + i + "]"); |
| assertNotNull("listIndexed returned value " + i, value); |
| assertTrue("listIndexed returned String " + i, |
| value instanceof String); |
| assertEquals("listIndexed returned correct " + i, |
| "String " + i, (String) value); |
| } catch (final Throwable t) { |
| fail("listIndexed " + i + " threw " + t); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "stringArray[" + i + "]"); |
| assertNotNull("stringArray returned value " + i, value); |
| assertTrue("stringArray returned String " + i, |
| value instanceof String); |
| assertEquals("stringArray returned correct " + i, |
| "String " + i, (String) value); |
| } catch (final Throwable t) { |
| fail("stringArray " + i + " threw " + t); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "stringIndexed[" + i + "]"); |
| assertNotNull("stringIndexed returned value " + i, value); |
| assertTrue("stringIndexed returned String " + i, |
| value instanceof String); |
| assertEquals("stringIndexed returned correct " + i, |
| "String " + i, (String) value); |
| } catch (final Throwable t) { |
| fail("stringIndexed " + i + " threw " + t); |
| } |
| |
| } |
| |
| // Index out of bounds tests |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "dupProperty", -1); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "dupProperty", 5); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "intArray", -1); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "intArray", 5); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "intIndexed", -1); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "intIndexed", 5); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "listIndexed", -1); |
| fail("Should have thrown IndexOutOfBoundsException"); |
| } catch (final IndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IndexOutOfBoundsException"); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "listIndexed", 5); |
| fail("Should have thrown IndexOutOfBoundsException"); |
| } catch (final IndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IndexOutOfBoundsException"); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "stringArray", -1); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "stringArray", 5); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "stringIndexed", -1); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "stringIndexed", 5); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| } |
| |
| /** |
| * Test getting an indexed value out of a multi-dimensional array |
| */ |
| public void testGetIndexedArray() { |
| final String[] firstArray = new String[] {"FIRST-1", "FIRST-2", "FIRST-3"}; |
| final String[] secondArray = new String[] {"SECOND-1", "SECOND-2", "SECOND-3", "SECOND-4"}; |
| final String[][] mainArray = {firstArray, secondArray}; |
| final TestBean bean = new TestBean(mainArray); |
| try { |
| assertEquals("firstArray[0]", firstArray[0], PropertyUtils.getProperty(bean, "string2dArray[0][0]")); |
| assertEquals("firstArray[1]", firstArray[1], PropertyUtils.getProperty(bean, "string2dArray[0][1]")); |
| assertEquals("firstArray[2]", firstArray[2], PropertyUtils.getProperty(bean, "string2dArray[0][2]")); |
| assertEquals("secondArray[0]", secondArray[0], PropertyUtils.getProperty(bean, "string2dArray[1][0]")); |
| assertEquals("secondArray[1]", secondArray[1], PropertyUtils.getProperty(bean, "string2dArray[1][1]")); |
| assertEquals("secondArray[2]", secondArray[2], PropertyUtils.getProperty(bean, "string2dArray[1][2]")); |
| assertEquals("secondArray[3]", secondArray[3], PropertyUtils.getProperty(bean, "string2dArray[1][3]")); |
| } catch (final Throwable t) { |
| fail("Threw " + t + ""); |
| } |
| } |
| |
| /** |
| * Test getting an indexed value out of List of Lists |
| */ |
| public void testGetIndexedList() { |
| final String[] firstArray = new String[] {"FIRST-1", "FIRST-2", "FIRST-3"}; |
| final String[] secondArray = new String[] {"SECOND-1", "SECOND-2", "SECOND-3", "SECOND-4"}; |
| final List<Object> mainList = new ArrayList<>(); |
| mainList.add(Arrays.asList(firstArray)); |
| mainList.add(Arrays.asList(secondArray)); |
| final TestBean bean = new TestBean(mainList); |
| try { |
| assertEquals("firstArray[0]", firstArray[0], PropertyUtils.getProperty(bean, "listIndexed[0][0]")); |
| assertEquals("firstArray[1]", firstArray[1], PropertyUtils.getProperty(bean, "listIndexed[0][1]")); |
| assertEquals("firstArray[2]", firstArray[2], PropertyUtils.getProperty(bean, "listIndexed[0][2]")); |
| assertEquals("secondArray[0]", secondArray[0], PropertyUtils.getProperty(bean, "listIndexed[1][0]")); |
| assertEquals("secondArray[1]", secondArray[1], PropertyUtils.getProperty(bean, "listIndexed[1][1]")); |
| assertEquals("secondArray[2]", secondArray[2], PropertyUtils.getProperty(bean, "listIndexed[1][2]")); |
| assertEquals("secondArray[3]", secondArray[3], PropertyUtils.getProperty(bean, "listIndexed[1][3]")); |
| } catch (final Throwable t) { |
| fail("Threw " + t + ""); |
| } |
| } |
| |
| /** |
| * Test getting a value out of a mapped Map |
| */ |
| public void testGetIndexedMap() { |
| final Map<String, Object> firstMap = new HashMap<>(); |
| firstMap.put("FIRST-KEY-1", "FIRST-VALUE-1"); |
| firstMap.put("FIRST-KEY-2", "FIRST-VALUE-2"); |
| final Map<String, Object> secondMap = new HashMap<>(); |
| secondMap.put("SECOND-KEY-1", "SECOND-VALUE-1"); |
| secondMap.put("SECOND-KEY-2", "SECOND-VALUE-2"); |
| |
| final List<Object> mainList = new ArrayList<>(); |
| mainList.add(firstMap); |
| mainList.add(secondMap); |
| final TestBean bean = new TestBean(mainList); |
| try { |
| assertEquals("listIndexed[0](FIRST-KEY-1)", "FIRST-VALUE-1", PropertyUtils.getProperty(bean, "listIndexed[0](FIRST-KEY-1)")); |
| assertEquals("listIndexed[0](FIRST-KEY-2)", "FIRST-VALUE-2", PropertyUtils.getProperty(bean, "listIndexed[0](FIRST-KEY-2)")); |
| assertEquals("listIndexed[1](SECOND-KEY-1)", "SECOND-VALUE-1", PropertyUtils.getProperty(bean, "listIndexed[1](SECOND-KEY-1)")); |
| assertEquals("listIndexed[1](SECOND-KEY-2)", "SECOND-VALUE-2", PropertyUtils.getProperty(bean, "listIndexed[1](SECOND-KEY-2)")); |
| } catch (final Throwable t) { |
| fail("Threw " + t + ""); |
| } |
| } |
| |
| /** |
| * Corner cases on getMappedProperty invalid arguments. |
| */ |
| public void testGetMappedArguments() { |
| |
| // Use explicit key argument |
| |
| try { |
| PropertyUtils.getMappedProperty(null, "mappedProperty", |
| "First Key"); |
| fail("Should throw IllegalArgumentException 1"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 1"); |
| } |
| |
| try { |
| PropertyUtils.getMappedProperty(bean, null, "First Key"); |
| fail("Should throw IllegalArgumentException 2"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 2"); |
| } |
| |
| try { |
| PropertyUtils.getMappedProperty(bean, "mappedProperty", null); |
| fail("Should throw IllegalArgumentException 3"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 3"); |
| } |
| |
| // Use key expression |
| |
| try { |
| PropertyUtils.getMappedProperty(null, |
| "mappedProperty(First Key)"); |
| fail("Should throw IllegalArgumentException 4"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 4"); |
| } |
| |
| try { |
| PropertyUtils.getMappedProperty(bean, "(Second Key)"); |
| fail("Should throw IllegalArgumentException 5"); |
| } catch (final NoSuchMethodException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of NoSuchMethodException 5"); |
| } |
| |
| try { |
| PropertyUtils.getMappedProperty(bean, "mappedProperty"); |
| fail("Should throw IllegalArgumentException 6"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 6"); |
| } |
| |
| } |
| |
| /** |
| * Test getting an indexed value out of a mapped array |
| */ |
| public void testGetMappedArray() { |
| final TestBean bean = new TestBean(); |
| final String[] array = new String[] {"abc", "def", "ghi"}; |
| bean.getMapProperty().put("mappedArray", array); |
| try { |
| assertEquals("abc", PropertyUtils.getProperty(bean, "mapProperty(mappedArray)[0]")); |
| assertEquals("def", PropertyUtils.getProperty(bean, "mapProperty(mappedArray)[1]")); |
| assertEquals("ghi", PropertyUtils.getProperty(bean, "mapProperty(mappedArray)[2]")); |
| } catch (final Throwable t) { |
| fail("Threw " + t + ""); |
| } |
| } |
| |
| /** |
| * Test getting an indexed value out of a mapped List |
| */ |
| public void testGetMappedList() { |
| final TestBean bean = new TestBean(); |
| final List<Object> list = new ArrayList<>(); |
| list.add("klm"); |
| list.add("nop"); |
| list.add("qrs"); |
| bean.getMapProperty().put("mappedList", list); |
| try { |
| assertEquals("klm", PropertyUtils.getProperty(bean, "mapProperty(mappedList)[0]")); |
| assertEquals("nop", PropertyUtils.getProperty(bean, "mapProperty(mappedList)[1]")); |
| assertEquals("qrs", PropertyUtils.getProperty(bean, "mapProperty(mappedList)[2]")); |
| } catch (final Throwable t) { |
| fail("Threw " + t + ""); |
| } |
| } |
| |
| /** |
| * Test getting a value out of a mapped Map |
| */ |
| public void testGetMappedMap() { |
| final TestBean bean = new TestBean(); |
| final Map<String, Object> map = new HashMap<>(); |
| map.put("sub-key-1", "sub-value-1"); |
| map.put("sub-key-2", "sub-value-2"); |
| map.put("sub-key-3", "sub-value-3"); |
| bean.getMapProperty().put("mappedMap", map); |
| try { |
| assertEquals("sub-value-1", PropertyUtils.getProperty(bean, "mapProperty(mappedMap)(sub-key-1)")); |
| assertEquals("sub-value-2", PropertyUtils.getProperty(bean, "mapProperty(mappedMap)(sub-key-2)")); |
| assertEquals("sub-value-3", PropertyUtils.getProperty(bean, "mapProperty(mappedMap)(sub-key-3)")); |
| } catch (final Throwable t) { |
| fail("Threw " + t + ""); |
| } |
| } |
| |
| /** |
| * Test getting mapped values with periods in the key. |
| */ |
| public void testGetMappedPeriods() { |
| |
| bean.setMappedProperty("key.with.a.dot", "Special Value"); |
| assertEquals("Can retrieve directly", |
| "Special Value", |
| bean.getMappedProperty("key.with.a.dot")); |
| try { |
| assertEquals("Can retrieve via getMappedProperty", |
| "Special Value", |
| PropertyUtils.getMappedProperty |
| (bean, "mappedProperty", "key.with.a.dot")); |
| } catch (final Exception e) { |
| fail("Thew exception: " + e); |
| } |
| try { |
| assertEquals("Can retrieve via getNestedProperty", |
| "Special Value", |
| PropertyUtils.getNestedProperty |
| (bean, "mappedProperty(key.with.a.dot)")); |
| } catch (final Exception e) { |
| fail("Thew exception: " + e); |
| } |
| |
| bean.setMappedObjects("nested.property", new TestBean()); |
| assertNotNull("Can retrieve directly", |
| bean.getMappedObjects("nested.property")); |
| try { |
| assertEquals("Can retrieve nested", |
| "This is a string", |
| PropertyUtils.getNestedProperty |
| (bean, |
| "mappedObjects(nested.property).stringProperty")); |
| } catch (final Exception e) { |
| fail("Thew exception: " + e); |
| } |
| |
| try |
| { |
| assertEquals("Can't retrieved nested with mapped property", |
| "Mapped Value", |
| PropertyUtils.getNestedProperty( |
| bean,"mappedNested.value(Mapped Key)")); |
| } catch (final Exception e) |
| { |
| fail("Thew exception: " + e); |
| } |
| } |
| |
| /** |
| * Test getting mapped values with slashes in the key. This is different |
| * from periods because slashes are not syntactically significant. |
| */ |
| public void testGetMappedSlashes() { |
| |
| bean.setMappedProperty("key/with/a/slash", "Special Value"); |
| assertEquals("Can retrieve directly", |
| "Special Value", |
| bean.getMappedProperty("key/with/a/slash")); |
| try { |
| assertEquals("Can retrieve via getMappedProperty", |
| "Special Value", |
| PropertyUtils.getMappedProperty |
| (bean, "mappedProperty", "key/with/a/slash")); |
| } catch (final Exception e) { |
| fail("Thew exception: " + e); |
| } |
| try { |
| assertEquals("Can retrieve via getNestedProperty", |
| "Special Value", |
| PropertyUtils.getNestedProperty |
| (bean, "mappedProperty(key/with/a/slash)")); |
| } catch (final Exception e) { |
| fail("Thew exception: " + e); |
| } |
| |
| bean.setMappedObjects("nested/property", new TestBean()); |
| assertNotNull("Can retrieve directly", |
| bean.getMappedObjects("nested/property")); |
| try { |
| assertEquals("Can retrieve nested", |
| "This is a string", |
| PropertyUtils.getNestedProperty |
| (bean, |
| "mappedObjects(nested/property).stringProperty")); |
| } catch (final Exception e) { |
| fail("Thew exception: " + e); |
| } |
| |
| } |
| |
| /** |
| * Positive and negative tests on getMappedProperty valid arguments. |
| */ |
| public void testGetMappedValues() { |
| |
| Object value = null; |
| |
| // Use explicit key argument |
| |
| try { |
| value = PropertyUtils.getMappedProperty(bean, "mappedProperty", |
| "First Key"); |
| assertEquals("Can find first value", "First Value", value); |
| } catch (final Throwable t) { |
| fail("Finding first value threw " + t); |
| } |
| |
| try { |
| value = PropertyUtils.getMappedProperty(bean, "mappedProperty", |
| "Second Key"); |
| assertEquals("Can find second value", "Second Value", value); |
| } catch (final Throwable t) { |
| fail("Finding second value threw " + t); |
| } |
| |
| try { |
| value = PropertyUtils.getMappedProperty(bean, "mappedProperty", |
| "Third Key"); |
| assertNull("Can not find third value", value); |
| } catch (final Throwable t) { |
| fail("Finding third value threw " + t); |
| } |
| |
| // Use key expression with parentheses |
| |
| try { |
| value = |
| PropertyUtils.getMappedProperty(bean, |
| "mappedProperty(First Key)"); |
| assertEquals("Can find first value", "First Value", value); |
| } catch (final Throwable t) { |
| fail("Finding first value threw " + t); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getMappedProperty(bean, |
| "mappedProperty(Second Key)"); |
| assertEquals("Can find second value", "Second Value", value); |
| } catch (final Throwable t) { |
| fail("Finding second value threw " + t); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getMappedProperty(bean, |
| "mappedProperty(Third Key)"); |
| assertNull("Can not find third value", value); |
| } catch (final Throwable t) { |
| fail("Finding third value threw " + t); |
| } |
| |
| // Use key expression with dotted syntax |
| |
| try { |
| value = |
| PropertyUtils.getNestedProperty(bean, |
| "mapProperty.First Key"); |
| assertEquals("Can find first value", "First Value", value); |
| } catch (final Throwable t) { |
| fail("Finding first value threw " + t); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getNestedProperty(bean, |
| "mapProperty.Second Key"); |
| assertEquals("Can find second value", "Second Value", value); |
| } catch (final Throwable t) { |
| fail("Finding second value threw " + t); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getNestedProperty(bean, |
| "mapProperty.Third Key"); |
| assertNull("Can not find third value", value); |
| } catch (final Throwable t) { |
| fail("Finding third value threw " + t); |
| } |
| |
| } |
| |
| /** |
| * Corner cases on getNestedProperty invalid arguments. |
| */ |
| public void testGetNestedArguments() { |
| |
| try { |
| PropertyUtils.getNestedProperty(null, "stringProperty"); |
| fail("Should throw IllegalArgumentException 1"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 1"); |
| } |
| |
| try { |
| PropertyUtils.getNestedProperty(bean, null); |
| fail("Should throw IllegalArgumentException 2"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 2"); |
| } |
| |
| } |
| |
| /** |
| * Test getNestedProperty on a boolean property. |
| */ |
| public void testGetNestedBoolean() { |
| |
| try { |
| final Object value = |
| PropertyUtils.getNestedProperty |
| (bean, "nested.booleanProperty"); |
| assertNotNull("Got a value", value); |
| assertTrue("Got correct type", value instanceof Boolean); |
| assertTrue("Got correct value", |
| ((Boolean) value).booleanValue() == |
| bean.getNested().getBooleanProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test getNestedProperty on a double property. |
| */ |
| public void testGetNestedDouble() { |
| |
| try { |
| final Object value = |
| PropertyUtils.getNestedProperty |
| (bean, "nested.doubleProperty"); |
| assertNotNull("Got a value", value); |
| assertTrue("Got correct type", value instanceof Double); |
| assertEquals("Got correct value", |
| ((Double) value).doubleValue(), |
| bean.getNested().getDoubleProperty(), |
| 0.005); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test getNestedProperty on a float property. |
| */ |
| public void testGetNestedFloat() { |
| |
| try { |
| final Object value = |
| PropertyUtils.getNestedProperty |
| (bean, "nested.floatProperty"); |
| assertNotNull("Got a value", value); |
| assertTrue("Got correct type", value instanceof Float); |
| assertEquals("Got correct value", |
| ((Float) value).floatValue(), |
| bean.getNested().getFloatProperty(), |
| (float) 0.005); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test getNestedProperty on an int property. |
| */ |
| public void testGetNestedInt() { |
| |
| try { |
| final Object value = |
| PropertyUtils.getNestedProperty |
| (bean, "nested.intProperty"); |
| assertNotNull("Got a value", value); |
| assertTrue("Got correct type", value instanceof Integer); |
| assertEquals("Got correct value", |
| ((Integer) value).intValue(), |
| bean.getNested().getIntProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test getNestedProperty on a long property. |
| */ |
| public void testGetNestedLong() { |
| |
| try { |
| final Object value = |
| PropertyUtils.getNestedProperty |
| (bean, "nested.longProperty"); |
| assertNotNull("Got a value", value); |
| assertTrue("Got correct type", value instanceof Long); |
| assertEquals("Got correct value", |
| ((Long) value).longValue(), |
| bean.getNested().getLongProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test getNestedProperty on a read-only String property. |
| */ |
| public void testGetNestedReadOnly() { |
| |
| try { |
| final Object value = |
| PropertyUtils.getNestedProperty |
| (bean, "nested.readOnlyProperty"); |
| assertNotNull("Got a value", value); |
| assertTrue("Got correct type", value instanceof String); |
| assertEquals("Got correct value", |
| (String) value, |
| bean.getReadOnlyProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test getNestedProperty on a short property. |
| */ |
| public void testGetNestedShort() { |
| |
| try { |
| final Object value = |
| PropertyUtils.getNestedProperty |
| (bean, "nested.shortProperty"); |
| assertNotNull("Got a value", value); |
| assertTrue("Got correct type", value instanceof Short); |
| assertEquals("Got correct value", |
| ((Short) value).shortValue(), |
| bean.getNested().getShortProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test getNestedProperty on a String property. |
| */ |
| public void testGetNestedString() { |
| |
| try { |
| final Object value = |
| PropertyUtils.getNestedProperty |
| (bean, "nested.stringProperty"); |
| assertNotNull("Got a value", value); |
| assertTrue("Got correct type", value instanceof String); |
| assertEquals("Got correct value", |
| (String) value, |
| bean.getNested().getStringProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Negative test getNestedProperty on an unknown property. |
| */ |
| public void testGetNestedUnknown() { |
| |
| try { |
| PropertyUtils.getNestedProperty(bean, "nested.unknown"); |
| fail("Should have thrown NoSuchMethodException"); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| // Correct result for this test |
| } |
| |
| } |
| |
| /** |
| * When a bean has a null property which is reference by the standard access language, |
| * this should throw a NestedNullException. |
| */ |
| public void testThrowNestedNull() throws Exception { |
| final NestedTestBean nestedBean = new NestedTestBean("base"); |
| // don't init! |
| |
| try { |
| PropertyUtils.getProperty( |
| nestedBean, |
| "simpleBeanProperty.indexedProperty[0]"); |
| fail("NestedNullException not thrown"); |
| } catch (final NestedNullException e) { |
| // that's what we wanted! |
| } |
| } |
| |
| /** |
| * Test getNestedProperty on a write-only String property. |
| */ |
| public void testGetNestedWriteOnly() { |
| |
| try { |
| PropertyUtils.getNestedProperty(bean, "writeOnlyProperty"); |
| fail("Should have thrown NoSuchMethodException"); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| // Correct result for this test |
| } |
| |
| } |
| |
| /** |
| * Test getPropertyType() on all kinds of properties. |
| */ |
| public void testGetPropertyType() { |
| |
| Class<?> clazz = null; |
| final int[] intArray = new int[0]; |
| final String[] stringArray = new String[0]; |
| |
| try { |
| |
| // Scalar and Indexed Properties |
| clazz = PropertyUtils.getPropertyType(bean, "booleanProperty"); |
| assertEquals("booleanProperty type", Boolean.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "booleanSecond"); |
| assertEquals("booleanSecond type", Boolean.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "doubleProperty"); |
| assertEquals("doubleProperty type", Double.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "dupProperty"); |
| assertEquals("dupProperty type", String.class, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "floatProperty"); |
| assertEquals("floatProperty type", Float.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "intArray"); |
| assertEquals("intArray type", intArray.getClass(), clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "intIndexed"); |
| assertEquals("intIndexed type", Integer.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "intProperty"); |
| assertEquals("intProperty type", Integer.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "listIndexed"); |
| assertEquals("listIndexed type", List.class, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "longProperty"); |
| assertEquals("longProperty type", Long.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "mappedProperty"); |
| assertEquals("mappedProperty type", String.class, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "mappedIntProperty"); |
| assertEquals("mappedIntProperty type", Integer.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "readOnlyProperty"); |
| assertEquals("readOnlyProperty type", String.class, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "shortProperty"); |
| assertEquals("shortProperty type", Short.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "stringArray"); |
| assertEquals("stringArray type", stringArray.getClass(), clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "stringIndexed"); |
| assertEquals("stringIndexed type", String.class, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "stringProperty"); |
| assertEquals("stringProperty type", String.class, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "writeOnlyProperty"); |
| assertEquals("writeOnlyProperty type", String.class, clazz); |
| |
| // Nested Properties |
| clazz = PropertyUtils.getPropertyType(bean, "nested.booleanProperty"); |
| assertEquals("booleanProperty type", Boolean.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nested.booleanSecond"); |
| assertEquals("booleanSecond type", Boolean.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nested.doubleProperty"); |
| assertEquals("doubleProperty type", Double.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nested.dupProperty"); |
| assertEquals("dupProperty type", String.class, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nested.floatProperty"); |
| assertEquals("floatProperty type", Float.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nested.intArray"); |
| assertEquals("intArray type", intArray.getClass(), clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nested.intIndexed"); |
| assertEquals("intIndexed type", Integer.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nested.intProperty"); |
| assertEquals("intProperty type", Integer.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nested.listIndexed"); |
| assertEquals("listIndexed type", List.class, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nested.longProperty"); |
| assertEquals("longProperty type", Long.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nested.mappedProperty"); |
| assertEquals("mappedProperty type", String.class, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nested.mappedIntProperty"); |
| assertEquals("mappedIntProperty type", Integer.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nested.readOnlyProperty"); |
| assertEquals("readOnlyProperty type", String.class, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nested.shortProperty"); |
| assertEquals("shortProperty type", Short.TYPE, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nested.stringArray"); |
| assertEquals("stringArray type", stringArray.getClass(), clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nested.stringIndexed"); |
| assertEquals("stringIndexed type", String.class, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nested.stringProperty"); |
| assertEquals("stringProperty type", String.class, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nested.writeOnlyProperty"); |
| assertEquals("writeOnlyProperty type", String.class, clazz); |
| |
| // Nested DynaBean |
| clazz = PropertyUtils.getPropertyType(bean, "nestedDynaBean"); |
| assertEquals("nestedDynaBean type", DynaBean.class, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nestedDynaBean.stringProperty"); |
| assertEquals("nestedDynaBean.stringProperty type", String.class, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nestedDynaBean.nestedBean"); |
| assertEquals("nestedDynaBean.nestedBean type", TestBean.class, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nestedDynaBean.nestedBean.nestedDynaBean"); |
| assertEquals("nestedDynaBean.nestedBean.nestedDynaBean type", DynaBean.class, clazz); |
| clazz = PropertyUtils.getPropertyType(bean, "nestedDynaBean.nestedBean.nestedDynaBean.stringProperty"); |
| assertEquals("nestedDynaBean.nestedBean.nestedDynaBean.stringPropert type", String.class, clazz); |
| |
| // test Null |
| clazz = PropertyUtils.getPropertyType(bean, "nestedDynaBean.nullDynaBean"); |
| assertEquals("nestedDynaBean.nullDynaBean type", DynaBean.class, clazz); |
| try { |
| clazz = PropertyUtils.getPropertyType(bean, "nestedDynaBean.nullDynaBean.foo"); |
| fail("Expected NestedNullException for nestedDynaBean.nullDynaBean.foo"); |
| } catch (final NestedNullException e) { |
| // expected |
| } |
| |
| } catch (final Exception e) { |
| fail("Exception: " + e.getMessage()); |
| } |
| |
| } |
| |
| /** |
| * Test accessing a public sub-bean of a package scope bean |
| */ |
| public void testGetPublicSubBean_of_PackageBean() { |
| |
| final PublicSubBean bean = new PublicSubBean(); |
| bean.setFoo("foo-start"); |
| bean.setBar("bar-start"); |
| Object result = null; |
| |
| // Get Foo |
| try { |
| result = PropertyUtils.getProperty(bean, "foo"); |
| } catch (final Throwable t) { |
| fail("getProperty(foo) threw " + t); |
| } |
| assertEquals("foo property", "foo-start", result); |
| |
| // Get Bar |
| try { |
| result = PropertyUtils.getProperty(bean, "bar"); |
| } catch (final Throwable t) { |
| fail("getProperty(bar) threw " + t); |
| } |
| assertEquals("bar property", "bar-start", result); |
| } |
| |
| /** |
| * Test getting accessible property reader methods for a specified |
| * list of properties of our standard test bean. |
| */ |
| public void testGetReadMethodBasic() { |
| |
| testGetReadMethod(bean, properties, TEST_BEAN_CLASS); |
| |
| } |
| |
| /** |
| * Test getting accessible property reader methods for a specified |
| * list of properties of a package private subclass of our standard |
| * test bean. |
| */ |
| public void testGetReadMethodPackageSubclass() { |
| |
| testGetReadMethod(beanPackageSubclass, properties, TEST_BEAN_CLASS); |
| |
| } |
| |
| /** |
| * Test getting accessible property reader methods for a specified |
| * list of properties that are declared either directly or via |
| * implemented interfaces. |
| */ |
| public void testGetReadMethodPublicInterface() { |
| |
| // Properties "bar" and "baz" are visible via implemented interfaces |
| // (one direct and one indirect) |
| testGetReadMethod(beanPrivate, |
| new String[]{ "bar" }, |
| PRIVATE_DIRECT_CLASS); |
| testGetReadMethod(beanPrivate, |
| new String[]{ "baz" }, |
| PRIVATE_INDIRECT_CLASS); |
| |
| // Properties "bar" and "baz" are visible via implemented interfaces |
| // (one direct and one indirect). The interface is implemented in |
| // a superclass |
| testGetReadMethod(beanPrivateSubclass, |
| new String[]{ "bar" }, |
| PRIVATE_DIRECT_CLASS); |
| testGetReadMethod(beanPrivateSubclass, |
| new String[]{ "baz" }, |
| PRIVATE_INDIRECT_CLASS); |
| |
| // Property "foo" is not accessible because the underlying |
| // class has package scope |
| final PropertyDescriptor[] pd = |
| PropertyUtils.getPropertyDescriptors(beanPrivate); |
| int n = -1; |
| for (int i = 0; i < pd.length; i++) { |
| if ("foo".equals(pd[i].getName())) { |
| n = i; |
| break; |
| } |
| } |
| assertTrue("Found foo descriptor", n >= 0); |
| final Method reader = pd[n].getReadMethod(); |
| assertNotNull("Found foo read method", reader); |
| try { |
| reader.invoke(beanPrivate, (Object[]) new Class<?>[0]); |
| fail("Foo reader did throw IllegalAccessException"); |
| } catch (final IllegalAccessException e) { |
| // Expected result for this test |
| } catch (final Throwable t) { |
| fail("Invoke foo reader: " + t); |
| } |
| |
| } |
| |
| /** |
| * Test getting accessible property reader methods for a specified |
| * list of properties of a public subclass of our standard test bean. |
| */ |
| public void testGetReadMethodPublicSubclass() { |
| |
| testGetReadMethod(beanPublicSubclass, properties, TEST_BEAN_CLASS); |
| |
| } |
| |
| /** |
| * Corner cases on getSimpleProperty invalid arguments. |
| */ |
| public void testGetSimpleArguments() { |
| |
| try { |
| PropertyUtils.getSimpleProperty(null, "stringProperty"); |
| fail("Should throw IllegalArgumentException 1"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 1"); |
| } |
| |
| try { |
| PropertyUtils.getSimpleProperty(bean, null); |
| fail("Should throw IllegalArgumentException 2"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 2"); |
| } |
| |
| } |
| |
| /** |
| * Test getSimpleProperty on a boolean property. |
| */ |
| public void testGetSimpleBoolean() { |
| |
| try { |
| final Object value = |
| PropertyUtils.getSimpleProperty(bean, |
| "booleanProperty"); |
| assertNotNull("Got a value", value); |
| assertTrue("Got correct type", value instanceof Boolean); |
| assertTrue("Got correct value", |
| ((Boolean) value).booleanValue() == |
| bean.getBooleanProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test getSimpleProperty on a double property. |
| */ |
| public void testGetSimpleDouble() { |
| |
| try { |
| final Object value = |
| PropertyUtils.getSimpleProperty(bean, |
| "doubleProperty"); |
| assertNotNull("Got a value", value); |
| assertTrue("Got correct type", value instanceof Double); |
| assertEquals("Got correct value", |
| ((Double) value).doubleValue(), |
| bean.getDoubleProperty(), 0.005); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test getSimpleProperty on a float property. |
| */ |
| public void testGetSimpleFloat() { |
| |
| try { |
| final Object value = |
| PropertyUtils.getSimpleProperty(bean, |
| "floatProperty"); |
| assertNotNull("Got a value", value); |
| assertTrue("Got correct type", value instanceof Float); |
| assertEquals("Got correct value", |
| ((Float) value).floatValue(), |
| bean.getFloatProperty(), |
| (float) 0.005); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Negative test getSimpleProperty on an indexed property. |
| */ |
| public void testGetSimpleIndexed() { |
| |
| try { |
| PropertyUtils.getSimpleProperty(bean, |
| "intIndexed[0]"); |
| fail("Should have thrown IllegalArgumentException"); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| // Correct result for this test |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test getSimpleProperty on an int property. |
| */ |
| public void testGetSimpleInt() { |
| |
| try { |
| final Object value = |
| PropertyUtils.getSimpleProperty(bean, |
| "intProperty"); |
| assertNotNull("Got a value", value); |
| assertTrue("Got correct type", value instanceof Integer); |
| assertEquals("Got correct value", |
| ((Integer) value).intValue(), |
| bean.getIntProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test getSimpleProperty on a long property. |
| */ |
| public void testGetSimpleLong() { |
| |
| try { |
| final Object value = |
| PropertyUtils.getSimpleProperty(bean, |
| "longProperty"); |
| assertNotNull("Got a value", value); |
| assertTrue("Got correct type", value instanceof Long); |
| assertEquals("Got correct value", |
| ((Long) value).longValue(), |
| bean.getLongProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Negative test getSimpleProperty on a nested property. |
| */ |
| public void testGetSimpleNested() { |
| |
| try { |
| PropertyUtils.getSimpleProperty(bean, |
| "nested.stringProperty"); |
| fail("Should have thrown IllegalArgumentException"); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| // Correct result for this test |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test getSimpleProperty on a read-only String property. |
| */ |
| public void testGetSimpleReadOnly() { |
| |
| try { |
| final Object value = |
| PropertyUtils.getSimpleProperty(bean, |
| "readOnlyProperty"); |
| assertNotNull("Got a value", value); |
| assertTrue("Got correct type", value instanceof String); |
| assertEquals("Got correct value", |
| (String) value, |
| bean.getReadOnlyProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test getSimpleProperty on a short property. |
| */ |
| public void testGetSimpleShort() { |
| |
| try { |
| final Object value = |
| PropertyUtils.getSimpleProperty(bean, |
| "shortProperty"); |
| assertNotNull("Got a value", value); |
| assertTrue("Got correct type", value instanceof Short); |
| assertEquals("Got correct value", |
| ((Short) value).shortValue(), |
| bean.getShortProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test getSimpleProperty on a String property. |
| */ |
| public void testGetSimpleString() { |
| |
| try { |
| final Object value = |
| PropertyUtils.getSimpleProperty(bean, |
| "stringProperty"); |
| assertNotNull("Got a value", value); |
| assertTrue("Got correct type", value instanceof String); |
| assertEquals("Got correct value", |
| (String) value, |
| bean.getStringProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Negative test getSimpleProperty on an unknown property. |
| */ |
| public void testGetSimpleUnknown() { |
| |
| try { |
| PropertyUtils.getSimpleProperty(bean, "unknown"); |
| fail("Should have thrown NoSuchMethodException"); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| // Correct result for this test |
| assertEquals("Unknown property 'unknown' on class '" + |
| bean.getClass() + "'", e.getMessage() ); |
| } |
| |
| } |
| |
| /** |
| * Test getSimpleProperty on a write-only String property. |
| */ |
| public void testGetSimpleWriteOnly() { |
| |
| try { |
| PropertyUtils.getSimpleProperty(bean, "writeOnlyProperty"); |
| fail("Should have thrown NoSuchMethodException"); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| // Correct result for this test |
| assertEquals("Property 'writeOnlyProperty' has no getter method in class '" + |
| bean.getClass() + "'", e.getMessage() ); |
| } |
| |
| } |
| |
| /** |
| * Test getting accessible property writer methods for a specified |
| * list of properties of our standard test bean. |
| */ |
| public void testGetWriteMethodBasic() { |
| |
| testGetWriteMethod(bean, properties, TEST_BEAN_CLASS); |
| |
| } |
| |
| /** |
| * Test getting accessible property writer methods for a specified |
| * list of properties of a package private subclass of our standard |
| * test bean. |
| */ |
| public void testGetWriteMethodPackageSubclass() { |
| |
| testGetWriteMethod(beanPackageSubclass, properties, TEST_BEAN_CLASS); |
| |
| } |
| |
| /** |
| * Test getting accessible property writer methods for a specified |
| * list of properties of a public subclass of our standard test bean. |
| */ |
| public void testGetWriteMethodPublicSubclass() { |
| |
| testGetWriteMethod(beanPublicSubclass, properties, TEST_BEAN_CLASS); |
| |
| } |
| |
| /** |
| * Test isReadable() method. |
| */ |
| public void testIsReadable() { |
| String property = null; |
| try { |
| property = "stringProperty"; |
| assertTrue("Property " + property +" isReadable expected TRUE", PropertyUtils.isReadable(bean, property)); |
| } catch (final Throwable t) { |
| fail("Property " + property +" isReadable Threw exception: " + t); |
| } |
| try { |
| property = "stringIndexed"; |
| assertTrue("Property " + property +" isReadable expected TRUE", PropertyUtils.isReadable(bean, property)); |
| } catch (final Throwable t) { |
| fail("Property " + property +" isReadable Threw exception: " + t); |
| } |
| try { |
| property = "mappedProperty"; |
| assertTrue("Property " + property +" isReadable expected TRUE", PropertyUtils.isReadable(bean, property)); |
| } catch (final Throwable t) { |
| fail("Property " + property +" isReadable Threw exception: " + t); |
| } |
| |
| try { |
| property = "nestedDynaBean"; |
| assertTrue("Property " + property +" isReadable expected TRUE", PropertyUtils.isReadable(bean, property)); |
| } catch (final Throwable t) { |
| fail("Property " + property +" isReadable Threw exception: " + t); |
| } |
| |
| try { |
| property = "nestedDynaBean.stringProperty"; |
| assertTrue("Property " + property +" isReadable expected TRUE", PropertyUtils.isReadable(bean, property)); |
| } catch (final Throwable t) { |
| fail("Property " + property +" isReadable Threw exception: " + t); |
| } |
| |
| try { |
| property = "nestedDynaBean.nestedBean"; |
| assertTrue("Property " + property +" isReadable expected TRUE", PropertyUtils.isReadable(bean, property)); |
| } catch (final Throwable t) { |
| fail("Property " + property +" isReadable Threw exception: " + t); |
| } |
| |
| try { |
| property = "nestedDynaBean.nestedBean.nestedDynaBean"; |
| assertTrue("Property " + property +" isReadable expected TRUE", PropertyUtils.isReadable(bean, property)); |
| } catch (final Throwable t) { |
| fail("Property " + property +" isReadable Threw exception: " + t); |
| } |
| |
| try { |
| property = "nestedDynaBean.nestedBean.nestedDynaBean.stringProperty"; |
| assertTrue("Property " + property +" isReadable expected TRUE", PropertyUtils.isReadable(bean, property)); |
| } catch (final Throwable t) { |
| fail("Property " + property +" isReadable Threw exception: " + t); |
| } |
| |
| try { |
| property = "nestedDynaBean.nullDynaBean"; |
| assertTrue("Property " + property +" isReadable expected TRUE", PropertyUtils.isReadable(bean, property)); |
| } catch (final Throwable t) { |
| fail("Property " + property +" isReadable Threw exception: " + t); |
| } |
| |
| try { |
| property = "nestedDynaBean.nullDynaBean.foo"; |
| assertTrue("Property " + property +" isReadable expected TRUE", PropertyUtils.isReadable(bean, property)); |
| fail("Property " + property +" isReadable expected NestedNullException"); |
| } catch (final NestedNullException e) { |
| // expected result |
| } catch (final Throwable t) { |
| fail("Property " + property +" isReadable Threw exception: " + t); |
| } |
| } |
| |
| /** |
| * Test isWriteable() method. |
| */ |
| public void testIsWriteable() { |
| String property = null; |
| try { |
| property = "stringProperty"; |
| assertTrue("Property " + property +" isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property)); |
| } catch (final Throwable t) { |
| fail("Property " + property +" isWriteable Threw exception: " + t); |
| } |
| try { |
| property = "stringIndexed"; |
| assertTrue("Property " + property +" isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property)); |
| } catch (final Throwable t) { |
| fail("Property " + property +" isWriteable Threw exception: " + t); |
| } |
| try { |
| property = "mappedProperty"; |
| assertTrue("Property " + property +" isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property)); |
| } catch (final Throwable t) { |
| fail("Property " + property +" isWriteable Threw exception: " + t); |
| } |
| |
| try { |
| property = "nestedDynaBean"; |
| assertTrue("Property " + property +" isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property)); |
| } catch (final Throwable t) { |
| fail("Property " + property +" isWriteable Threw exception: " + t); |
| } |
| |
| try { |
| property = "nestedDynaBean.stringProperty"; |
| assertTrue("Property " + property +" isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property)); |
| } catch (final Throwable t) { |
| t.printStackTrace(); |
| fail("Property " + property +" isWriteable Threw exception: " + t); |
| } |
| |
| try { |
| property = "nestedDynaBean.nestedBean"; |
| assertTrue("Property " + property +" isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property)); |
| } catch (final Throwable t) { |
| fail("Property " + property +" isWriteable Threw exception: " + t); |
| } |
| |
| try { |
| property = "nestedDynaBean.nestedBean.nestedDynaBean"; |
| assertTrue("Property " + property +" isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property)); |
| } catch (final Throwable t) { |
| fail("Property " + property +" isWriteable Threw exception: " + t); |
| } |
| |
| try { |
| property = "nestedDynaBean.nestedBean.nestedDynaBean.stringProperty"; |
| assertTrue("Property " + property +" isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property)); |
| } catch (final Throwable t) { |
| fail("Property " + property +" isWriteable Threw exception: " + t); |
| } |
| |
| try { |
| property = "nestedDynaBean.nullDynaBean"; |
| assertTrue("Property " + property +" isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property)); |
| } catch (final Throwable t) { |
| fail("Property " + property +" isWriteable Threw exception: " + t); |
| } |
| |
| try { |
| property = "nestedDynaBean.nullDynaBean.foo"; |
| assertTrue("Property " + property +" isWriteable expected TRUE", PropertyUtils.isWriteable(bean, property)); |
| fail("Property " + property +" isWriteable expected NestedNullException"); |
| } catch (final NestedNullException e) { |
| // expected result |
| } catch (final Throwable t) { |
| fail("Property " + property +" isWriteable Threw exception: " + t); |
| } |
| } |
| |
| /** |
| * Test the mappedPropertyType of MappedPropertyDescriptor. |
| */ |
| public void testMappedPropertyType() throws Exception { |
| |
| MappedPropertyDescriptor desc; |
| |
| // Check a String property |
| desc = (MappedPropertyDescriptor) |
| PropertyUtils.getPropertyDescriptor(bean, |
| "mappedProperty"); |
| assertEquals(String.class, desc.getMappedPropertyType()); |
| |
| // Check an int property |
| desc = (MappedPropertyDescriptor) |
| PropertyUtils.getPropertyDescriptor(bean, |
| "mappedIntProperty"); |
| assertEquals(Integer.TYPE, desc.getMappedPropertyType()); |
| |
| } |
| |
| /** |
| * Corner cases on setIndexedProperty invalid arguments. |
| */ |
| public void testSetIndexedArguments() { |
| |
| // Use explicit index argument |
| |
| try { |
| PropertyUtils.setIndexedProperty(null, "intArray", 0, |
| new Integer(1)); |
| fail("Should throw IllegalArgumentException 1"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 1"); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, null, 0, |
| new Integer(1)); |
| fail("Should throw IllegalArgumentException 2"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 2"); |
| } |
| |
| // Use index expression |
| |
| try { |
| PropertyUtils.setIndexedProperty(null, |
| "intArray[0]", |
| new Integer(1)); |
| fail("Should throw IllegalArgumentException 3"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 3"); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, "[0]", |
| new Integer(1)); |
| fail("Should throw NoSuchMethodException 4"); |
| } catch (final NoSuchMethodException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of NoSuchMethodException 4"); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, "intArray", |
| new Integer(1)); |
| fail("Should throw IllegalArgumentException 5"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 5"); |
| } |
| |
| // Use explicit index argument |
| |
| try { |
| PropertyUtils.setIndexedProperty(null, "intIndexed", 0, |
| new Integer(1)); |
| fail("Should throw IllegalArgumentException 1"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 1"); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, null, 0, |
| new Integer(1)); |
| fail("Should throw IllegalArgumentException 2"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 2"); |
| } |
| |
| // Use index expression |
| |
| try { |
| PropertyUtils.setIndexedProperty(null, |
| "intIndexed[0]", |
| new Integer(1)); |
| fail("Should throw IllegalArgumentException 3"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 3"); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, "[0]", |
| new Integer(1)); |
| fail("Should throw NoSuchMethodException 4"); |
| } catch (final NoSuchMethodException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of NoSuchMethodException 4"); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, "intIndexed", |
| new Integer(1)); |
| fail("Should throw IllegalArgumentException 5"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 5"); |
| } |
| |
| } |
| |
| /** |
| * Test setting an indexed value out of a multi-dimensional array |
| */ |
| public void testSetIndexedArray() { |
| final String[] firstArray = new String[] {"FIRST-1", "FIRST-2", "FIRST-3"}; |
| final String[] secondArray = new String[] {"SECOND-1", "SECOND-2", "SECOND-3", "SECOND-4"}; |
| final String[][] mainArray = {firstArray, secondArray}; |
| final TestBean bean = new TestBean(mainArray); |
| assertEquals("BEFORE", "SECOND-3", bean.getString2dArray(1)[2]); |
| try { |
| PropertyUtils.setProperty(bean, "string2dArray[1][2]", "SECOND-3-UPDATED"); |
| } catch (final Throwable t) { |
| fail("Threw " + t + ""); |
| } |
| assertEquals("AFTER", "SECOND-3-UPDATED", bean.getString2dArray(1)[2]); |
| } |
| |
| /** |
| * Test setting an indexed value out of List of Lists |
| */ |
| public void testSetIndexedList() { |
| final String[] firstArray = new String[] {"FIRST-1", "FIRST-2", "FIRST-3"}; |
| final String[] secondArray = new String[] {"SECOND-1", "SECOND-2", "SECOND-3", "SECOND-4"}; |
| final List<Object> mainList = new ArrayList<>(); |
| mainList.add(Arrays.asList(firstArray)); |
| mainList.add(Arrays.asList(secondArray)); |
| final TestBean bean = new TestBean(mainList); |
| assertEquals("BEFORE", "SECOND-4", ((List<?>)bean.getListIndexed().get(1)).get(3)); |
| try { |
| PropertyUtils.setProperty(bean, "listIndexed[1][3]", "SECOND-4-UPDATED"); |
| } catch (final Throwable t) { |
| fail("Threw " + t + ""); |
| } |
| assertEquals("AFTER", "SECOND-4-UPDATED", ((List<?>)bean.getListIndexed().get(1)).get(3)); |
| } |
| |
| /** |
| * Test setting a value out of a mapped Map |
| */ |
| public void testSetIndexedMap() { |
| final Map<String, Object> firstMap = new HashMap<>(); |
| firstMap.put("FIRST-KEY-1", "FIRST-VALUE-1"); |
| firstMap.put("FIRST-KEY-2", "FIRST-VALUE-2"); |
| final Map<String, Object> secondMap = new HashMap<>(); |
| secondMap.put("SECOND-KEY-1", "SECOND-VALUE-1"); |
| secondMap.put("SECOND-KEY-2", "SECOND-VALUE-2"); |
| |
| final List<Object> mainList = new ArrayList<>(); |
| mainList.add(firstMap); |
| mainList.add(secondMap); |
| final TestBean bean = new TestBean(mainList); |
| |
| assertEquals("BEFORE", null, ((Map<?, ?>)bean.getListIndexed().get(0)).get("FIRST-NEW-KEY")); |
| assertEquals("BEFORE", "SECOND-VALUE-1", ((Map<?, ?>)bean.getListIndexed().get(1)).get("SECOND-KEY-1")); |
| try { |
| PropertyUtils.setProperty(bean, "listIndexed[0](FIRST-NEW-KEY)", "FIRST-NEW-VALUE"); |
| PropertyUtils.setProperty(bean, "listIndexed[1](SECOND-KEY-1)", "SECOND-VALUE-1-UPDATED"); |
| } catch (final Throwable t) { |
| fail("Threw " + t + ""); |
| } |
| assertEquals("BEFORE", "FIRST-NEW-VALUE", ((Map<?, ?>)bean.getListIndexed().get(0)).get("FIRST-NEW-KEY")); |
| assertEquals("AFTER", "SECOND-VALUE-1-UPDATED", ((Map<?, ?>)bean.getListIndexed().get(1)).get("SECOND-KEY-1")); |
| } |
| |
| /** |
| * Positive and negative tests on setIndexedProperty valid arguments. |
| */ |
| public void testSetIndexedValues() { |
| |
| Object value = null; |
| |
| // Use explicit index argument |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "dupProperty", 0, |
| "New 0"); |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "dupProperty", 0); |
| assertNotNull("Returned new value 0", value); |
| assertTrue("Returned String new value 0", |
| value instanceof String); |
| assertEquals("Returned correct new value 0", "New 0", |
| (String) value); |
| } catch (final Throwable t) { |
| fail("Threw " + t); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "intArray", 0, |
| new Integer(1)); |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "intArray", 0); |
| assertNotNull("Returned new value 0", value); |
| assertTrue("Returned Integer new value 0", |
| value instanceof Integer); |
| assertEquals("Returned correct new value 0", 1, |
| ((Integer) value).intValue()); |
| } catch (final Throwable t) { |
| fail("Threw " + t); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "intIndexed", 1, |
| new Integer(11)); |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "intIndexed", 1); |
| assertNotNull("Returned new value 1", value); |
| assertTrue("Returned Integer new value 1", |
| value instanceof Integer); |
| assertEquals("Returned correct new value 1", 11, |
| ((Integer) value).intValue()); |
| } catch (final Throwable t) { |
| fail("Threw " + t); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "listIndexed", 2, |
| "New Value 2"); |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "listIndexed", 2); |
| assertNotNull("Returned new value 2", value); |
| assertTrue("Returned String new value 2", |
| value instanceof String); |
| assertEquals("Returned correct new value 2", "New Value 2", |
| (String) value); |
| } catch (final Throwable t) { |
| fail("Threw " + t); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "stringArray", 2, |
| "New Value 2"); |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "stringArray", 2); |
| assertNotNull("Returned new value 2", value); |
| assertTrue("Returned String new value 2", |
| value instanceof String); |
| assertEquals("Returned correct new value 2", "New Value 2", |
| (String) value); |
| } catch (final Throwable t) { |
| fail("Threw " + t); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "stringArray", 3, |
| "New Value 3"); |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "stringArray", 3); |
| assertNotNull("Returned new value 3", value); |
| assertTrue("Returned String new value 3", |
| value instanceof String); |
| assertEquals("Returned correct new value 3", "New Value 3", |
| (String) value); |
| } catch (final Throwable t) { |
| fail("Threw " + t); |
| } |
| |
| // Use index expression |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "dupProperty[4]", |
| "New 4"); |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "dupProperty[4]"); |
| assertNotNull("Returned new value 4", value); |
| assertTrue("Returned String new value 4", |
| value instanceof String); |
| assertEquals("Returned correct new value 4", "New 4", |
| (String) value); |
| } catch (final Throwable t) { |
| fail("Threw " + t); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "intArray[4]", |
| new Integer(1)); |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "intArray[4]"); |
| assertNotNull("Returned new value 4", value); |
| assertTrue("Returned Integer new value 4", |
| value instanceof Integer); |
| assertEquals("Returned correct new value 4", 1, |
| ((Integer) value).intValue()); |
| } catch (final Throwable t) { |
| fail("Threw " + t); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "intIndexed[3]", |
| new Integer(11)); |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "intIndexed[3]"); |
| assertNotNull("Returned new value 5", value); |
| assertTrue("Returned Integer new value 5", |
| value instanceof Integer); |
| assertEquals("Returned correct new value 5", 11, |
| ((Integer) value).intValue()); |
| } catch (final Throwable t) { |
| fail("Threw " + t); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "listIndexed[1]", |
| "New Value 2"); |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "listIndexed[1]"); |
| assertNotNull("Returned new value 6", value); |
| assertTrue("Returned String new value 6", |
| value instanceof String); |
| assertEquals("Returned correct new value 6", "New Value 2", |
| (String) value); |
| } catch (final Throwable t) { |
| fail("Threw " + t); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "stringArray[1]", |
| "New Value 2"); |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "stringArray[2]"); |
| assertNotNull("Returned new value 6", value); |
| assertTrue("Returned String new value 6", |
| value instanceof String); |
| assertEquals("Returned correct new value 6", "New Value 2", |
| (String) value); |
| } catch (final Throwable t) { |
| fail("Threw " + t); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "stringArray[0]", |
| "New Value 3"); |
| value = |
| PropertyUtils.getIndexedProperty(bean, |
| "stringArray[0]"); |
| assertNotNull("Returned new value 7", value); |
| assertTrue("Returned String new value 7", |
| value instanceof String); |
| assertEquals("Returned correct new value 7", "New Value 3", |
| (String) value); |
| } catch (final Throwable t) { |
| fail("Threw " + t); |
| } |
| |
| // Index out of bounds tests |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "dupProperty", -1, |
| "New -1"); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "dupProperty", 5, |
| "New 5"); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "intArray", -1, |
| new Integer(0)); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "intArray", 5, |
| new Integer(0)); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "intIndexed", -1, |
| new Integer(0)); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "intIndexed", 5, |
| new Integer(0)); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "listIndexed", 5, |
| "New String"); |
| fail("Should have thrown IndexOutOfBoundsException"); |
| } catch (final IndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IndexOutOfBoundsException"); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "listIndexed", -1, |
| "New String"); |
| fail("Should have thrown IndexOutOfBoundsException"); |
| } catch (final IndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IndexOutOfBoundsException"); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "stringArray", -1, |
| "New String"); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "stringArray", 5, |
| "New String"); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "stringIndexed", -1, |
| "New String"); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| try { |
| PropertyUtils.setIndexedProperty(bean, |
| "stringIndexed", 5, |
| "New String"); |
| fail("Should have thrown ArrayIndexOutOfBoundsException"); |
| } catch (final ArrayIndexOutOfBoundsException t) { |
| // Expected results |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of ArrayIndexOutOfBoundsException"); |
| } |
| |
| } |
| |
| /** |
| * Corner cases on getMappedProperty invalid arguments. |
| */ |
| public void testSetMappedArguments() { |
| |
| // Use explicit key argument |
| |
| try { |
| PropertyUtils.setMappedProperty(null, "mappedProperty", |
| "First Key", "First Value"); |
| fail("Should throw IllegalArgumentException 1"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 1"); |
| } |
| |
| try { |
| PropertyUtils.setMappedProperty(bean, null, "First Key", |
| "First Value"); |
| fail("Should throw IllegalArgumentException 2"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 2"); |
| } |
| |
| try { |
| PropertyUtils.setMappedProperty(bean, "mappedProperty", null, |
| "First Value"); |
| fail("Should throw IllegalArgumentException 3"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 3"); |
| } |
| |
| // Use key expression |
| |
| try { |
| PropertyUtils.setMappedProperty(null, |
| "mappedProperty(First Key)", |
| "First Value"); |
| fail("Should throw IllegalArgumentException 4"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 4"); |
| } |
| |
| try { |
| PropertyUtils.setMappedProperty(bean, "(Second Key)", |
| "Second Value"); |
| fail("Should throw IllegalArgumentException 5"); |
| } catch (final NoSuchMethodException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of NoSuchMethodException 5"); |
| } |
| |
| try { |
| PropertyUtils.setMappedProperty(bean, "mappedProperty", |
| "Third Value"); |
| fail("Should throw IllegalArgumentException 6"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 6"); |
| } |
| |
| } |
| |
| /** |
| * Test setting an indexed value out of a mapped array |
| */ |
| public void testSetMappedArray() { |
| final TestBean bean = new TestBean(); |
| final String[] array = new String[] {"abc", "def", "ghi"}; |
| bean.getMapProperty().put("mappedArray", array); |
| |
| assertEquals("BEFORE", "def", ((String[])bean.getMapProperty().get("mappedArray"))[1]); |
| try { |
| PropertyUtils.setProperty(bean, "mapProperty(mappedArray)[1]", "DEF-UPDATED"); |
| } catch (final Throwable t) { |
| fail("Threw " + t + ""); |
| } |
| assertEquals("AFTER", "DEF-UPDATED", ((String[])bean.getMapProperty().get("mappedArray"))[1]); |
| } |
| |
| /** |
| * Test setting an indexed value out of a mapped List |
| */ |
| public void testSetMappedList() { |
| final TestBean bean = new TestBean(); |
| final List<Object> list = new ArrayList<>(); |
| list.add("klm"); |
| list.add("nop"); |
| list.add("qrs"); |
| bean.getMapProperty().put("mappedList", list); |
| |
| assertEquals("BEFORE", "klm", ((List<?>)bean.getMapProperty().get("mappedList")).get(0)); |
| try { |
| PropertyUtils.setProperty(bean, "mapProperty(mappedList)[0]", "KLM-UPDATED"); |
| } catch (final Throwable t) { |
| fail("Threw " + t + ""); |
| } |
| assertEquals("AFTER", "KLM-UPDATED", ((List<?>)bean.getMapProperty().get("mappedList")).get(0)); |
| } |
| |
| /** |
| * Test setting a value out of a mapped Map |
| */ |
| public void testSetMappedMap() { |
| final TestBean bean = new TestBean(); |
| final Map<String, Object> map = new HashMap<>(); |
| map.put("sub-key-1", "sub-value-1"); |
| map.put("sub-key-2", "sub-value-2"); |
| map.put("sub-key-3", "sub-value-3"); |
| bean.getMapProperty().put("mappedMap", map); |
| |
| assertEquals("BEFORE", "sub-value-3", ((Map<?, ?>)bean.getMapProperty().get("mappedMap")).get("sub-key-3")); |
| try { |
| PropertyUtils.setProperty(bean, "mapProperty(mappedMap)(sub-key-3)", "SUB-KEY-3-UPDATED"); |
| } catch (final Throwable t) { |
| fail("Threw " + t + ""); |
| } |
| assertEquals("AFTER", "SUB-KEY-3-UPDATED", ((Map<?, ?>)bean.getMapProperty().get("mappedMap")).get("sub-key-3")); |
| } |
| |
| /** |
| * Positive and negative tests on setMappedProperty valid arguments. |
| */ |
| public void testSetMappedValues() { |
| |
| Object value = null; |
| |
| // Use explicit key argument |
| |
| try { |
| value = PropertyUtils.getMappedProperty(bean, "mappedProperty", |
| "Fourth Key"); |
| assertNull("Can not find fourth value", value); |
| } catch (final Throwable t) { |
| fail("Finding fourth value threw " + t); |
| } |
| |
| try { |
| PropertyUtils.setMappedProperty(bean, "mappedProperty", |
| "Fourth Key", "Fourth Value"); |
| } catch (final Throwable t) { |
| fail("Setting fourth value threw " + t); |
| } |
| |
| try { |
| value = PropertyUtils.getMappedProperty(bean, "mappedProperty", |
| "Fourth Key"); |
| assertEquals("Can find fourth value", "Fourth Value", value); |
| } catch (final Throwable t) { |
| fail("Finding fourth value threw " + t); |
| } |
| |
| // Use key expression with parentheses |
| |
| try { |
| value = |
| PropertyUtils.getMappedProperty(bean, |
| "mappedProperty(Fifth Key)"); |
| assertNull("Can not find fifth value", value); |
| } catch (final Throwable t) { |
| fail("Finding fifth value threw " + t); |
| } |
| |
| try { |
| PropertyUtils.setMappedProperty(bean, |
| "mappedProperty(Fifth Key)", |
| "Fifth Value"); |
| } catch (final Throwable t) { |
| fail("Setting fifth value threw " + t); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getMappedProperty(bean, |
| "mappedProperty(Fifth Key)"); |
| assertEquals("Can find fifth value", "Fifth Value", value); |
| } catch (final Throwable t) { |
| fail("Finding fifth value threw " + t); |
| } |
| |
| // Use key expression with dotted expression |
| |
| try { |
| value = |
| PropertyUtils.getNestedProperty(bean, |
| "mapProperty.Sixth Key"); |
| assertNull("Can not find sixth value", value); |
| } catch (final Throwable t) { |
| fail("Finding fifth value threw " + t); |
| } |
| |
| try { |
| PropertyUtils.setNestedProperty(bean, |
| "mapProperty.Sixth Key", |
| "Sixth Value"); |
| } catch (final Throwable t) { |
| fail("Setting sixth value threw " + t); |
| } |
| |
| try { |
| value = |
| PropertyUtils.getNestedProperty(bean, |
| "mapProperty.Sixth Key"); |
| assertEquals("Can find sixth value", "Sixth Value", value); |
| } catch (final Throwable t) { |
| fail("Finding sixth value threw " + t); |
| } |
| |
| } |
| |
| /** |
| * Test setting mapped values with periods in the key. |
| */ |
| public void testSetMappedPeriods() { |
| |
| // -------- PropertyUtils.setMappedProperty()-------- |
| bean.setMappedProperty("key.with.a.dot", "Special Value"); |
| assertEquals("Can retrieve directly (A)", |
| "Special Value", |
| bean.getMappedProperty("key.with.a.dot")); |
| |
| try { |
| PropertyUtils.setMappedProperty(bean, "mappedProperty", "key.with.a.dot", "Updated Special Value"); |
| assertEquals("Check set via setMappedProperty", |
| "Updated Special Value", |
| bean.getMappedProperty("key.with.a.dot")); |
| } catch (final Exception e) { |
| fail("Thew exception: " + e); |
| } |
| |
| // -------- PropertyUtils.setNestedProperty() -------- |
| bean.setMappedProperty("key.with.a.dot", "Special Value"); |
| assertEquals("Can retrieve directly (B)", |
| "Special Value", |
| bean.getMappedProperty("key.with.a.dot")); |
| try { |
| PropertyUtils.setNestedProperty(bean, "mappedProperty(key.with.a.dot)", "Updated Special Value"); |
| assertEquals("Check set via setNestedProperty (B)", |
| "Updated Special Value", |
| bean.getMappedProperty("key.with.a.dot")); |
| } catch (final Exception e) { |
| fail("Thew exception: " + e); |
| } |
| |
| // -------- PropertyUtils.setNestedProperty() -------- |
| final TestBean testBean = new TestBean(); |
| bean.setMappedObjects("nested.property", testBean); |
| assertEquals("Can retrieve directly (C)", |
| "This is a string", |
| testBean.getStringProperty()); |
| try { |
| PropertyUtils.setNestedProperty(bean, "mappedObjects(nested.property).stringProperty", |
| "Updated String Value"); |
| assertEquals("Check set via setNestedProperty (C)", |
| "Updated String Value", |
| testBean.getStringProperty()); |
| } catch (final Exception e) { |
| fail("Thew exception: " + e); |
| } |
| |
| // -------- PropertyUtils.setNestedProperty() -------- |
| bean.getNested().setMappedProperty("Mapped Key", "Nested Mapped Value"); |
| try { |
| assertEquals("Can retrieve via getNestedProperty (D)", |
| "Nested Mapped Value", |
| PropertyUtils.getNestedProperty( |
| bean,"nested.mappedProperty(Mapped Key)")); |
| PropertyUtils.setNestedProperty(bean, "nested.mappedProperty(Mapped Key)", |
| "Updated Nested Mapped Value"); |
| assertEquals("Check set via setNestedProperty (D)", |
| "Updated Nested Mapped Value", |
| PropertyUtils.getNestedProperty( |
| bean,"nested.mappedProperty(Mapped Key)")); |
| } catch (final Exception e) { |
| fail("Thew exception: " + e); |
| } |
| } |
| |
| /** |
| * Corner cases on setNestedProperty invalid arguments. |
| */ |
| public void testSetNestedArguments() { |
| |
| try { |
| PropertyUtils.setNestedProperty(null, "stringProperty", ""); |
| fail("Should throw IllegalArgumentException 1"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 1"); |
| } |
| |
| try { |
| PropertyUtils.setNestedProperty(bean, null, ""); |
| fail("Should throw IllegalArgumentException 2"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 2"); |
| } |
| |
| } |
| |
| /** |
| * Test setNextedProperty on a boolean property. |
| */ |
| public void testSetNestedBoolean() { |
| |
| try { |
| final boolean oldValue = bean.getNested().getBooleanProperty(); |
| final boolean newValue = !oldValue; |
| PropertyUtils.setNestedProperty(bean, |
| "nested.booleanProperty", |
| new Boolean(newValue)); |
| assertTrue("Matched new value", |
| newValue == |
| bean.getNested().getBooleanProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test setNestedProperty on a double property. |
| */ |
| public void testSetNestedDouble() { |
| |
| try { |
| final double oldValue = bean.getNested().getDoubleProperty(); |
| final double newValue = oldValue + 1.0; |
| PropertyUtils.setNestedProperty(bean, |
| "nested.doubleProperty", |
| new Double(newValue)); |
| assertEquals("Matched new value", |
| newValue, |
| bean.getNested().getDoubleProperty(), |
| 0.005); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test setNestedProperty on a float property. |
| */ |
| public void testSetNestedFloat() { |
| |
| try { |
| final float oldValue = bean.getNested().getFloatProperty(); |
| final float newValue = oldValue + (float) 1.0; |
| PropertyUtils.setNestedProperty(bean, |
| "nested.floatProperty", |
| new Float(newValue)); |
| assertEquals("Matched new value", |
| newValue, |
| bean.getNested().getFloatProperty(), |
| (float) 0.005); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test setNestedProperty on a int property. |
| */ |
| public void testSetNestedInt() { |
| |
| try { |
| final int oldValue = bean.getNested().getIntProperty(); |
| final int newValue = oldValue + 1; |
| PropertyUtils.setNestedProperty(bean, |
| "nested.intProperty", |
| new Integer(newValue)); |
| assertEquals("Matched new value", |
| newValue, |
| bean.getNested().getIntProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test setNestedProperty on a long property. |
| */ |
| public void testSetNestedLong() { |
| |
| try { |
| final long oldValue = bean.getNested().getLongProperty(); |
| final long newValue = oldValue + 1; |
| PropertyUtils.setNestedProperty(bean, |
| "nested.longProperty", |
| new Long(newValue)); |
| assertEquals("Matched new value", |
| newValue, |
| bean.getNested().getLongProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test setNestedProperty on a read-only String property. |
| */ |
| public void testSetNestedReadOnly() { |
| |
| try { |
| final String oldValue = bean.getNested().getWriteOnlyPropertyValue(); |
| final String newValue = oldValue + " Extra Value"; |
| PropertyUtils.setNestedProperty(bean, |
| "nested.readOnlyProperty", |
| newValue); |
| fail("Should have thrown NoSuchMethodException"); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| // Correct result for this test |
| } |
| |
| } |
| |
| /** |
| * Test setNestedProperty on a short property. |
| */ |
| public void testSetNestedShort() { |
| |
| try { |
| final short oldValue = bean.getNested().getShortProperty(); |
| short newValue = oldValue; |
| newValue++; |
| PropertyUtils.setNestedProperty(bean, |
| "nested.shortProperty", |
| new Short(newValue)); |
| assertEquals("Matched new value", |
| newValue, |
| bean.getNested().getShortProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test setNestedProperty on a String property. |
| */ |
| public void testSetNestedString() { |
| |
| try { |
| final String oldValue = bean.getNested().getStringProperty(); |
| final String newValue = oldValue + " Extra Value"; |
| PropertyUtils.setNestedProperty(bean, |
| "nested.stringProperty", |
| newValue); |
| assertEquals("Matched new value", |
| newValue, |
| bean.getNested().getStringProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test setNestedProperty on an unknown property name. |
| */ |
| public void testSetNestedUnknown() { |
| |
| try { |
| final String newValue = "New String Value"; |
| PropertyUtils.setNestedProperty(bean, |
| "nested.unknown", |
| newValue); |
| fail("Should have thrown NoSuchMethodException"); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| // Correct result for this test |
| } |
| |
| } |
| |
| /** |
| * Test setNestedProperty on a write-only String property. |
| */ |
| public void testSetNestedWriteOnly() { |
| |
| try { |
| final String oldValue = bean.getNested().getWriteOnlyPropertyValue(); |
| final String newValue = oldValue + " Extra Value"; |
| PropertyUtils.setNestedProperty(bean, |
| "nested.writeOnlyProperty", |
| newValue); |
| assertEquals("Matched new value", |
| newValue, |
| bean.getNested().getWriteOnlyPropertyValue()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Corner cases on setSimpleProperty invalid arguments. |
| */ |
| public void testSetSimpleArguments() { |
| |
| try { |
| PropertyUtils.setSimpleProperty(null, "stringProperty", ""); |
| fail("Should throw IllegalArgumentException 1"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 1"); |
| } |
| |
| try { |
| PropertyUtils.setSimpleProperty(bean, null, ""); |
| fail("Should throw IllegalArgumentException 2"); |
| } catch (final IllegalArgumentException e) { |
| // Expected response |
| } catch (final Throwable t) { |
| fail("Threw " + t + " instead of IllegalArgumentException 2"); |
| } |
| |
| } |
| |
| /** |
| * Test setSimpleProperty on a boolean property. |
| */ |
| public void testSetSimpleBoolean() { |
| |
| try { |
| final boolean oldValue = bean.getBooleanProperty(); |
| final boolean newValue = !oldValue; |
| PropertyUtils.setSimpleProperty(bean, |
| "booleanProperty", |
| new Boolean(newValue)); |
| assertTrue("Matched new value", |
| newValue == |
| bean.getBooleanProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test setSimpleProperty on a double property. |
| */ |
| public void testSetSimpleDouble() { |
| |
| try { |
| final double oldValue = bean.getDoubleProperty(); |
| final double newValue = oldValue + 1.0; |
| PropertyUtils.setSimpleProperty(bean, |
| "doubleProperty", |
| new Double(newValue)); |
| assertEquals("Matched new value", |
| newValue, |
| bean.getDoubleProperty(), |
| 0.005); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test setSimpleProperty on a float property. |
| */ |
| public void testSetSimpleFloat() { |
| |
| try { |
| final float oldValue = bean.getFloatProperty(); |
| final float newValue = oldValue + (float) 1.0; |
| PropertyUtils.setSimpleProperty(bean, |
| "floatProperty", |
| new Float(newValue)); |
| assertEquals("Matched new value", |
| newValue, |
| bean.getFloatProperty(), |
| (float) 0.005); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Negative test setSimpleProperty on an indexed property. |
| */ |
| public void testSetSimpleIndexed() { |
| |
| try { |
| PropertyUtils.setSimpleProperty(bean, |
| "stringIndexed[0]", |
| "New String Value"); |
| fail("Should have thrown IllegalArgumentException"); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| // Correct result for this test |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test setSimpleProperty on a int property. |
| */ |
| public void testSetSimpleInt() { |
| |
| try { |
| final int oldValue = bean.getIntProperty(); |
| final int newValue = oldValue + 1; |
| PropertyUtils.setSimpleProperty(bean, |
| "intProperty", |
| new Integer(newValue)); |
| assertEquals("Matched new value", |
| newValue, |
| bean.getIntProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test setSimpleProperty on a long property. |
| */ |
| public void testSetSimpleLong() { |
| |
| try { |
| final long oldValue = bean.getLongProperty(); |
| final long newValue = oldValue + 1; |
| PropertyUtils.setSimpleProperty(bean, |
| "longProperty", |
| new Long(newValue)); |
| assertEquals("Matched new value", |
| newValue, |
| bean.getLongProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Negative test setSimpleProperty on a nested property. |
| */ |
| public void testSetSimpleNested() { |
| |
| try { |
| PropertyUtils.setSimpleProperty(bean, |
| "nested.stringProperty", |
| "New String Value"); |
| fail("Should have thrown IllegalArgumentException"); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| // Correct result for this test |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test setSimpleProperty on a read-only String property. |
| */ |
| public void testSetSimpleReadOnly() { |
| |
| try { |
| final String oldValue = bean.getWriteOnlyPropertyValue(); |
| final String newValue = oldValue + " Extra Value"; |
| PropertyUtils.setSimpleProperty(bean, |
| "readOnlyProperty", |
| newValue); |
| fail("Should have thrown NoSuchMethodException"); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| // Correct result for this test |
| assertEquals("Property 'readOnlyProperty' has no setter method in class '" + |
| bean.getClass() + "'", e.getMessage() ); |
| } |
| |
| } |
| |
| /** |
| * Test setSimpleProperty on a short property. |
| */ |
| public void testSetSimpleShort() { |
| |
| try { |
| final short oldValue = bean.getShortProperty(); |
| short newValue = oldValue; |
| newValue++; |
| PropertyUtils.setSimpleProperty(bean, |
| "shortProperty", |
| new Short(newValue)); |
| assertEquals("Matched new value", |
| newValue, |
| bean.getShortProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test setSimpleProperty on a String property. |
| */ |
| public void testSetSimpleString() { |
| |
| try { |
| final String oldValue = bean.getStringProperty(); |
| final String newValue = oldValue + " Extra Value"; |
| PropertyUtils.setSimpleProperty(bean, |
| "stringProperty", |
| newValue); |
| assertEquals("Matched new value", |
| newValue, |
| bean.getStringProperty()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Test setSimpleProperty on an unknown property name. |
| */ |
| public void testSetSimpleUnknown() { |
| |
| try { |
| final String newValue = "New String Value"; |
| PropertyUtils.setSimpleProperty(bean, |
| "unknown", |
| newValue); |
| fail("Should have thrown NoSuchMethodException"); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| // Correct result for this test |
| assertEquals("Unknown property 'unknown' on class '" + |
| bean.getClass() + "'", e.getMessage() ); |
| } |
| |
| } |
| |
| /** |
| * Test setSimpleProperty on a write-only String property. |
| */ |
| public void testSetSimpleWriteOnly() { |
| |
| try { |
| final String oldValue = bean.getWriteOnlyPropertyValue(); |
| final String newValue = oldValue + " Extra Value"; |
| PropertyUtils.setSimpleProperty(bean, |
| "writeOnlyProperty", |
| newValue); |
| assertEquals("Matched new value", |
| newValue, |
| bean.getWriteOnlyPropertyValue()); |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final IllegalArgumentException e) { |
| fail("IllegalArgumentException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| |
| |
| /** |
| * Base for testGetDescriptorXxxxx() series of tests. |
| * |
| * @param name Name of the property to be retrieved |
| * @param read Expected name of the read method (or null) |
| * @param write Expected name of the write method (or null) |
| */ |
| protected void testGetDescriptorBase(final String name, final String read, |
| final String write) { |
| |
| try { |
| final PropertyDescriptor pd = |
| PropertyUtils.getPropertyDescriptor(bean, name); |
| if (read != null || write != null) { |
| assertNotNull("Got descriptor", pd); |
| } else { |
| assertNull("Got descriptor", pd); |
| return; |
| } |
| final Method rm = pd.getReadMethod(); |
| if (read != null) { |
| assertNotNull("Got read method", rm); |
| assertEquals("Got correct read method", |
| rm.getName(), read); |
| } else { |
| assertNull("Got read method", rm); |
| } |
| final Method wm = pd.getWriteMethod(); |
| if (write != null) { |
| assertNotNull("Got write method", wm); |
| assertEquals("Got correct write method", |
| wm.getName(), write); |
| } else { |
| assertNull("Got write method", wm); |
| } |
| } catch (final IllegalAccessException e) { |
| fail("IllegalAccessException"); |
| } catch (final InvocationTargetException e) { |
| fail("InvocationTargetException"); |
| } catch (final NoSuchMethodException e) { |
| fail("NoSuchMethodException"); |
| } |
| |
| } |
| |
| /** |
| * Base for testGetReadMethod() series of tests. |
| * |
| * @param bean Bean for which to retrieve read methods. |
| * @param properties Property names to search for |
| * @param className Class name where this method should be defined |
| */ |
| protected void testGetReadMethod(final Object bean, final String[] properties, |
| final String className) { |
| |
| final PropertyDescriptor[] pd = |
| PropertyUtils.getPropertyDescriptors(bean); |
| for (final String propertie : properties) { |
| |
| // Identify the property descriptor for this property |
| if (propertie.equals("intIndexed")) { |
| continue; |
| } |
| if (propertie.equals("stringIndexed")) { |
| continue; |
| } |
| if (propertie.equals("writeOnlyProperty")) { |
| continue; |
| } |
| int n = -1; |
| for (int j = 0; j < pd.length; j++) { |
| if (propertie.equals(pd[j].getName())) { |
| n = j; |
| break; |
| } |
| } |
| assertTrue("PropertyDescriptor for " + propertie, |
| n >= 0); |
| |
| // Locate an accessible property reader method for it |
| final Method reader = PropertyUtils.getReadMethod(pd[n]); |
| assertNotNull("Reader for " + propertie, |
| reader); |
| final Class<?> clazz = reader.getDeclaringClass(); |
| assertNotNull("Declaring class for " + propertie, |
| clazz); |
| assertEquals("Correct declaring class for " + propertie, |
| clazz.getName(), |
| className); |
| |
| // Actually call the reader method we received |
| try { |
| reader.invoke(bean, (Object[]) new Class<?>[0]); |
| } catch (final Throwable t) { |
| fail("Call for " + propertie + ": " + t); |
| } |
| |
| } |
| |
| } |
| |
| /** |
| * Base for testGetWriteMethod() series of tests. |
| * |
| * @param bean Bean for which to retrieve write methods. |
| * @param properties Property names to search for |
| * @param className Class name where this method should be defined |
| */ |
| protected void testGetWriteMethod(final Object bean, final String[] properties, |
| final String className) { |
| |
| final PropertyDescriptor[] pd = |
| PropertyUtils.getPropertyDescriptors(bean); |
| for (final String property : properties) { |
| |
| // Identify the property descriptor for this property |
| if (property.equals("intIndexed")) { |
| continue; |
| } |
| if (property.equals("listIndexed")) { |
| continue; |
| } |
| if (property.equals("nested")) |
| { |
| continue; // This property is read only |
| } |
| if (property.equals("readOnlyProperty")) { |
| continue; |
| } |
| if (property.equals("stringIndexed")) { |
| continue; |
| } |
| int n = -1; |
| for (int j = 0; j < pd.length; j++) { |
| if (property.equals(pd[j].getName())) { |
| n = j; |
| break; |
| } |
| } |
| assertTrue("PropertyDescriptor for " + property, |
| n >= 0); |
| |
| // Locate an accessible property reader method for it |
| final Method writer = PropertyUtils.getWriteMethod(pd[n]); |
| assertNotNull("Writer for " + property, |
| writer); |
| final Class<?> clazz = writer.getDeclaringClass(); |
| assertNotNull("Declaring class for " + property, |
| clazz); |
| assertEquals("Correct declaring class for " + property, |
| clazz.getName(), |
| className); |
| |
| } |
| |
| } |
| |
| public void testNestedWithIndex() throws Exception |
| { |
| final NestedTestBean nestedBean = new NestedTestBean("base"); |
| nestedBean.init(); |
| nestedBean.getSimpleBeanProperty().init(); |
| |
| NestedTestBean |
| |
| // test first calling properties on indexed beans |
| |
| value = (NestedTestBean) PropertyUtils.getProperty( |
| nestedBean, |
| "indexedProperty[0]"); |
| assertEquals("Cannot get simple index(1)", "Bean@0", value.getName()); |
| assertEquals("Bug in NestedTestBean", "NOT SET", value.getTestString()); |
| |
| value = (NestedTestBean) PropertyUtils.getProperty( |
| nestedBean, |
| "indexedProperty[1]"); |
| assertEquals("Cannot get simple index(1)", "Bean@1", value.getName()); |
| assertEquals("Bug in NestedTestBean", "NOT SET", value.getTestString()); |
| |
| String |
| prop = (String) PropertyUtils.getProperty( |
| nestedBean, |
| "indexedProperty[0].testString"); |
| assertEquals("Get property on indexes failed (1)", "NOT SET", prop); |
| |
| prop = (String) PropertyUtils.getProperty( |
| nestedBean, |
| "indexedProperty[1].testString"); |
| assertEquals("Get property on indexes failed (2)", "NOT SET", prop); |
| |
| PropertyUtils.setProperty( |
| nestedBean, |
| "indexedProperty[0].testString", |
| "Test#1"); |
| assertEquals( |
| "Cannot set property on indexed bean (1)", |
| "Test#1", |
| nestedBean.getIndexedProperty(0).getTestString()); |
| |
| PropertyUtils.setProperty( |
| nestedBean, |
| "indexedProperty[1].testString", |
| "Test#2"); |
| assertEquals( |
| "Cannot set property on indexed bean (2)", |
| "Test#2", |
| nestedBean.getIndexedProperty(1).getTestString()); |
| |
| // test first calling indexed properties on a simple property |
| |
| value = (NestedTestBean) PropertyUtils.getProperty( |
| nestedBean, |
| "simpleBeanProperty"); |
| assertEquals("Cannot get simple bean", "Simple Property Bean", value.getName()); |
| assertEquals("Bug in NestedTestBean", "NOT SET", value.getTestString()); |
| |
| value = (NestedTestBean) PropertyUtils.getProperty( |
| nestedBean, |
| "simpleBeanProperty.indexedProperty[3]"); |
| assertEquals("Cannot get index property on property", "Bean@3", value.getName()); |
| assertEquals("Bug in NestedTestBean", "NOT SET", value.getTestString()); |
| |
| PropertyUtils.setProperty( |
| nestedBean, |
| "simpleBeanProperty.indexedProperty[3].testString", |
| "Test#3"); |
| assertEquals( |
| "Cannot set property on indexed property on property", |
| "Test#3", |
| nestedBean.getSimpleBeanProperty().getIndexedProperty(3).getTestString()); |
| } |
| |
| /** Text case for setting properties on inner classes */ |
| public void testGetSetInnerBean() throws Exception { |
| final BeanWithInnerBean bean = new BeanWithInnerBean(); |
| |
| PropertyUtils.setProperty(bean, "innerBean.fish(loiterTimer)", "5"); |
| String out = (String) PropertyUtils.getProperty(bean.getInnerBean(), "fish(loiterTimer)"); |
| assertEquals( |
| "(1) Inner class property set/get property failed.", |
| "5", |
| out); |
| |
| out = (String) PropertyUtils.getProperty(bean, "innerBean.fish(loiterTimer)"); |
| |
| assertEquals( |
| "(2) Inner class property set/get property failed.", |
| "5", |
| out); |
| } |
| |
| /** Text case for setting properties on parent */ |
| public void testGetSetParentBean() throws Exception { |
| |
| final SonOfAlphaBean bean = new SonOfAlphaBean("Roger"); |
| |
| final String out = (String) PropertyUtils.getProperty(bean, "name"); |
| assertEquals( |
| "(1) Get/Set On Parent.", |
| "Roger", |
| out); |
| |
| PropertyUtils.setProperty(bean, "name", "abcd"); |
| assertEquals( |
| "(2) Get/Set On Parent.", |
| "abcd", |
| bean.getName()); |
| } |
| |
| public void testSetNoGetter() throws Exception |
| { |
| final BetaBean bean = new BetaBean("Cedric"); |
| |
| // test standard no getter |
| bean.setNoGetterProperty("Sigma"); |
| assertEquals("BetaBean test failed", "Sigma", bean.getSecret()); |
| |
| assertNotNull("Descriptor is null", PropertyUtils.getPropertyDescriptor(bean, "noGetterProperty")); |
| |
| BeanUtils.setProperty(bean, "noGetterProperty", "Omega"); |
| assertEquals("Cannot set no-getter property", "Omega", bean.getSecret()); |
| |
| // test mapped no getter descriptor |
| assertNotNull("Map Descriptor is null", PropertyUtils.getPropertyDescriptor(bean, "noGetterMappedProperty")); |
| |
| PropertyUtils.setMappedProperty(bean, "noGetterMappedProperty", "Epsilon", "Epsilon"); |
| assertEquals("Cannot set mapped no-getter property", "MAP:Epsilon", bean.getSecret()); |
| } |
| |
| /** |
| * Test accessing a public sub-bean of a package scope bean |
| */ |
| public void testSetPublicSubBean_of_PackageBean() { |
| |
| final PublicSubBean bean = new PublicSubBean(); |
| bean.setFoo("foo-start"); |
| bean.setBar("bar-start"); |
| |
| // Set Foo |
| try { |
| PropertyUtils.setProperty(bean, "foo", "foo-updated"); |
| } catch (final Throwable t) { |
| fail("setProperty(foo) threw " + t); |
| } |
| assertEquals("foo property", "foo-updated", bean.getFoo()); |
| |
| // Set Bar |
| try { |
| PropertyUtils.setProperty(bean, "bar", "bar-updated"); |
| } catch (final Throwable t) { |
| fail("setProperty(bar) threw " + t); |
| } |
| assertEquals("bar property", "bar-updated", bean.getBar()); |
| } |
| |
| /** |
| * There is an issue in setNestedProperty/getNestedProperty when the |
| * target bean is a map and the name string requests mapped or indexed |
| * operations on a field. These are not supported for fields of a Map, |
| * but it's an easy mistake to make and this test case ensures that an |
| * appropriate exception is thrown when a user does this. |
| * <p> |
| * The problem is with passing strings of form "a(b)" or "a[3]" to |
| * setNestedProperty or getNestedProperty when the target bean they |
| * are applied to implements Map. These strings are actually requesting |
| * "the result of calling mapped method a on the target object with |
| * a parameter of b" or "the result of calling indexed method a on the |
| * target object with a parameter of 3". And these requests are not valid |
| * when the target is a Map as a Map only supports calling get(fieldName) |
| * or put(fieldName), neither of which can be further indexed with a |
| * string or an integer. |
| * <p> |
| * However it is likely that some users will assume that "a[3]" when applied |
| * to a map will be equivalent to (map.get("a"))[3] with the appropriate |
| * typecasting, or for "a(b)" to be equivalent to map.get("a").get("b"). |
| * <p> |
| * Here we verify that an exception is thrown if the user makes this |
| * mistake. |
| */ |
| public void testNestedPropertyKeyOrIndexOnBeanImplementingMap() throws Exception { |
| final HashMap<String, Object> map = new HashMap<>(); |
| final HashMap<String, Object> submap = new HashMap<>(); |
| final BetaBean betaBean1 = new BetaBean("test1"); |
| final BetaBean betaBean2 = new BetaBean("test2"); |
| |
| // map.put("submap", submap) |
| PropertyUtils.setNestedProperty(map, "submap", submap); |
| |
| // map.get("submap").put("beta1", betaBean1) |
| PropertyUtils.setNestedProperty(map, "submap.beta1", betaBean1); |
| assertEquals("Unexpected keys in map", "submap", keysToString(map)); |
| assertEquals("Unexpected keys in submap", "beta1", keysToString(submap)); |
| |
| try { |
| // One would expect that the command below would be equivalent to |
| // Map m = (Map) map.get("submap"); |
| // m.put("beta2", betaBean2) |
| // However this isn't how javabeans property methods work. A map |
| // only effectively has "simple" properties, even when the |
| // returned object is a Map or Array. |
| PropertyUtils.setNestedProperty(map, "submap(beta2)", betaBean2); |
| |
| // What, no exception? In that case, setNestedProperties has |
| // probably just tried to do |
| // map.set("submap(beta2)", betaBean2) |
| // which is almost certainly not what the used expected. This is |
| // what beanutils 1.5.0 to 1.7.1 did.... |
| fail("Exception not thrown for invalid setNestedProperty syntax"); |
| } catch(final IllegalArgumentException ex) { |
| // ok, getting an exception was expected. As it is of a generic |
| // type, let's check the message string to make sure it really |
| // was caused by the issue we expected. |
| final int index = ex.getMessage().indexOf( |
| "Indexed or mapped properties are not supported"); |
| assertTrue("Unexpected exception message", index>=0); |
| } |
| |
| try { |
| // One would expect that "submap[3]" would be equivalent to |
| // Object[] objects = (Object[]) map.get("submap"); |
| // return objects[3]; |
| // However this isn't how javabeans property methods work. A map |
| // only effectively has "simple" properties, even when the |
| // returned object is a Map or Array. |
| PropertyUtils.getNestedProperty(map, "submap[3]"); |
| |
| // What, no exception? In that case, getNestedProperties has |
| // probably just tried to do |
| // map.get("submap[3]") |
| // which is almost certainly not what the used expected. This is |
| // what beanutils 1.5.0 to 1.7.1 did.... |
| fail("Exception not thrown for invalid setNestedProperty syntax"); |
| } catch(final IllegalArgumentException ex) { |
| // ok, getting an exception was expected. As it is of a generic |
| // type, let's check the message string to make sure it really |
| // was caused by the issue we expected. |
| final int index = ex.getMessage().indexOf( |
| "Indexed or mapped properties are not supported"); |
| assertTrue("Unexpected exception message", index>=0); |
| } |
| } |
| |
| /** |
| * Returns a single string containing all the keys in the map, |
| * sorted in alphabetical order and separated by ", ". |
| * <p> |
| * If there are no keys, an empty string is returned. |
| */ |
| private String keysToString(final Map<?, ?> map) { |
| final Object[] mapKeys = map.keySet().toArray(); |
| java.util.Arrays.sort(mapKeys); |
| final StringBuilder buf = new StringBuilder(); |
| for(int i=0; i<mapKeys.length; ++i) { |
| if (i != 0) { |
| buf.append(", "); |
| } |
| buf.append(mapKeys[i]); |
| } |
| return buf.toString(); |
| } |
| |
| /** |
| * This tests to see that classes that implement Map always have their |
| * custom properties ignored. |
| * <p> |
| * Note that this behavior has changed several times over past releases |
| * of beanutils, breaking backwards compatibility each time. Here's hoping |
| * that the current 1.7.1 release is the last time this behavior changes! |
| */ |
| public void testMapExtensionDefault() throws Exception { |
| final ExtendMapBean bean = new ExtendMapBean(); |
| |
| // setting property direct should work, and not affect map |
| bean.setUnusuallyNamedProperty("bean value"); |
| assertEquals("Set property direct failed", "bean value", bean.getUnusuallyNamedProperty()); |
| assertNull("Get on unset map property failed", |
| PropertyUtils.getNestedProperty(bean, "unusuallyNamedProperty")); |
| |
| // setting simple property should call the setter method only, and not |
| // affect the map. |
| PropertyUtils.setSimpleProperty(bean, "unusuallyNamedProperty", "new value"); |
| assertEquals("Set property on map failed (1)", "new value", bean.getUnusuallyNamedProperty()); |
| assertNull("Get on unset map property failed", |
| PropertyUtils.getNestedProperty(bean, "unusuallyNamedProperty")); |
| |
| // setting via setNestedProperty should affect the map only, and not |
| // call the setter method. |
| PropertyUtils.setProperty(bean, "unusuallyNamedProperty", "next value"); |
| assertEquals( |
| "setNestedProperty on map not visible to getNestedProperty", |
| "next value", |
| PropertyUtils.getNestedProperty(bean, "unusuallyNamedProperty")); |
| assertEquals( |
| "Set nested property on map unexpected affected simple property", |
| "new value", |
| bean.getUnusuallyNamedProperty()); |
| } |
| |
| /** |
| * This tests to see that it is possible to subclass PropertyUtilsBean |
| * and change the behavior of setNestedProperty/getNestedProperty when |
| * dealing with objects that implement Map. |
| */ |
| public void testMapExtensionCustom() throws Exception { |
| final PropsFirstPropertyUtilsBean utilsBean = new PropsFirstPropertyUtilsBean(); |
| final ExtendMapBean bean = new ExtendMapBean(); |
| |
| // hardly worth testing this, really :-) |
| bean.setUnusuallyNamedProperty("bean value"); |
| assertEquals("Set property direct failed", "bean value", bean.getUnusuallyNamedProperty()); |
| |
| // setSimpleProperty should affect the simple property |
| utilsBean.setSimpleProperty(bean, "unusuallyNamedProperty", "new value"); |
| assertEquals("Set property on map failed (1)", "new value", bean.getUnusuallyNamedProperty()); |
| |
| // setNestedProperty with setter should affect the simple property |
| // getNestedProperty with getter should obtain the simple property |
| utilsBean.setProperty(bean, "unusuallyNamedProperty", "next value"); |
| assertEquals("Set property on map failed (2)", "next value", bean.getUnusuallyNamedProperty()); |
| assertEquals("setNestedProperty on non-simple property failed", |
| "next value", |
| utilsBean.getNestedProperty(bean, "unusuallyNamedProperty")); |
| |
| // setting property without setter should update the map |
| // getting property without setter should fetch from the map |
| utilsBean.setProperty(bean, "mapProperty", "value1"); |
| assertEquals("setNestedProperty on non-simple property failed", |
| "value1", utilsBean.getNestedProperty(bean, "mapProperty")); |
| |
| final HashMap<String, Object> myMap = new HashMap<>(); |
| myMap.put("thebean", bean); |
| utilsBean.getNestedProperty(myMap, "thebean.mapitem"); |
| utilsBean.getNestedProperty(myMap, "thebean(mapitem)"); |
| } |
| |
| /** |
| * Test {@link PropertyUtilsBean}'s invoke method throwing an IllegalArgumentException |
| * and check that the "cause" has been properly initialized for JDK 1.4+ |
| * See BEANUTILS-266 for changes and reason for test |
| */ |
| public void testExceptionFromInvoke() throws Exception { |
| if (BeanUtilsTestCase.isPre14JVM()) { |
| return; |
| } |
| try { |
| PropertyUtils.setSimpleProperty(bean, "intProperty","XXX"); |
| } catch(final IllegalArgumentException t) { |
| final Throwable cause = (Throwable)PropertyUtils.getProperty(t, "cause"); |
| assertNotNull("Cause not found", cause); |
| assertTrue("Expected cause to be IllegalArgumentException, but was: " + cause.getClass(), |
| cause instanceof IllegalArgumentException); |
| // JDK 1.6 doesn't have "argument type mismatch" message |
| // assertEquals("Check error message", "argument type mismatch", cause.getMessage()); |
| } catch(final Throwable t) { |
| fail("Expected IllegalArgumentException, but threw " + t); |
| } |
| } |
| |
| /** |
| * Tests whether the default introspection mechanism can be replaced by a |
| * custom BeanIntrospector. |
| */ |
| public void testCustomIntrospection() { |
| final PropertyDescriptor[] desc1 = PropertyUtils |
| .getPropertyDescriptors(AlphaBean.class); |
| PropertyDescriptor nameDescriptor = findNameDescriptor(desc1); |
| assertNotNull("No write method", nameDescriptor.getWriteMethod()); |
| |
| final BeanIntrospector bi = icontext -> { |
| final Set<String> names = icontext.propertyNames(); |
| final PropertyDescriptor[] newDescs = new PropertyDescriptor[names |
| .size()]; |
| int idx = 0; |
| for (final Iterator<String> it = names.iterator(); it.hasNext(); idx++) { |
| final String propName = it.next(); |
| final PropertyDescriptor pd = icontext |
| .getPropertyDescriptor(propName); |
| newDescs[idx] = new PropertyDescriptor(pd.getName(), |
| pd.getReadMethod(), null); |
| } |
| icontext.addPropertyDescriptors(newDescs); |
| }; |
| PropertyUtils.clearDescriptors(); |
| PropertyUtils.addBeanIntrospector(bi); |
| final PropertyDescriptor[] desc2 = PropertyUtils |
| .getPropertyDescriptors(AlphaBean.class); |
| assertEquals("Different number of properties", desc1.length, |
| desc2.length); |
| nameDescriptor = findNameDescriptor(desc2); |
| assertNull("Got a write method", nameDescriptor.getWriteMethod()); |
| PropertyUtils.removeBeanIntrospector(bi); |
| } |
| |
| /** |
| * Finds the descriptor of the name property. |
| * |
| * @param desc the array with descriptors |
| * @return the found descriptor or null |
| */ |
| private static PropertyDescriptor findNameDescriptor( |
| final PropertyDescriptor[] desc) { |
| for (final PropertyDescriptor element : desc) { |
| if (element.getName().equals("name")) { |
| return element; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Tests whether exceptions during custom introspection are handled. |
| */ |
| public void testCustomIntrospectionEx() { |
| final BeanIntrospector bi = icontext -> { |
| throw new IntrospectionException("TestException"); |
| }; |
| PropertyUtils.clearDescriptors(); |
| PropertyUtils.addBeanIntrospector(bi); |
| final PropertyDescriptor[] desc = PropertyUtils |
| .getPropertyDescriptors(AlphaBean.class); |
| assertNotNull("Introspection did not work", findNameDescriptor(desc)); |
| PropertyUtils.removeBeanIntrospector(bi); |
| } |
| |
| /** |
| * Tests whether a BeanIntrospector can be removed. |
| */ |
| public void testRemoveBeanIntrospector() { |
| assertTrue( |
| "Wrong result", |
| PropertyUtils |
| .removeBeanIntrospector(DefaultBeanIntrospector.INSTANCE)); |
| final PropertyDescriptor[] desc = PropertyUtils |
| .getPropertyDescriptors(AlphaBean.class); |
| assertEquals("Got descriptors", 0, desc.length); |
| PropertyUtils.addBeanIntrospector(DefaultBeanIntrospector.INSTANCE); |
| } |
| |
| /** |
| * Tries to add a null BeanIntrospector. |
| */ |
| public void testAddBeanIntrospectorNull() { |
| try { |
| PropertyUtils.addBeanIntrospector(null); |
| fail("Could add null BeanIntrospector!"); |
| } catch (final IllegalArgumentException iex) { |
| // ok |
| } |
| } |
| |
| /** |
| * Tests whether a reset of the registered BeanIntrospectors can be performed. |
| */ |
| public void testResetBeanIntrospectors() { |
| assertTrue("Wrong result", |
| PropertyUtils.removeBeanIntrospector(DefaultBeanIntrospector.INSTANCE)); |
| PropertyUtils.resetBeanIntrospectors(); |
| final PropertyDescriptor[] desc = PropertyUtils.getPropertyDescriptors(AlphaBean.class); |
| assertTrue("Got no descriptors", desc.length > 0); |
| } |
| } |