0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017:
0018: package org.apache.commons.beanutils;
0019:
0020: import java.beans.PropertyDescriptor;
0021: import java.lang.reflect.InvocationTargetException;
0022: import java.lang.reflect.Method;
0023: import java.util.ArrayList;
0024: import java.util.Arrays;
0025: import java.util.HashMap;
0026: import java.util.List;
0027: import java.util.Map;
0028: import java.util.StringTokenizer;
0029:
0030: import org.apache.commons.beanutils.priv.PrivateBeanFactory;
0031: import org.apache.commons.beanutils.priv.PrivateDirect;
0032:
0033: import junit.framework.TestCase;
0034: import junit.framework.Test;
0035: import junit.framework.TestSuite;
0036:
0037: /**
0038: * <p>Test Case for the PropertyUtils class. The majority of these tests use
0039: * instances of the TestBean class, so be sure to update the tests if you
0040: * change the characteristics of that class.</p>
0041: *
0042: * <p>So far, this test case has tests for the following methods of the
0043: * <code>PropertyUtils</code> class:</p>
0044: * <ul>
0045: * <li>getIndexedProperty(Object,String)</li>
0046: * <li>getIndexedProperty(Object,String,int)</li>
0047: * <li>getMappedProperty(Object,String)</li>
0048: * <li>getMappedProperty(Object,String,String</li>
0049: * <li>getNestedProperty(Object,String)</li>
0050: * <li>getPropertyDescriptor(Object,String)</li>
0051: * <li>getPropertyDescriptors(Object)</li>
0052: * <li>getPropertyType(Object,String)</li>
0053: * <li>getSimpleProperty(Object,String)</li>
0054: * <li>setIndexedProperty(Object,String,Object)</li>
0055: * <li>setIndexedProperty(Object,String,String,Object)</li>
0056: * <li>setMappedProperty(Object,String,Object)</li>
0057: * <li>setMappedProperty(Object,String,String,Object)</li>
0058: * <li>setNestedProperty(Object,String,Object)</li>
0059: * <li>setSimpleProperty(Object,String,Object)</li>
0060: * </ul>
0061: *
0062: * @author Craig R. McClanahan
0063: * @author Jan Sorensen
0064: * @version $Revision: 555184 $ $Date: 2007-07-11 07:25:35 +0100 (Wed, 11 Jul 2007) $
0065: */
0066:
0067: public class PropertyUtilsTestCase extends TestCase {
0068:
0069: // ---------------------------------------------------- Instance Variables
0070:
0071: /**
0072: * The fully qualified class name of our private directly
0073: * implemented interface.
0074: */
0075: private static final String PRIVATE_DIRECT_CLASS = "org.apache.commons.beanutils.priv.PrivateDirect";
0076:
0077: /**
0078: * The fully qualified class name of our private indirectly
0079: * implemented interface.
0080: */
0081: private static final String PRIVATE_INDIRECT_CLASS = "org.apache.commons.beanutils.priv.PrivateIndirect";
0082:
0083: /**
0084: * The fully qualified class name of our test bean class.
0085: */
0086: private static final String TEST_BEAN_CLASS = "org.apache.commons.beanutils.TestBean";
0087:
0088: /**
0089: * The basic test bean for each test.
0090: */
0091: protected TestBean bean = null;
0092:
0093: /**
0094: * The "package private subclass" test bean for each test.
0095: */
0096: protected TestBeanPackageSubclass beanPackageSubclass = null;
0097:
0098: /**
0099: * The test bean for private access tests.
0100: */
0101: protected PrivateDirect beanPrivate = null;
0102:
0103: /**
0104: * The test bean for private access tests of subclasses.
0105: */
0106: protected PrivateDirect beanPrivateSubclass = null;
0107:
0108: /**
0109: * The "public subclass" test bean for each test.
0110: */
0111: protected TestBeanPublicSubclass beanPublicSubclass = null;
0112:
0113: /**
0114: * The set of properties that should be described.
0115: */
0116: protected String describes[] = { "booleanProperty",
0117: "booleanSecond", "doubleProperty", "floatProperty",
0118: "intArray",
0119: // "intIndexed",
0120: "intProperty", "listIndexed", "longProperty",
0121: // "mappedObjects",
0122: // "mappedProperty",
0123: // "mappedIntProperty",
0124: "nested", "nullProperty",
0125: // "readOnlyProperty",
0126: "shortProperty", "stringArray",
0127: // "stringIndexed",
0128: "stringProperty" };
0129:
0130: /**
0131: * The set of property names we expect to have returned when calling
0132: * <code>getPropertyDescriptors()</code>. You should update this list
0133: * when new properties are added to TestBean.
0134: */
0135: protected final static String[] properties = { "booleanProperty",
0136: "booleanSecond", "doubleProperty", "dupProperty",
0137: "floatProperty", "intArray", "intIndexed", "intProperty",
0138: "listIndexed", "longProperty", "nested", "nullProperty",
0139: "readOnlyProperty", "shortProperty", "stringArray",
0140: "stringIndexed", "stringProperty", "writeOnlyProperty", };
0141:
0142: // ---------------------------------------------------------- Constructors
0143:
0144: /**
0145: * Construct a new instance of this test case.
0146: *
0147: * @param name Name of the test case
0148: */
0149: public PropertyUtilsTestCase(String name) {
0150:
0151: super (name);
0152:
0153: }
0154:
0155: // -------------------------------------------------- Overall Test Methods
0156:
0157: /**
0158: * Set up instance variables required by this test case.
0159: */
0160: public void setUp() {
0161:
0162: bean = new TestBean();
0163: beanPackageSubclass = new TestBeanPackageSubclass();
0164: beanPrivate = PrivateBeanFactory.create();
0165: beanPrivateSubclass = PrivateBeanFactory.createSubclass();
0166: beanPublicSubclass = new TestBeanPublicSubclass();
0167:
0168: }
0169:
0170: /**
0171: * Return the tests included in this test suite.
0172: */
0173: public static Test suite() {
0174:
0175: return (new TestSuite(PropertyUtilsTestCase.class));
0176:
0177: }
0178:
0179: /**
0180: * Tear down instance variables required by this test case.
0181: */
0182: public void tearDown() {
0183:
0184: bean = null;
0185: beanPackageSubclass = null;
0186: beanPrivate = null;
0187: beanPrivateSubclass = null;
0188: beanPublicSubclass = null;
0189:
0190: }
0191:
0192: // ------------------------------------------------ Individual Test Methods
0193:
0194: /**
0195: * Test copyProperties() when the origin is a a <code>Map</code>.
0196: */
0197: public void testCopyPropertiesMap() {
0198:
0199: Map map = new HashMap();
0200: map.put("booleanProperty", Boolean.FALSE);
0201: map.put("doubleProperty", new Double(333.0));
0202: map.put("dupProperty",
0203: new String[] { "New 0", "New 1", "New 2" });
0204: map.put("floatProperty", new Float((float) 222.0));
0205: map.put("intArray", new int[] { 0, 100, 200 });
0206: map.put("intProperty", new Integer(111));
0207: map.put("longProperty", new Long(444));
0208: map.put("shortProperty", new Short((short) 555));
0209: map.put("stringProperty", "New String Property");
0210:
0211: try {
0212: PropertyUtils.copyProperties(bean, map);
0213: } catch (Throwable t) {
0214: fail("Threw " + t.toString());
0215: }
0216:
0217: // Scalar properties
0218: assertEquals("booleanProperty", false, bean
0219: .getBooleanProperty());
0220: assertEquals("doubleProperty", 333.0, bean.getDoubleProperty(),
0221: 0.005);
0222: assertEquals("floatProperty", (float) 222.0, bean
0223: .getFloatProperty(), (float) 0.005);
0224: assertEquals("intProperty", 111, bean.getIntProperty());
0225: assertEquals("longProperty", 444, bean.getLongProperty());
0226: assertEquals("shortProperty", (short) 555, bean
0227: .getShortProperty());
0228: assertEquals("stringProperty", "New String Property", bean
0229: .getStringProperty());
0230:
0231: // Indexed Properties
0232: String dupProperty[] = bean.getDupProperty();
0233: assertNotNull("dupProperty present", dupProperty);
0234: assertEquals("dupProperty length", 3, dupProperty.length);
0235: assertEquals("dupProperty[0]", "New 0", dupProperty[0]);
0236: assertEquals("dupProperty[1]", "New 1", dupProperty[1]);
0237: assertEquals("dupProperty[2]", "New 2", dupProperty[2]);
0238: int intArray[] = bean.getIntArray();
0239: assertNotNull("intArray present", intArray);
0240: assertEquals("intArray length", 3, intArray.length);
0241: assertEquals("intArray[0]", 0, intArray[0]);
0242: assertEquals("intArray[1]", 100, intArray[1]);
0243: assertEquals("intArray[2]", 200, intArray[2]);
0244:
0245: }
0246:
0247: /**
0248: * Test the describe() method.
0249: */
0250: public void testDescribe() {
0251:
0252: Map map = null;
0253: try {
0254: map = PropertyUtils.describe(bean);
0255: } catch (Exception e) {
0256: fail("Threw exception " + e);
0257: }
0258:
0259: // Verify existence of all the properties that should be present
0260: for (int i = 0; i < describes.length; i++) {
0261: assertTrue("Property '" + describes[i] + "' is present",
0262: map.containsKey(describes[i]));
0263: }
0264: assertTrue("Property 'writeOnlyProperty' is not present", !map
0265: .containsKey("writeOnlyProperty"));
0266:
0267: // Verify the values of scalar properties
0268: assertEquals("Value of 'booleanProperty'", Boolean.TRUE, map
0269: .get("booleanProperty"));
0270: assertEquals("Value of 'doubleProperty'", new Double(321.0),
0271: map.get("doubleProperty"));
0272: assertEquals("Value of 'floatProperty'", new Float(
0273: (float) 123.0), map.get("floatProperty"));
0274: assertEquals("Value of 'intProperty'", new Integer(123), map
0275: .get("intProperty"));
0276: assertEquals("Value of 'longProperty'", new Long(321), map
0277: .get("longProperty"));
0278: assertEquals("Value of 'shortProperty'",
0279: new Short((short) 987), map.get("shortProperty"));
0280: assertEquals("Value of 'stringProperty'", "This is a string",
0281: (String) map.get("stringProperty"));
0282:
0283: }
0284:
0285: /**
0286: * Corner cases on getPropertyDescriptor invalid arguments.
0287: */
0288: public void testGetDescriptorArguments() {
0289:
0290: try {
0291: PropertyUtils.getPropertyDescriptor(null, "stringProperty");
0292: fail("Should throw IllegalArgumentException 1");
0293: } catch (IllegalArgumentException e) {
0294: // Expected response
0295: } catch (Throwable t) {
0296: fail("Threw " + t
0297: + " instead of IllegalArgumentException 1");
0298: }
0299:
0300: try {
0301: PropertyUtils.getPropertyDescriptor(bean, null);
0302: fail("Should throw IllegalArgumentException 2");
0303: } catch (IllegalArgumentException e) {
0304: // Expected response
0305: } catch (Throwable t) {
0306: fail("Threw " + t
0307: + " instead of IllegalArgumentException 2");
0308: }
0309:
0310: }
0311:
0312: /**
0313: * Positive getPropertyDescriptor on property <code>booleanProperty</code>.
0314: */
0315: public void testGetDescriptorBoolean() {
0316:
0317: testGetDescriptorBase("booleanProperty", "getBooleanProperty",
0318: "setBooleanProperty");
0319:
0320: }
0321:
0322: /**
0323: * Positive getPropertyDescriptor on property <code>doubleProperty</code>.
0324: */
0325: public void testGetDescriptorDouble() {
0326:
0327: testGetDescriptorBase("doubleProperty", "getDoubleProperty",
0328: "setDoubleProperty");
0329:
0330: }
0331:
0332: /**
0333: * Positive getPropertyDescriptor on property <code>floatProperty</code>.
0334: */
0335: public void testGetDescriptorFloat() {
0336:
0337: testGetDescriptorBase("floatProperty", "getFloatProperty",
0338: "setFloatProperty");
0339:
0340: }
0341:
0342: /**
0343: * Positive getPropertyDescriptor on property <code>intProperty</code>.
0344: */
0345: public void testGetDescriptorInt() {
0346:
0347: testGetDescriptorBase("intProperty", "getIntProperty",
0348: "setIntProperty");
0349:
0350: }
0351:
0352: /**
0353: * <p>Negative tests on an invalid property with two different boolean
0354: * getters (which is fine, according to the JavaBeans spec) but a
0355: * String setter instead of a boolean setter.</p>
0356: *
0357: * <p>Although one could logically argue that this combination of method
0358: * signatures should not identify a property at all, there is a sentence
0359: * in Section 8.3.1 making it clear that the behavior tested for here
0360: * is correct: "If we find only one of these methods, then we regard
0361: * it as defining either a read-only or write-only property called
0362: * <em><property-name></em>.</p>
0363: */
0364: public void testGetDescriptorInvalidBoolean() throws Exception {
0365:
0366: PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(
0367: bean, "invalidBoolean");
0368: assertNotNull("invalidBoolean is a property", pd);
0369: assertNotNull("invalidBoolean has a getter method", pd
0370: .getReadMethod());
0371: assertNull("invalidBoolean has no write method", pd
0372: .getWriteMethod());
0373: assertTrue("invalidBoolean getter method is isInvalidBoolean",
0374: "isInvalidBoolean".equals(pd.getReadMethod().getName()));
0375:
0376: }
0377:
0378: /**
0379: * Positive getPropertyDescriptor on property <code>longProperty</code>.
0380: */
0381: public void testGetDescriptorLong() {
0382:
0383: testGetDescriptorBase("longProperty", "getLongProperty",
0384: "setLongProperty");
0385:
0386: }
0387:
0388: /**
0389: * Test getting mapped descriptor with periods in the key.
0390: */
0391: public void testGetDescriptorMappedPeriods() {
0392:
0393: bean.getMappedIntProperty("xyz"); // initializes mappedIntProperty
0394:
0395: PropertyDescriptor desc;
0396: Integer testIntegerValue = new Integer(1234);
0397:
0398: bean.setMappedIntProperty("key.with.a.dot", testIntegerValue
0399: .intValue());
0400: assertEquals(
0401: "Can retrieve directly",
0402: testIntegerValue,
0403: new Integer(bean.getMappedIntProperty("key.with.a.dot")));
0404: try {
0405: desc = PropertyUtils.getPropertyDescriptor(bean,
0406: "mappedIntProperty(key.with.a.dot)");
0407: assertEquals("Check descriptor type (A)", Integer.TYPE,
0408: ((MappedPropertyDescriptor) desc)
0409: .getMappedPropertyType());
0410: } catch (Exception e) {
0411: fail("Threw exception (A): " + e);
0412: }
0413:
0414: bean.setMappedObjects("nested.property", new TestBean(
0415: testIntegerValue.intValue()));
0416: assertEquals("Can retrieve directly", testIntegerValue,
0417: new Integer(((TestBean) bean
0418: .getMappedObjects("nested.property"))
0419: .getIntProperty()));
0420: try {
0421: desc = PropertyUtils.getPropertyDescriptor(bean,
0422: "mappedObjects(nested.property).intProperty");
0423: assertEquals("Check descriptor type (B)", Integer.TYPE,
0424: desc.getPropertyType());
0425: } catch (Exception e) {
0426: fail("Threw exception (B): " + e);
0427: }
0428: }
0429:
0430: /**
0431: * Positive getPropertyDescriptor on property
0432: * <code>readOnlyProperty</code>.
0433: */
0434: public void testGetDescriptorReadOnly() {
0435:
0436: testGetDescriptorBase("readOnlyProperty",
0437: "getReadOnlyProperty", null);
0438:
0439: }
0440:
0441: /**
0442: * Positive getPropertyDescriptor on property <code>booleanSecond</code>
0443: * that uses an "is" method as the getter.
0444: */
0445: public void testGetDescriptorSecond() {
0446:
0447: testGetDescriptorBase("booleanSecond", "isBooleanSecond",
0448: "setBooleanSecond");
0449:
0450: }
0451:
0452: /**
0453: * Positive getPropertyDescriptor on property <code>shortProperty</code>.
0454: */
0455: public void testGetDescriptorShort() {
0456:
0457: testGetDescriptorBase("shortProperty", "getShortProperty",
0458: "setShortProperty");
0459:
0460: }
0461:
0462: /**
0463: * Positive getPropertyDescriptor on property <code>stringProperty</code>.
0464: */
0465: public void testGetDescriptorString() {
0466:
0467: testGetDescriptorBase("stringProperty", "getStringProperty",
0468: "setStringProperty");
0469:
0470: }
0471:
0472: /**
0473: * Negative getPropertyDescriptor on property <code>unknown</code>.
0474: */
0475: public void testGetDescriptorUnknown() {
0476:
0477: testGetDescriptorBase("unknown", null, null);
0478:
0479: }
0480:
0481: /**
0482: * Positive getPropertyDescriptor on property
0483: * <code>writeOnlyProperty</code>.
0484: */
0485: public void testGetDescriptorWriteOnly() {
0486:
0487: testGetDescriptorBase("writeOnlyProperty", null,
0488: "setWriteOnlyProperty");
0489:
0490: }
0491:
0492: /**
0493: * Positive test for getPropertyDescriptors(). Each property name
0494: * listed in <code>properties</code> should be returned exactly once.
0495: */
0496: public void testGetDescriptors() {
0497:
0498: PropertyDescriptor pd[] = PropertyUtils
0499: .getPropertyDescriptors(bean);
0500: assertNotNull("Got descriptors", pd);
0501: int count[] = new int[properties.length];
0502: for (int i = 0; i < pd.length; i++) {
0503: String name = pd[i].getName();
0504: for (int j = 0; j < properties.length; j++) {
0505: if (name.equals(properties[j]))
0506: count[j]++;
0507: }
0508: }
0509: for (int j = 0; j < properties.length; j++) {
0510: if (count[j] < 0)
0511: fail("Missing property " + properties[j]);
0512: else if (count[j] > 1)
0513: fail("Duplicate property " + properties[j]);
0514: }
0515:
0516: }
0517:
0518: /**
0519: * Corner cases on getPropertyDescriptors invalid arguments.
0520: */
0521: public void testGetDescriptorsArguments() {
0522:
0523: try {
0524: PropertyUtils.getPropertyDescriptors(null);
0525: fail("Should throw IllegalArgumentException");
0526: } catch (IllegalArgumentException e) {
0527: // Expected response
0528: } catch (Throwable t) {
0529: fail("Threw " + t + " instead of IllegalArgumentException");
0530: }
0531:
0532: }
0533:
0534: /**
0535: * Corner cases on getIndexedProperty invalid arguments.
0536: */
0537: public void testGetIndexedArguments() {
0538:
0539: // Use explicit index argument
0540:
0541: try {
0542: PropertyUtils.getIndexedProperty(null, "intArray", 0);
0543: fail("Should throw IllegalArgumentException 1");
0544: } catch (IllegalArgumentException e) {
0545: // Expected response
0546: } catch (Throwable t) {
0547: fail("Threw " + t
0548: + " instead of IllegalArgumentException 1");
0549: }
0550:
0551: try {
0552: PropertyUtils.getIndexedProperty(bean, null, 0);
0553: fail("Should throw IllegalArgumentException 2");
0554: } catch (IllegalArgumentException e) {
0555: // Expected response
0556: } catch (Throwable t) {
0557: fail("Threw " + t
0558: + " instead of IllegalArgumentException 2");
0559: }
0560:
0561: // Use index expression
0562:
0563: try {
0564: PropertyUtils.getIndexedProperty(null, "intArray[0]");
0565: fail("Should throw IllegalArgumentException 3");
0566: } catch (IllegalArgumentException e) {
0567: // Expected response
0568: } catch (Throwable t) {
0569: fail("Threw " + t
0570: + " instead of IllegalArgumentException 3");
0571: }
0572:
0573: try {
0574: PropertyUtils.getIndexedProperty(bean, "[0]");
0575: fail("Should throw NoSuchMethodException 4");
0576: } catch (NoSuchMethodException e) {
0577: // Expected response
0578: } catch (Throwable t) {
0579: fail("Threw " + t + " instead of NoSuchMethodException 4");
0580: }
0581:
0582: try {
0583: PropertyUtils.getIndexedProperty(bean, "intArray");
0584: fail("Should throw IllegalArgumentException 5");
0585: } catch (IllegalArgumentException e) {
0586: // Expected response
0587: } catch (Throwable t) {
0588: fail("Threw " + t
0589: + " instead of IllegalArgumentException 5");
0590: }
0591:
0592: // Use explicit index argument
0593:
0594: try {
0595: PropertyUtils.getIndexedProperty(null, "intIndexed", 0);
0596: fail("Should throw IllegalArgumentException 1");
0597: } catch (IllegalArgumentException e) {
0598: // Expected response
0599: } catch (Throwable t) {
0600: fail("Threw " + t
0601: + " instead of IllegalArgumentException 1");
0602: }
0603:
0604: try {
0605: PropertyUtils.getIndexedProperty(bean, null, 0);
0606: fail("Should throw IllegalArgumentException 2");
0607: } catch (IllegalArgumentException e) {
0608: // Expected response
0609: } catch (Throwable t) {
0610: fail("Threw " + t
0611: + " instead of IllegalArgumentException 2");
0612: }
0613:
0614: // Use index expression
0615:
0616: try {
0617: PropertyUtils.getIndexedProperty(null, "intIndexed[0]");
0618: fail("Should throw IllegalArgumentException 3");
0619: } catch (IllegalArgumentException e) {
0620: // Expected response
0621: } catch (Throwable t) {
0622: fail("Threw " + t
0623: + " instead of IllegalArgumentException 3");
0624: }
0625:
0626: try {
0627: PropertyUtils.getIndexedProperty(bean, "[0]");
0628: fail("Should throw NoSuchMethodException 4");
0629: } catch (NoSuchMethodException e) {
0630: // Expected response
0631: } catch (Throwable t) {
0632: fail("Threw " + t + " instead of NoSuchMethodException 4");
0633: }
0634:
0635: try {
0636: PropertyUtils.getIndexedProperty(bean, "intIndexed");
0637: fail("Should throw IllegalArgumentException 5");
0638: } catch (IllegalArgumentException e) {
0639: // Expected response
0640: } catch (Throwable t) {
0641: fail("Threw " + t
0642: + " instead of IllegalArgumentException 5");
0643: }
0644:
0645: }
0646:
0647: /**
0648: * Positive and negative tests on getIndexedProperty valid arguments.
0649: */
0650: public void testGetIndexedValues() {
0651:
0652: Object value = null;
0653:
0654: // Use explicit key argument
0655:
0656: for (int i = 0; i < 5; i++) {
0657:
0658: try {
0659: value = PropertyUtils.getIndexedProperty(bean,
0660: "dupProperty", i);
0661: assertNotNull("dupProperty returned value " + i, value);
0662: assertTrue("dupProperty returned String " + i,
0663: value instanceof String);
0664: assertEquals("dupProperty returned correct " + i,
0665: "Dup " + i, (String) value);
0666: } catch (Throwable t) {
0667: fail("dupProperty " + i + " threw " + t);
0668: }
0669:
0670: try {
0671: value = PropertyUtils.getIndexedProperty(bean,
0672: "intArray", i);
0673: assertNotNull("intArray returned value " + i, value);
0674: assertTrue("intArray returned Integer " + i,
0675: value instanceof Integer);
0676: assertEquals("intArray returned correct " + i, i * 10,
0677: ((Integer) value).intValue());
0678: } catch (Throwable t) {
0679: fail("intArray " + i + " threw " + t);
0680: }
0681:
0682: try {
0683: value = PropertyUtils.getIndexedProperty(bean,
0684: "intIndexed", i);
0685: assertNotNull("intIndexed returned value " + i, value);
0686: assertTrue("intIndexed returned Integer " + i,
0687: value instanceof Integer);
0688: assertEquals("intIndexed returned correct " + i,
0689: i * 10, ((Integer) value).intValue());
0690: } catch (Throwable t) {
0691: fail("intIndexed " + i + " threw " + t);
0692: }
0693:
0694: try {
0695: value = PropertyUtils.getIndexedProperty(bean,
0696: "listIndexed", i);
0697: assertNotNull("listIndexed returned value " + i, value);
0698: assertTrue("list returned String " + i,
0699: value instanceof String);
0700: assertEquals("listIndexed returned correct " + i,
0701: "String " + i, (String) value);
0702: } catch (Throwable t) {
0703: fail("listIndexed " + i + " threw " + t);
0704: }
0705:
0706: try {
0707: value = PropertyUtils.getIndexedProperty(bean,
0708: "stringArray", i);
0709: assertNotNull("stringArray returned value " + i, value);
0710: assertTrue("stringArray returned String " + i,
0711: value instanceof String);
0712: assertEquals("stringArray returned correct " + i,
0713: "String " + i, (String) value);
0714: } catch (Throwable t) {
0715: fail("stringArray " + i + " threw " + t);
0716: }
0717:
0718: try {
0719: value = PropertyUtils.getIndexedProperty(bean,
0720: "stringIndexed", i);
0721: assertNotNull("stringIndexed returned value " + i,
0722: value);
0723: assertTrue("stringIndexed returned String " + i,
0724: value instanceof String);
0725: assertEquals("stringIndexed returned correct " + i,
0726: "String " + i, (String) value);
0727: } catch (Throwable t) {
0728: fail("stringIndexed " + i + " threw " + t);
0729: }
0730:
0731: }
0732:
0733: // Use key expression
0734:
0735: for (int i = 0; i < 5; i++) {
0736:
0737: try {
0738: value = PropertyUtils.getIndexedProperty(bean,
0739: "dupProperty[" + i + "]");
0740: assertNotNull("dupProperty returned value " + i, value);
0741: assertTrue("dupProperty returned String " + i,
0742: value instanceof String);
0743: assertEquals("dupProperty returned correct " + i,
0744: "Dup " + i, (String) value);
0745: } catch (Throwable t) {
0746: fail("dupProperty " + i + " threw " + t);
0747: }
0748:
0749: try {
0750: value = PropertyUtils.getIndexedProperty(bean,
0751: "intArray[" + i + "]");
0752: assertNotNull("intArray returned value " + i, value);
0753: assertTrue("intArray returned Integer " + i,
0754: value instanceof Integer);
0755: assertEquals("intArray returned correct " + i, i * 10,
0756: ((Integer) value).intValue());
0757: } catch (Throwable t) {
0758: fail("intArray " + i + " threw " + t);
0759: }
0760:
0761: try {
0762: value = PropertyUtils.getIndexedProperty(bean,
0763: "intIndexed[" + i + "]");
0764: assertNotNull("intIndexed returned value " + i, value);
0765: assertTrue("intIndexed returned Integer " + i,
0766: value instanceof Integer);
0767: assertEquals("intIndexed returned correct " + i,
0768: i * 10, ((Integer) value).intValue());
0769: } catch (Throwable t) {
0770: fail("intIndexed " + i + " threw " + t);
0771: }
0772:
0773: try {
0774: value = PropertyUtils.getIndexedProperty(bean,
0775: "listIndexed[" + i + "]");
0776: assertNotNull("listIndexed returned value " + i, value);
0777: assertTrue("listIndexed returned String " + i,
0778: value instanceof String);
0779: assertEquals("listIndexed returned correct " + i,
0780: "String " + i, (String) value);
0781: } catch (Throwable t) {
0782: fail("listIndexed " + i + " threw " + t);
0783: }
0784:
0785: try {
0786: value = PropertyUtils.getIndexedProperty(bean,
0787: "stringArray[" + i + "]");
0788: assertNotNull("stringArray returned value " + i, value);
0789: assertTrue("stringArray returned String " + i,
0790: value instanceof String);
0791: assertEquals("stringArray returned correct " + i,
0792: "String " + i, (String) value);
0793: } catch (Throwable t) {
0794: fail("stringArray " + i + " threw " + t);
0795: }
0796:
0797: try {
0798: value = PropertyUtils.getIndexedProperty(bean,
0799: "stringIndexed[" + i + "]");
0800: assertNotNull("stringIndexed returned value " + i,
0801: value);
0802: assertTrue("stringIndexed returned String " + i,
0803: value instanceof String);
0804: assertEquals("stringIndexed returned correct " + i,
0805: "String " + i, (String) value);
0806: } catch (Throwable t) {
0807: fail("stringIndexed " + i + " threw " + t);
0808: }
0809:
0810: }
0811:
0812: // Index out of bounds tests
0813:
0814: try {
0815: value = PropertyUtils.getIndexedProperty(bean,
0816: "dupProperty", -1);
0817: fail("Should have thrown ArrayIndexOutOfBoundsException");
0818: } catch (ArrayIndexOutOfBoundsException t) {
0819: // Expected results
0820: } catch (Throwable t) {
0821: fail("Threw " + t
0822: + " instead of ArrayIndexOutOfBoundsException");
0823: }
0824:
0825: try {
0826: value = PropertyUtils.getIndexedProperty(bean,
0827: "dupProperty", 5);
0828: fail("Should have thrown ArrayIndexOutOfBoundsException");
0829: } catch (ArrayIndexOutOfBoundsException t) {
0830: // Expected results
0831: } catch (Throwable t) {
0832: fail("Threw " + t
0833: + " instead of ArrayIndexOutOfBoundsException");
0834: }
0835:
0836: try {
0837: value = PropertyUtils.getIndexedProperty(bean, "intArray",
0838: -1);
0839: fail("Should have thrown ArrayIndexOutOfBoundsException");
0840: } catch (ArrayIndexOutOfBoundsException t) {
0841: // Expected results
0842: } catch (Throwable t) {
0843: fail("Threw " + t
0844: + " instead of ArrayIndexOutOfBoundsException");
0845: }
0846:
0847: try {
0848: value = PropertyUtils.getIndexedProperty(bean, "intArray",
0849: 5);
0850: fail("Should have thrown ArrayIndexOutOfBoundsException");
0851: } catch (ArrayIndexOutOfBoundsException t) {
0852: // Expected results
0853: } catch (Throwable t) {
0854: fail("Threw " + t
0855: + " instead of ArrayIndexOutOfBoundsException");
0856: }
0857:
0858: try {
0859: value = PropertyUtils.getIndexedProperty(bean,
0860: "intIndexed", -1);
0861: fail("Should have thrown ArrayIndexOutOfBoundsException");
0862: } catch (ArrayIndexOutOfBoundsException t) {
0863: // Expected results
0864: } catch (Throwable t) {
0865: fail("Threw " + t
0866: + " instead of ArrayIndexOutOfBoundsException");
0867: }
0868:
0869: try {
0870: value = PropertyUtils.getIndexedProperty(bean,
0871: "intIndexed", 5);
0872: fail("Should have thrown ArrayIndexOutOfBoundsException");
0873: } catch (ArrayIndexOutOfBoundsException t) {
0874: // Expected results
0875: } catch (Throwable t) {
0876: fail("Threw " + t
0877: + " instead of ArrayIndexOutOfBoundsException");
0878: }
0879:
0880: try {
0881: value = PropertyUtils.getIndexedProperty(bean,
0882: "listIndexed", -1);
0883: fail("Should have thrown IndexOutOfBoundsException");
0884: } catch (IndexOutOfBoundsException t) {
0885: // Expected results
0886: } catch (Throwable t) {
0887: fail("Threw " + t + " instead of IndexOutOfBoundsException");
0888: }
0889:
0890: try {
0891: value = PropertyUtils.getIndexedProperty(bean,
0892: "listIndexed", 5);
0893: fail("Should have thrown IndexOutOfBoundsException");
0894: } catch (IndexOutOfBoundsException t) {
0895: // Expected results
0896: } catch (Throwable t) {
0897: fail("Threw " + t + " instead of IndexOutOfBoundsException");
0898: }
0899:
0900: try {
0901: value = PropertyUtils.getIndexedProperty(bean,
0902: "stringArray", -1);
0903: fail("Should have thrown ArrayIndexOutOfBoundsException");
0904: } catch (ArrayIndexOutOfBoundsException t) {
0905: // Expected results
0906: } catch (Throwable t) {
0907: fail("Threw " + t
0908: + " instead of ArrayIndexOutOfBoundsException");
0909: }
0910:
0911: try {
0912: value = PropertyUtils.getIndexedProperty(bean,
0913: "stringArray", 5);
0914: fail("Should have thrown ArrayIndexOutOfBoundsException");
0915: } catch (ArrayIndexOutOfBoundsException t) {
0916: // Expected results
0917: } catch (Throwable t) {
0918: fail("Threw " + t
0919: + " instead of ArrayIndexOutOfBoundsException");
0920: }
0921:
0922: try {
0923: value = PropertyUtils.getIndexedProperty(bean,
0924: "stringIndexed", -1);
0925: fail("Should have thrown ArrayIndexOutOfBoundsException");
0926: } catch (ArrayIndexOutOfBoundsException t) {
0927: // Expected results
0928: } catch (Throwable t) {
0929: fail("Threw " + t
0930: + " instead of ArrayIndexOutOfBoundsException");
0931: }
0932:
0933: try {
0934: value = PropertyUtils.getIndexedProperty(bean,
0935: "stringIndexed", 5);
0936: fail("Should have thrown ArrayIndexOutOfBoundsException");
0937: } catch (ArrayIndexOutOfBoundsException t) {
0938: // Expected results
0939: } catch (Throwable t) {
0940: fail("Threw " + t
0941: + " instead of ArrayIndexOutOfBoundsException");
0942: }
0943:
0944: }
0945:
0946: /**
0947: * Test getting an indexed value out of a multi-dimensional array
0948: */
0949: public void testGetIndexedArray() {
0950: String[] firstArray = new String[] { "FIRST-1", "FIRST-2",
0951: "FIRST-3" };
0952: String[] secondArray = new String[] { "SECOND-1", "SECOND-2",
0953: "SECOND-3", "SECOND-4" };
0954: String[][] mainArray = { firstArray, secondArray };
0955: TestBean bean = new TestBean(mainArray);
0956: try {
0957: assertEquals("firstArray[0]", firstArray[0], PropertyUtils
0958: .getProperty(bean, "string2dArray[0][0]"));
0959: assertEquals("firstArray[1]", firstArray[1], PropertyUtils
0960: .getProperty(bean, "string2dArray[0][1]"));
0961: assertEquals("firstArray[2]", firstArray[2], PropertyUtils
0962: .getProperty(bean, "string2dArray[0][2]"));
0963: assertEquals("secondArray[0]", secondArray[0],
0964: PropertyUtils.getProperty(bean,
0965: "string2dArray[1][0]"));
0966: assertEquals("secondArray[1]", secondArray[1],
0967: PropertyUtils.getProperty(bean,
0968: "string2dArray[1][1]"));
0969: assertEquals("secondArray[2]", secondArray[2],
0970: PropertyUtils.getProperty(bean,
0971: "string2dArray[1][2]"));
0972: assertEquals("secondArray[3]", secondArray[3],
0973: PropertyUtils.getProperty(bean,
0974: "string2dArray[1][3]"));
0975: } catch (Throwable t) {
0976: fail("Threw " + t + "");
0977: }
0978: }
0979:
0980: /**
0981: * Test getting an indexed value out of List of Lists
0982: */
0983: public void testGetIndexedList() {
0984: String[] firstArray = new String[] { "FIRST-1", "FIRST-2",
0985: "FIRST-3" };
0986: String[] secondArray = new String[] { "SECOND-1", "SECOND-2",
0987: "SECOND-3", "SECOND-4" };
0988: List mainList = new ArrayList();
0989: mainList.add(Arrays.asList(firstArray));
0990: mainList.add(Arrays.asList(secondArray));
0991: TestBean bean = new TestBean(mainList);
0992: try {
0993: assertEquals("firstArray[0]", firstArray[0], PropertyUtils
0994: .getProperty(bean, "listIndexed[0][0]"));
0995: assertEquals("firstArray[1]", firstArray[1], PropertyUtils
0996: .getProperty(bean, "listIndexed[0][1]"));
0997: assertEquals("firstArray[2]", firstArray[2], PropertyUtils
0998: .getProperty(bean, "listIndexed[0][2]"));
0999: assertEquals("secondArray[0]", secondArray[0],
1000: PropertyUtils
1001: .getProperty(bean, "listIndexed[1][0]"));
1002: assertEquals("secondArray[1]", secondArray[1],
1003: PropertyUtils
1004: .getProperty(bean, "listIndexed[1][1]"));
1005: assertEquals("secondArray[2]", secondArray[2],
1006: PropertyUtils
1007: .getProperty(bean, "listIndexed[1][2]"));
1008: assertEquals("secondArray[3]", secondArray[3],
1009: PropertyUtils
1010: .getProperty(bean, "listIndexed[1][3]"));
1011: } catch (Throwable t) {
1012: fail("Threw " + t + "");
1013: }
1014: }
1015:
1016: /**
1017: * Test getting a value out of a mapped Map
1018: */
1019: public void testGetIndexedMap() {
1020: Map firstMap = new HashMap();
1021: firstMap.put("FIRST-KEY-1", "FIRST-VALUE-1");
1022: firstMap.put("FIRST-KEY-2", "FIRST-VALUE-2");
1023: Map secondMap = new HashMap();
1024: secondMap.put("SECOND-KEY-1", "SECOND-VALUE-1");
1025: secondMap.put("SECOND-KEY-2", "SECOND-VALUE-2");
1026:
1027: List mainList = new ArrayList();
1028: mainList.add(firstMap);
1029: mainList.add(secondMap);
1030: TestBean bean = new TestBean(mainList);
1031: try {
1032: assertEquals("listIndexed[0](FIRST-KEY-1)",
1033: "FIRST-VALUE-1", PropertyUtils.getProperty(bean,
1034: "listIndexed[0](FIRST-KEY-1)"));
1035: assertEquals("listIndexed[0](FIRST-KEY-2)",
1036: "FIRST-VALUE-2", PropertyUtils.getProperty(bean,
1037: "listIndexed[0](FIRST-KEY-2)"));
1038: assertEquals("listIndexed[1](SECOND-KEY-1)",
1039: "SECOND-VALUE-1", PropertyUtils.getProperty(bean,
1040: "listIndexed[1](SECOND-KEY-1)"));
1041: assertEquals("listIndexed[1](SECOND-KEY-2)",
1042: "SECOND-VALUE-2", PropertyUtils.getProperty(bean,
1043: "listIndexed[1](SECOND-KEY-2)"));
1044: } catch (Throwable t) {
1045: fail("Threw " + t + "");
1046: }
1047: }
1048:
1049: /**
1050: * Corner cases on getMappedProperty invalid arguments.
1051: */
1052: public void testGetMappedArguments() {
1053:
1054: // Use explicit key argument
1055:
1056: try {
1057: PropertyUtils.getMappedProperty(null, "mappedProperty",
1058: "First Key");
1059: fail("Should throw IllegalArgumentException 1");
1060: } catch (IllegalArgumentException e) {
1061: // Expected response
1062: } catch (Throwable t) {
1063: fail("Threw " + t
1064: + " instead of IllegalArgumentException 1");
1065: }
1066:
1067: try {
1068: PropertyUtils.getMappedProperty(bean, null, "First Key");
1069: fail("Should throw IllegalArgumentException 2");
1070: } catch (IllegalArgumentException e) {
1071: // Expected response
1072: } catch (Throwable t) {
1073: fail("Threw " + t
1074: + " instead of IllegalArgumentException 2");
1075: }
1076:
1077: try {
1078: PropertyUtils.getMappedProperty(bean, "mappedProperty",
1079: null);
1080: fail("Should throw IllegalArgumentException 3");
1081: } catch (IllegalArgumentException e) {
1082: // Expected response
1083: } catch (Throwable t) {
1084: fail("Threw " + t
1085: + " instead of IllegalArgumentException 3");
1086: }
1087:
1088: // Use key expression
1089:
1090: try {
1091: PropertyUtils.getMappedProperty(null,
1092: "mappedProperty(First Key)");
1093: fail("Should throw IllegalArgumentException 4");
1094: } catch (IllegalArgumentException e) {
1095: // Expected response
1096: } catch (Throwable t) {
1097: fail("Threw " + t
1098: + " instead of IllegalArgumentException 4");
1099: }
1100:
1101: try {
1102: PropertyUtils.getMappedProperty(bean, "(Second Key)");
1103: fail("Should throw IllegalArgumentException 5");
1104: } catch (NoSuchMethodException e) {
1105: // Expected response
1106: } catch (Throwable t) {
1107: fail("Threw " + t + " instead of NoSuchMethodException 5");
1108: }
1109:
1110: try {
1111: PropertyUtils.getMappedProperty(bean, "mappedProperty");
1112: fail("Should throw IllegalArgumentException 6");
1113: } catch (IllegalArgumentException e) {
1114: // Expected response
1115: } catch (Throwable t) {
1116: fail("Threw " + t
1117: + " instead of IllegalArgumentException 6");
1118: }
1119:
1120: }
1121:
1122: /**
1123: * Test getting an indexed value out of a mapped array
1124: */
1125: public void testGetMappedArray() {
1126: TestBean bean = new TestBean();
1127: String[] array = new String[] { "abc", "def", "ghi" };
1128: bean.getMapProperty().put("mappedArray", array);
1129: try {
1130: assertEquals("abc", PropertyUtils.getProperty(bean,
1131: "mapProperty(mappedArray)[0]"));
1132: assertEquals("def", PropertyUtils.getProperty(bean,
1133: "mapProperty(mappedArray)[1]"));
1134: assertEquals("ghi", PropertyUtils.getProperty(bean,
1135: "mapProperty(mappedArray)[2]"));
1136: } catch (Throwable t) {
1137: fail("Threw " + t + "");
1138: }
1139: }
1140:
1141: /**
1142: * Test getting an indexed value out of a mapped List
1143: */
1144: public void testGetMappedList() {
1145: TestBean bean = new TestBean();
1146: List list = new ArrayList();
1147: list.add("klm");
1148: list.add("nop");
1149: list.add("qrs");
1150: bean.getMapProperty().put("mappedList", list);
1151: try {
1152: assertEquals("klm", PropertyUtils.getProperty(bean,
1153: "mapProperty(mappedList)[0]"));
1154: assertEquals("nop", PropertyUtils.getProperty(bean,
1155: "mapProperty(mappedList)[1]"));
1156: assertEquals("qrs", PropertyUtils.getProperty(bean,
1157: "mapProperty(mappedList)[2]"));
1158: } catch (Throwable t) {
1159: fail("Threw " + t + "");
1160: }
1161: }
1162:
1163: /**
1164: * Test getting a value out of a mapped Map
1165: */
1166: public void testGetMappedMap() {
1167: TestBean bean = new TestBean();
1168: Map map = new HashMap();
1169: map.put("sub-key-1", "sub-value-1");
1170: map.put("sub-key-2", "sub-value-2");
1171: map.put("sub-key-3", "sub-value-3");
1172: bean.getMapProperty().put("mappedMap", map);
1173: try {
1174: assertEquals("sub-value-1", PropertyUtils.getProperty(bean,
1175: "mapProperty(mappedMap)(sub-key-1)"));
1176: assertEquals("sub-value-2", PropertyUtils.getProperty(bean,
1177: "mapProperty(mappedMap)(sub-key-2)"));
1178: assertEquals("sub-value-3", PropertyUtils.getProperty(bean,
1179: "mapProperty(mappedMap)(sub-key-3)"));
1180: } catch (Throwable t) {
1181: fail("Threw " + t + "");
1182: }
1183: }
1184:
1185: /**
1186: * Test getting mapped values with periods in the key.
1187: */
1188: public void testGetMappedPeriods() {
1189:
1190: bean.setMappedProperty("key.with.a.dot", "Special Value");
1191: assertEquals("Can retrieve directly", "Special Value", bean
1192: .getMappedProperty("key.with.a.dot"));
1193: try {
1194: assertEquals("Can retrieve via getMappedProperty",
1195: "Special Value", PropertyUtils.getMappedProperty(
1196: bean, "mappedProperty", "key.with.a.dot"));
1197: } catch (Exception e) {
1198: fail("Thew exception: " + e);
1199: }
1200: try {
1201: assertEquals("Can retrieve via getNestedProperty",
1202: "Special Value", PropertyUtils.getNestedProperty(
1203: bean, "mappedProperty(key.with.a.dot)"));
1204: } catch (Exception e) {
1205: fail("Thew exception: " + e);
1206: }
1207:
1208: bean.setMappedObjects("nested.property", new TestBean());
1209: assertNotNull("Can retrieve directly", bean
1210: .getMappedObjects("nested.property"));
1211: try {
1212: assertEquals(
1213: "Can retrieve nested",
1214: "This is a string",
1215: PropertyUtils
1216: .getNestedProperty(bean,
1217: "mappedObjects(nested.property).stringProperty"));
1218: } catch (Exception e) {
1219: fail("Thew exception: " + e);
1220: }
1221:
1222: try {
1223: assertEquals("Can't retrieved nested with mapped property",
1224: "Mapped Value", PropertyUtils.getNestedProperty(
1225: bean, "mappedNested.value(Mapped Key)"));
1226: } catch (Exception e) {
1227: fail("Thew exception: " + e);
1228: }
1229: }
1230:
1231: /**
1232: * Test getting mapped values with slashes in the key. This is different
1233: * from periods because slashes are not syntactically significant.
1234: */
1235: public void testGetMappedSlashes() {
1236:
1237: bean.setMappedProperty("key/with/a/slash", "Special Value");
1238: assertEquals("Can retrieve directly", "Special Value", bean
1239: .getMappedProperty("key/with/a/slash"));
1240: try {
1241: assertEquals("Can retrieve via getMappedProperty",
1242: "Special Value", PropertyUtils.getMappedProperty(
1243: bean, "mappedProperty", "key/with/a/slash"));
1244: } catch (Exception e) {
1245: fail("Thew exception: " + e);
1246: }
1247: try {
1248: assertEquals("Can retrieve via getNestedProperty",
1249: "Special Value", PropertyUtils.getNestedProperty(
1250: bean, "mappedProperty(key/with/a/slash)"));
1251: } catch (Exception e) {
1252: fail("Thew exception: " + e);
1253: }
1254:
1255: bean.setMappedObjects("nested/property", new TestBean());
1256: assertNotNull("Can retrieve directly", bean
1257: .getMappedObjects("nested/property"));
1258: try {
1259: assertEquals(
1260: "Can retrieve nested",
1261: "This is a string",
1262: PropertyUtils
1263: .getNestedProperty(bean,
1264: "mappedObjects(nested/property).stringProperty"));
1265: } catch (Exception e) {
1266: fail("Thew exception: " + e);
1267: }
1268:
1269: }
1270:
1271: /**
1272: * Positive and negative tests on getMappedProperty valid arguments.
1273: */
1274: public void testGetMappedValues() {
1275:
1276: Object value = null;
1277:
1278: // Use explicit key argument
1279:
1280: try {
1281: value = PropertyUtils.getMappedProperty(bean,
1282: "mappedProperty", "First Key");
1283: assertEquals("Can find first value", "First Value", value);
1284: } catch (Throwable t) {
1285: fail("Finding first value threw " + t);
1286: }
1287:
1288: try {
1289: value = PropertyUtils.getMappedProperty(bean,
1290: "mappedProperty", "Second Key");
1291: assertEquals("Can find second value", "Second Value", value);
1292: } catch (Throwable t) {
1293: fail("Finding second value threw " + t);
1294: }
1295:
1296: try {
1297: value = PropertyUtils.getMappedProperty(bean,
1298: "mappedProperty", "Third Key");
1299: assertNull("Can not find third value", value);
1300: } catch (Throwable t) {
1301: fail("Finding third value threw " + t);
1302: }
1303:
1304: // Use key expression with parentheses
1305:
1306: try {
1307: value = PropertyUtils.getMappedProperty(bean,
1308: "mappedProperty(First Key)");
1309: assertEquals("Can find first value", "First Value", value);
1310: } catch (Throwable t) {
1311: fail("Finding first value threw " + t);
1312: }
1313:
1314: try {
1315: value = PropertyUtils.getMappedProperty(bean,
1316: "mappedProperty(Second Key)");
1317: assertEquals("Can find second value", "Second Value", value);
1318: } catch (Throwable t) {
1319: fail("Finding second value threw " + t);
1320: }
1321:
1322: try {
1323: value = PropertyUtils.getMappedProperty(bean,
1324: "mappedProperty(Third Key)");
1325: assertNull("Can not find third value", value);
1326: } catch (Throwable t) {
1327: fail("Finding third value threw " + t);
1328: }
1329:
1330: // Use key expression with dotted syntax
1331:
1332: try {
1333: value = PropertyUtils.getNestedProperty(bean,
1334: "mapProperty.First Key");
1335: assertEquals("Can find first value", "First Value", value);
1336: } catch (Throwable t) {
1337: fail("Finding first value threw " + t);
1338: }
1339:
1340: try {
1341: value = PropertyUtils.getNestedProperty(bean,
1342: "mapProperty.Second Key");
1343: assertEquals("Can find second value", "Second Value", value);
1344: } catch (Throwable t) {
1345: fail("Finding second value threw " + t);
1346: }
1347:
1348: try {
1349: value = PropertyUtils.getNestedProperty(bean,
1350: "mapProperty.Third Key");
1351: assertNull("Can not find third value", value);
1352: } catch (Throwable t) {
1353: fail("Finding third value threw " + t);
1354: }
1355:
1356: }
1357:
1358: /**
1359: * Corner cases on getNestedProperty invalid arguments.
1360: */
1361: public void testGetNestedArguments() {
1362:
1363: try {
1364: PropertyUtils.getNestedProperty(null, "stringProperty");
1365: fail("Should throw IllegalArgumentException 1");
1366: } catch (IllegalArgumentException e) {
1367: // Expected response
1368: } catch (Throwable t) {
1369: fail("Threw " + t
1370: + " instead of IllegalArgumentException 1");
1371: }
1372:
1373: try {
1374: PropertyUtils.getNestedProperty(bean, null);
1375: fail("Should throw IllegalArgumentException 2");
1376: } catch (IllegalArgumentException e) {
1377: // Expected response
1378: } catch (Throwable t) {
1379: fail("Threw " + t
1380: + " instead of IllegalArgumentException 2");
1381: }
1382:
1383: }
1384:
1385: /**
1386: * Test getNestedProperty on a boolean property.
1387: */
1388: public void testGetNestedBoolean() {
1389:
1390: try {
1391: Object value = PropertyUtils.getNestedProperty(bean,
1392: "nested.booleanProperty");
1393: assertNotNull("Got a value", value);
1394: assertTrue("Got correct type", (value instanceof Boolean));
1395: assertTrue("Got correct value", ((Boolean) value)
1396: .booleanValue() == bean.getNested()
1397: .getBooleanProperty());
1398: } catch (IllegalAccessException e) {
1399: fail("IllegalAccessException");
1400: } catch (IllegalArgumentException e) {
1401: fail("IllegalArgumentException");
1402: } catch (InvocationTargetException e) {
1403: fail("InvocationTargetException");
1404: } catch (NoSuchMethodException e) {
1405: fail("NoSuchMethodException");
1406: }
1407:
1408: }
1409:
1410: /**
1411: * Test getNestedProperty on a double property.
1412: */
1413: public void testGetNestedDouble() {
1414:
1415: try {
1416: Object value = PropertyUtils.getNestedProperty(bean,
1417: "nested.doubleProperty");
1418: assertNotNull("Got a value", value);
1419: assertTrue("Got correct type", (value instanceof Double));
1420: assertEquals("Got correct value", ((Double) value)
1421: .doubleValue(), bean.getNested()
1422: .getDoubleProperty(), 0.005);
1423: } catch (IllegalAccessException e) {
1424: fail("IllegalAccessException");
1425: } catch (IllegalArgumentException e) {
1426: fail("IllegalArgumentException");
1427: } catch (InvocationTargetException e) {
1428: fail("InvocationTargetException");
1429: } catch (NoSuchMethodException e) {
1430: fail("NoSuchMethodException");
1431: }
1432:
1433: }
1434:
1435: /**
1436: * Test getNestedProperty on a float property.
1437: */
1438: public void testGetNestedFloat() {
1439:
1440: try {
1441: Object value = PropertyUtils.getNestedProperty(bean,
1442: "nested.floatProperty");
1443: assertNotNull("Got a value", value);
1444: assertTrue("Got correct type", (value instanceof Float));
1445: assertEquals("Got correct value", ((Float) value)
1446: .floatValue(), bean.getNested().getFloatProperty(),
1447: (float) 0.005);
1448: } catch (IllegalAccessException e) {
1449: fail("IllegalAccessException");
1450: } catch (IllegalArgumentException e) {
1451: fail("IllegalArgumentException");
1452: } catch (InvocationTargetException e) {
1453: fail("InvocationTargetException");
1454: } catch (NoSuchMethodException e) {
1455: fail("NoSuchMethodException");
1456: }
1457:
1458: }
1459:
1460: /**
1461: * Test getNestedProperty on an int property.
1462: */
1463: public void testGetNestedInt() {
1464:
1465: try {
1466: Object value = PropertyUtils.getNestedProperty(bean,
1467: "nested.intProperty");
1468: assertNotNull("Got a value", value);
1469: assertTrue("Got correct type", (value instanceof Integer));
1470: assertEquals("Got correct value", ((Integer) value)
1471: .intValue(), bean.getNested().getIntProperty());
1472: } catch (IllegalAccessException e) {
1473: fail("IllegalAccessException");
1474: } catch (IllegalArgumentException e) {
1475: fail("IllegalArgumentException");
1476: } catch (InvocationTargetException e) {
1477: fail("InvocationTargetException");
1478: } catch (NoSuchMethodException e) {
1479: fail("NoSuchMethodException");
1480: }
1481:
1482: }
1483:
1484: /**
1485: * Test getNestedProperty on a long property.
1486: */
1487: public void testGetNestedLong() {
1488:
1489: try {
1490: Object value = PropertyUtils.getNestedProperty(bean,
1491: "nested.longProperty");
1492: assertNotNull("Got a value", value);
1493: assertTrue("Got correct type", (value instanceof Long));
1494: assertEquals("Got correct value", ((Long) value)
1495: .longValue(), bean.getNested().getLongProperty());
1496: } catch (IllegalAccessException e) {
1497: fail("IllegalAccessException");
1498: } catch (IllegalArgumentException e) {
1499: fail("IllegalArgumentException");
1500: } catch (InvocationTargetException e) {
1501: fail("InvocationTargetException");
1502: } catch (NoSuchMethodException e) {
1503: fail("NoSuchMethodException");
1504: }
1505:
1506: }
1507:
1508: /**
1509: * Test getNestedProperty on a read-only String property.
1510: */
1511: public void testGetNestedReadOnly() {
1512:
1513: try {
1514: Object value = PropertyUtils.getNestedProperty(bean,
1515: "nested.readOnlyProperty");
1516: assertNotNull("Got a value", value);
1517: assertTrue("Got correct type", (value instanceof String));
1518: assertEquals("Got correct value", (String) value, bean
1519: .getReadOnlyProperty());
1520: } catch (IllegalAccessException e) {
1521: fail("IllegalAccessException");
1522: } catch (IllegalArgumentException e) {
1523: fail("IllegalArgumentException");
1524: } catch (InvocationTargetException e) {
1525: fail("InvocationTargetException");
1526: } catch (NoSuchMethodException e) {
1527: fail("NoSuchMethodException");
1528: }
1529:
1530: }
1531:
1532: /**
1533: * Test getNestedProperty on a short property.
1534: */
1535: public void testGetNestedShort() {
1536:
1537: try {
1538: Object value = PropertyUtils.getNestedProperty(bean,
1539: "nested.shortProperty");
1540: assertNotNull("Got a value", value);
1541: assertTrue("Got correct type", (value instanceof Short));
1542: assertEquals("Got correct value", ((Short) value)
1543: .shortValue(), bean.getNested().getShortProperty());
1544: } catch (IllegalAccessException e) {
1545: fail("IllegalAccessException");
1546: } catch (IllegalArgumentException e) {
1547: fail("IllegalArgumentException");
1548: } catch (InvocationTargetException e) {
1549: fail("InvocationTargetException");
1550: } catch (NoSuchMethodException e) {
1551: fail("NoSuchMethodException");
1552: }
1553:
1554: }
1555:
1556: /**
1557: * Test getNestedProperty on a String property.
1558: */
1559: public void testGetNestedString() {
1560:
1561: try {
1562: Object value = PropertyUtils.getNestedProperty(bean,
1563: "nested.stringProperty");
1564: assertNotNull("Got a value", value);
1565: assertTrue("Got correct type", (value instanceof String));
1566: assertEquals("Got correct value", ((String) value), bean
1567: .getNested().getStringProperty());
1568: } catch (IllegalAccessException e) {
1569: fail("IllegalAccessException");
1570: } catch (IllegalArgumentException e) {
1571: fail("IllegalArgumentException");
1572: } catch (InvocationTargetException e) {
1573: fail("InvocationTargetException");
1574: } catch (NoSuchMethodException e) {
1575: fail("NoSuchMethodException");
1576: }
1577:
1578: }
1579:
1580: /**
1581: * Negative test getNestedProperty on an unknown property.
1582: */
1583: public void testGetNestedUnknown() {
1584:
1585: try {
1586: PropertyUtils.getNestedProperty(bean, "nested.unknown");
1587: fail("Should have thrown NoSuchMethodException");
1588: } catch (IllegalAccessException e) {
1589: fail("IllegalAccessException");
1590: } catch (IllegalArgumentException e) {
1591: fail("IllegalArgumentException");
1592: } catch (InvocationTargetException e) {
1593: fail("InvocationTargetException");
1594: } catch (NoSuchMethodException e) {
1595: // Correct result for this test
1596: }
1597:
1598: }
1599:
1600: /**
1601: * When a bean has a null property which is reference by the standard access language,
1602: * this should throw a NestedNullException.
1603: */
1604: public void testThrowNestedNull() throws Exception {
1605: NestedTestBean nestedBean = new NestedTestBean("base");
1606: // don't init!
1607:
1608: try {
1609: NestedTestBean value = (NestedTestBean) PropertyUtils
1610: .getProperty(nestedBean,
1611: "simpleBeanProperty.indexedProperty[0]");
1612: fail("NestedNullException not thrown");
1613: } catch (NestedNullException e) {
1614: // that's what we wanted!
1615: }
1616: }
1617:
1618: /**
1619: * Test getNestedProperty on a write-only String property.
1620: */
1621: public void testGetNestedWriteOnly() {
1622:
1623: try {
1624: PropertyUtils.getNestedProperty(bean, "writeOnlyProperty");
1625: fail("Should have thrown NoSuchMethodException");
1626: } catch (IllegalAccessException e) {
1627: fail("IllegalAccessException");
1628: } catch (IllegalArgumentException e) {
1629: fail("IllegalArgumentException");
1630: } catch (InvocationTargetException e) {
1631: fail("InvocationTargetException");
1632: } catch (NoSuchMethodException e) {
1633: // Correct result for this test
1634: }
1635:
1636: }
1637:
1638: /**
1639: * Test getPropertyType() on all kinds of properties.
1640: */
1641: public void testGetPropertyType() {
1642:
1643: Class clazz = null;
1644: int intArray[] = new int[0];
1645: String stringArray[] = new String[0];
1646:
1647: try {
1648:
1649: // Scalar and Indexed Properties
1650: clazz = PropertyUtils.getPropertyType(bean,
1651: "booleanProperty");
1652: assertEquals("booleanProperty type", Boolean.TYPE, clazz);
1653: clazz = PropertyUtils
1654: .getPropertyType(bean, "booleanSecond");
1655: assertEquals("booleanSecond type", Boolean.TYPE, clazz);
1656: clazz = PropertyUtils.getPropertyType(bean,
1657: "doubleProperty");
1658: assertEquals("doubleProperty type", Double.TYPE, clazz);
1659: clazz = PropertyUtils.getPropertyType(bean, "dupProperty");
1660: assertEquals("dupProperty type", String.class, clazz);
1661: clazz = PropertyUtils
1662: .getPropertyType(bean, "floatProperty");
1663: assertEquals("floatProperty type", Float.TYPE, clazz);
1664: clazz = PropertyUtils.getPropertyType(bean, "intArray");
1665: assertEquals("intArray type", intArray.getClass(), clazz);
1666: clazz = PropertyUtils.getPropertyType(bean, "intIndexed");
1667: assertEquals("intIndexed type", Integer.TYPE, clazz);
1668: clazz = PropertyUtils.getPropertyType(bean, "intProperty");
1669: assertEquals("intProperty type", Integer.TYPE, clazz);
1670: clazz = PropertyUtils.getPropertyType(bean, "listIndexed");
1671: assertEquals("listIndexed type", List.class, clazz);
1672: clazz = PropertyUtils.getPropertyType(bean, "longProperty");
1673: assertEquals("longProperty type", Long.TYPE, clazz);
1674: clazz = PropertyUtils.getPropertyType(bean,
1675: "mappedProperty");
1676: assertEquals("mappedProperty type", String.class, clazz);
1677: clazz = PropertyUtils.getPropertyType(bean,
1678: "mappedIntProperty");
1679: assertEquals("mappedIntProperty type", Integer.TYPE, clazz);
1680: clazz = PropertyUtils.getPropertyType(bean,
1681: "readOnlyProperty");
1682: assertEquals("readOnlyProperty type", String.class, clazz);
1683: clazz = PropertyUtils
1684: .getPropertyType(bean, "shortProperty");
1685: assertEquals("shortProperty type", Short.TYPE, clazz);
1686: clazz = PropertyUtils.getPropertyType(bean, "stringArray");
1687: assertEquals("stringArray type", stringArray.getClass(),
1688: clazz);
1689: clazz = PropertyUtils
1690: .getPropertyType(bean, "stringIndexed");
1691: assertEquals("stringIndexed type", String.class, clazz);
1692: clazz = PropertyUtils.getPropertyType(bean,
1693: "stringProperty");
1694: assertEquals("stringProperty type", String.class, clazz);
1695: clazz = PropertyUtils.getPropertyType(bean,
1696: "writeOnlyProperty");
1697: assertEquals("writeOnlyProperty type", String.class, clazz);
1698:
1699: // Nested Properties
1700: clazz = PropertyUtils.getPropertyType(bean,
1701: "nested.booleanProperty");
1702: assertEquals("booleanProperty type", Boolean.TYPE, clazz);
1703: clazz = PropertyUtils.getPropertyType(bean,
1704: "nested.booleanSecond");
1705: assertEquals("booleanSecond type", Boolean.TYPE, clazz);
1706: clazz = PropertyUtils.getPropertyType(bean,
1707: "nested.doubleProperty");
1708: assertEquals("doubleProperty type", Double.TYPE, clazz);
1709: clazz = PropertyUtils.getPropertyType(bean,
1710: "nested.dupProperty");
1711: assertEquals("dupProperty type", String.class, clazz);
1712: clazz = PropertyUtils.getPropertyType(bean,
1713: "nested.floatProperty");
1714: assertEquals("floatProperty type", Float.TYPE, clazz);
1715: clazz = PropertyUtils.getPropertyType(bean,
1716: "nested.intArray");
1717: assertEquals("intArray type", intArray.getClass(), clazz);
1718: clazz = PropertyUtils.getPropertyType(bean,
1719: "nested.intIndexed");
1720: assertEquals("intIndexed type", Integer.TYPE, clazz);
1721: clazz = PropertyUtils.getPropertyType(bean,
1722: "nested.intProperty");
1723: assertEquals("intProperty type", Integer.TYPE, clazz);
1724: clazz = PropertyUtils.getPropertyType(bean,
1725: "nested.listIndexed");
1726: assertEquals("listIndexed type", List.class, clazz);
1727: clazz = PropertyUtils.getPropertyType(bean,
1728: "nested.longProperty");
1729: assertEquals("longProperty type", Long.TYPE, clazz);
1730: clazz = PropertyUtils.getPropertyType(bean,
1731: "nested.mappedProperty");
1732: assertEquals("mappedProperty type", String.class, clazz);
1733: clazz = PropertyUtils.getPropertyType(bean,
1734: "nested.mappedIntProperty");
1735: assertEquals("mappedIntProperty type", Integer.TYPE, clazz);
1736: clazz = PropertyUtils.getPropertyType(bean,
1737: "nested.readOnlyProperty");
1738: assertEquals("readOnlyProperty type", String.class, clazz);
1739: clazz = PropertyUtils.getPropertyType(bean,
1740: "nested.shortProperty");
1741: assertEquals("shortProperty type", Short.TYPE, clazz);
1742: clazz = PropertyUtils.getPropertyType(bean,
1743: "nested.stringArray");
1744: assertEquals("stringArray type", stringArray.getClass(),
1745: clazz);
1746: clazz = PropertyUtils.getPropertyType(bean,
1747: "nested.stringIndexed");
1748: assertEquals("stringIndexed type", String.class, clazz);
1749: clazz = PropertyUtils.getPropertyType(bean,
1750: "nested.stringProperty");
1751: assertEquals("stringProperty type", String.class, clazz);
1752: clazz = PropertyUtils.getPropertyType(bean,
1753: "nested.writeOnlyProperty");
1754: assertEquals("writeOnlyProperty type", String.class, clazz);
1755:
1756: } catch (Exception e) {
1757: fail("Exception: " + e.getMessage());
1758: }
1759:
1760: }
1761:
1762: /**
1763: * Test getting accessible property reader methods for a specified
1764: * list of properties of our standard test bean.
1765: */
1766: public void testGetReadMethodBasic() {
1767:
1768: testGetReadMethod(bean, properties, TEST_BEAN_CLASS);
1769:
1770: }
1771:
1772: /**
1773: * Test getting accessible property reader methods for a specified
1774: * list of properties of a package private subclass of our standard
1775: * test bean.
1776: */
1777: public void testGetReadMethodPackageSubclass() {
1778:
1779: testGetReadMethod(beanPackageSubclass, properties,
1780: TEST_BEAN_CLASS);
1781:
1782: }
1783:
1784: /**
1785: * Test getting accessible property reader methods for a specified
1786: * list of properties that are declared either directly or via
1787: * implemented interfaces.
1788: */
1789: public void testGetReadMethodPublicInterface() {
1790:
1791: // Properties "bar" and "baz" are visible via implemented interfaces
1792: // (one direct and one indirect)
1793: testGetReadMethod(beanPrivate, new String[] { "bar" },
1794: PRIVATE_DIRECT_CLASS);
1795: testGetReadMethod(beanPrivate, new String[] { "baz" },
1796: PRIVATE_INDIRECT_CLASS);
1797:
1798: // Properties "bar" and "baz" are visible via implemented interfaces
1799: // (one direct and one indirect). The interface is implemented in
1800: // a superclass
1801: testGetReadMethod(beanPrivateSubclass, new String[] { "bar" },
1802: PRIVATE_DIRECT_CLASS);
1803: testGetReadMethod(beanPrivateSubclass, new String[] { "baz" },
1804: PRIVATE_INDIRECT_CLASS);
1805:
1806: // Property "foo" is not accessible because the underlying
1807: // class has package scope
1808: PropertyDescriptor pd[] = PropertyUtils
1809: .getPropertyDescriptors(beanPrivate);
1810: int n = -1;
1811: for (int i = 0; i < pd.length; i++) {
1812: if ("foo".equals(pd[i].getName())) {
1813: n = i;
1814: break;
1815: }
1816: }
1817: assertTrue("Found foo descriptor", n >= 0);
1818: Method reader = pd[n].getReadMethod();
1819: assertNotNull("Found foo read method", reader);
1820: Object value = null;
1821: try {
1822: value = reader.invoke(beanPrivate, new Class[0]);
1823: fail("Foo reader did throw IllegalAccessException");
1824: } catch (IllegalAccessException e) {
1825: // Expected result for this test
1826: } catch (Throwable t) {
1827: fail("Invoke foo reader: " + t);
1828: }
1829:
1830: }
1831:
1832: /**
1833: * Test getting accessible property reader methods for a specified
1834: * list of properties of a public subclass of our standard test bean.
1835: */
1836: public void testGetReadMethodPublicSubclass() {
1837:
1838: testGetReadMethod(beanPublicSubclass, properties,
1839: TEST_BEAN_CLASS);
1840:
1841: }
1842:
1843: /**
1844: * Corner cases on getSimpleProperty invalid arguments.
1845: */
1846: public void testGetSimpleArguments() {
1847:
1848: try {
1849: PropertyUtils.getSimpleProperty(null, "stringProperty");
1850: fail("Should throw IllegalArgumentException 1");
1851: } catch (IllegalArgumentException e) {
1852: // Expected response
1853: } catch (Throwable t) {
1854: fail("Threw " + t
1855: + " instead of IllegalArgumentException 1");
1856: }
1857:
1858: try {
1859: PropertyUtils.getSimpleProperty(bean, null);
1860: fail("Should throw IllegalArgumentException 2");
1861: } catch (IllegalArgumentException e) {
1862: // Expected response
1863: } catch (Throwable t) {
1864: fail("Threw " + t
1865: + " instead of IllegalArgumentException 2");
1866: }
1867:
1868: }
1869:
1870: /**
1871: * Test getSimpleProperty on a boolean property.
1872: */
1873: public void testGetSimpleBoolean() {
1874:
1875: try {
1876: Object value = PropertyUtils.getSimpleProperty(bean,
1877: "booleanProperty");
1878: assertNotNull("Got a value", value);
1879: assertTrue("Got correct type", (value instanceof Boolean));
1880: assertTrue("Got correct value", ((Boolean) value)
1881: .booleanValue() == bean.getBooleanProperty());
1882: } catch (IllegalAccessException e) {
1883: fail("IllegalAccessException");
1884: } catch (IllegalArgumentException e) {
1885: fail("IllegalArgumentException");
1886: } catch (InvocationTargetException e) {
1887: fail("InvocationTargetException");
1888: } catch (NoSuchMethodException e) {
1889: fail("NoSuchMethodException");
1890: }
1891:
1892: }
1893:
1894: /**
1895: * Test getSimpleProperty on a double property.
1896: */
1897: public void testGetSimpleDouble() {
1898:
1899: try {
1900: Object value = PropertyUtils.getSimpleProperty(bean,
1901: "doubleProperty");
1902: assertNotNull("Got a value", value);
1903: assertTrue("Got correct type", (value instanceof Double));
1904: assertEquals("Got correct value", ((Double) value)
1905: .doubleValue(), bean.getDoubleProperty(), 0.005);
1906: } catch (IllegalAccessException e) {
1907: fail("IllegalAccessException");
1908: } catch (IllegalArgumentException e) {
1909: fail("IllegalArgumentException");
1910: } catch (InvocationTargetException e) {
1911: fail("InvocationTargetException");
1912: } catch (NoSuchMethodException e) {
1913: fail("NoSuchMethodException");
1914: }
1915:
1916: }
1917:
1918: /**
1919: * Test getSimpleProperty on a float property.
1920: */
1921: public void testGetSimpleFloat() {
1922:
1923: try {
1924: Object value = PropertyUtils.getSimpleProperty(bean,
1925: "floatProperty");
1926: assertNotNull("Got a value", value);
1927: assertTrue("Got correct type", (value instanceof Float));
1928: assertEquals("Got correct value", ((Float) value)
1929: .floatValue(), bean.getFloatProperty(),
1930: (float) 0.005);
1931: } catch (IllegalAccessException e) {
1932: fail("IllegalAccessException");
1933: } catch (IllegalArgumentException e) {
1934: fail("IllegalArgumentException");
1935: } catch (InvocationTargetException e) {
1936: fail("InvocationTargetException");
1937: } catch (NoSuchMethodException e) {
1938: fail("NoSuchMethodException");
1939: }
1940:
1941: }
1942:
1943: /**
1944: * Negative test getSimpleProperty on an indexed property.
1945: */
1946: public void testGetSimpleIndexed() {
1947:
1948: Object value = null;
1949: try {
1950: value = PropertyUtils.getSimpleProperty(bean,
1951: "intIndexed[0]");
1952: fail("Should have thrown IllegalArgumentException");
1953: } catch (IllegalAccessException e) {
1954: fail("IllegalAccessException");
1955: } catch (IllegalArgumentException e) {
1956: // Correct result for this test
1957: } catch (InvocationTargetException e) {
1958: fail("InvocationTargetException");
1959: } catch (NoSuchMethodException e) {
1960: fail("NoSuchMethodException");
1961: }
1962:
1963: }
1964:
1965: /**
1966: * Test getSimpleProperty on an int property.
1967: */
1968: public void testGetSimpleInt() {
1969:
1970: try {
1971: Object value = PropertyUtils.getSimpleProperty(bean,
1972: "intProperty");
1973: assertNotNull("Got a value", value);
1974: assertTrue("Got correct type", (value instanceof Integer));
1975: assertEquals("Got correct value", ((Integer) value)
1976: .intValue(), bean.getIntProperty());
1977: } catch (IllegalAccessException e) {
1978: fail("IllegalAccessException");
1979: } catch (IllegalArgumentException e) {
1980: fail("IllegalArgumentException");
1981: } catch (InvocationTargetException e) {
1982: fail("InvocationTargetException");
1983: } catch (NoSuchMethodException e) {
1984: fail("NoSuchMethodException");
1985: }
1986:
1987: }
1988:
1989: /**
1990: * Test getSimpleProperty on a long property.
1991: */
1992: public void testGetSimpleLong() {
1993:
1994: try {
1995: Object value = PropertyUtils.getSimpleProperty(bean,
1996: "longProperty");
1997: assertNotNull("Got a value", value);
1998: assertTrue("Got correct type", (value instanceof Long));
1999: assertEquals("Got correct value", ((Long) value)
2000: .longValue(), bean.getLongProperty());
2001: } catch (IllegalAccessException e) {
2002: fail("IllegalAccessException");
2003: } catch (IllegalArgumentException e) {
2004: fail("IllegalArgumentException");
2005: } catch (InvocationTargetException e) {
2006: fail("InvocationTargetException");
2007: } catch (NoSuchMethodException e) {
2008: fail("NoSuchMethodException");
2009: }
2010:
2011: }
2012:
2013: /**
2014: * Negative test getSimpleProperty on a nested property.
2015: */
2016: public void testGetSimpleNested() {
2017:
2018: Object value = null;
2019: try {
2020: value = PropertyUtils.getSimpleProperty(bean,
2021: "nested.stringProperty");
2022: fail("Should have thrown IllegaArgumentException");
2023: } catch (IllegalAccessException e) {
2024: fail("IllegalAccessException");
2025: } catch (IllegalArgumentException e) {
2026: // Correct result for this test
2027: } catch (InvocationTargetException e) {
2028: fail("InvocationTargetException");
2029: } catch (NoSuchMethodException e) {
2030: fail("NoSuchMethodException");
2031: }
2032:
2033: }
2034:
2035: /**
2036: * Test getSimpleProperty on a read-only String property.
2037: */
2038: public void testGetSimpleReadOnly() {
2039:
2040: try {
2041: Object value = PropertyUtils.getSimpleProperty(bean,
2042: "readOnlyProperty");
2043: assertNotNull("Got a value", value);
2044: assertTrue("Got correct type", (value instanceof String));
2045: assertEquals("Got correct value", (String) value, bean
2046: .getReadOnlyProperty());
2047: } catch (IllegalAccessException e) {
2048: fail("IllegalAccessException");
2049: } catch (IllegalArgumentException e) {
2050: fail("IllegalArgumentException");
2051: } catch (InvocationTargetException e) {
2052: fail("InvocationTargetException");
2053: } catch (NoSuchMethodException e) {
2054: fail("NoSuchMethodException");
2055: }
2056:
2057: }
2058:
2059: /**
2060: * Test getSimpleProperty on a short property.
2061: */
2062: public void testGetSimpleShort() {
2063:
2064: try {
2065: Object value = PropertyUtils.getSimpleProperty(bean,
2066: "shortProperty");
2067: assertNotNull("Got a value", value);
2068: assertTrue("Got correct type", (value instanceof Short));
2069: assertEquals("Got correct value", ((Short) value)
2070: .shortValue(), bean.getShortProperty());
2071: } catch (IllegalAccessException e) {
2072: fail("IllegalAccessException");
2073: } catch (IllegalArgumentException e) {
2074: fail("IllegalArgumentException");
2075: } catch (InvocationTargetException e) {
2076: fail("InvocationTargetException");
2077: } catch (NoSuchMethodException e) {
2078: fail("NoSuchMethodException");
2079: }
2080:
2081: }
2082:
2083: /**
2084: * Test getSimpleProperty on a String property.
2085: */
2086: public void testGetSimpleString() {
2087:
2088: try {
2089: Object value = PropertyUtils.getSimpleProperty(bean,
2090: "stringProperty");
2091: assertNotNull("Got a value", value);
2092: assertTrue("Got correct type", (value instanceof String));
2093: assertEquals("Got correct value", (String) value, bean
2094: .getStringProperty());
2095: } catch (IllegalAccessException e) {
2096: fail("IllegalAccessException");
2097: } catch (IllegalArgumentException e) {
2098: fail("IllegalArgumentException");
2099: } catch (InvocationTargetException e) {
2100: fail("InvocationTargetException");
2101: } catch (NoSuchMethodException e) {
2102: fail("NoSuchMethodException");
2103: }
2104:
2105: }
2106:
2107: /**
2108: * Negative test getSimpleProperty on an unknown property.
2109: */
2110: public void testGetSimpleUnknown() {
2111:
2112: try {
2113: PropertyUtils.getSimpleProperty(bean, "unknown");
2114: fail("Should have thrown NoSuchMethodException");
2115: } catch (IllegalAccessException e) {
2116: fail("IllegalAccessException");
2117: } catch (IllegalArgumentException e) {
2118: fail("IllegalArgumentException");
2119: } catch (InvocationTargetException e) {
2120: fail("InvocationTargetException");
2121: } catch (NoSuchMethodException e) {
2122: // Correct result for this test
2123: assertEquals("Unknown property 'unknown' on class '"
2124: + bean.getClass() + "'", e.getMessage());
2125: }
2126:
2127: }
2128:
2129: /**
2130: * Test getSimpleProperty on a write-only String property.
2131: */
2132: public void testGetSimpleWriteOnly() {
2133:
2134: try {
2135: PropertyUtils.getSimpleProperty(bean, "writeOnlyProperty");
2136: fail("Should have thrown NoSuchMethodException");
2137: } catch (IllegalAccessException e) {
2138: fail("IllegalAccessException");
2139: } catch (IllegalArgumentException e) {
2140: fail("IllegalArgumentException");
2141: } catch (InvocationTargetException e) {
2142: fail("InvocationTargetException");
2143: } catch (NoSuchMethodException e) {
2144: // Correct result for this test
2145: assertEquals(
2146: "Property 'writeOnlyProperty' has no getter method in class '"
2147: + bean.getClass() + "'", e.getMessage());
2148: }
2149:
2150: }
2151:
2152: /**
2153: * Test getting accessible property writer methods for a specified
2154: * list of properties of our standard test bean.
2155: */
2156: public void testGetWriteMethodBasic() {
2157:
2158: testGetWriteMethod(bean, properties, TEST_BEAN_CLASS);
2159:
2160: }
2161:
2162: /**
2163: * Test getting accessible property writer methods for a specified
2164: * list of properties of a package private subclass of our standard
2165: * test bean.
2166: */
2167: public void testGetWriteMethodPackageSubclass() {
2168:
2169: testGetWriteMethod(beanPackageSubclass, properties,
2170: TEST_BEAN_CLASS);
2171:
2172: }
2173:
2174: /**
2175: * Test getting accessible property writer methods for a specified
2176: * list of properties of a public subclass of our standard test bean.
2177: */
2178: public void testGetWriteMethodPublicSubclass() {
2179:
2180: testGetWriteMethod(beanPublicSubclass, properties,
2181: TEST_BEAN_CLASS);
2182:
2183: }
2184:
2185: /**
2186: * Test isReadable() method.
2187: */
2188: public void testIsReadable() {
2189: TestBean bean = new TestBean();
2190: String property = null;
2191: try {
2192: property = "stringProperty";
2193: assertTrue("Property " + property
2194: + " isReadable expeced TRUE", PropertyUtils
2195: .isReadable(bean, property));
2196: } catch (Throwable t) {
2197: fail("Property " + property
2198: + " isReadable Threw exception: " + t);
2199: }
2200: try {
2201: property = "stringIndexed";
2202: assertTrue("Property " + property
2203: + " isReadable expeced TRUE", PropertyUtils
2204: .isReadable(bean, property));
2205: } catch (Throwable t) {
2206: fail("Property " + property
2207: + " isReadable Threw exception: " + t);
2208: }
2209: try {
2210: property = "mappedProperty";
2211: assertTrue("Property " + property
2212: + " isReadable expeced TRUE", PropertyUtils
2213: .isReadable(bean, property));
2214: } catch (Throwable t) {
2215: fail("Property " + property
2216: + " isReadable Threw exception: " + t);
2217: }
2218:
2219: }
2220:
2221: /**
2222: * Test isWriteable() method.
2223: */
2224: public void testIsWriteable() {
2225: TestBean bean = new TestBean();
2226: String property = null;
2227: try {
2228: property = "stringProperty";
2229: assertTrue("Property " + property
2230: + " isWriteable expeced TRUE", PropertyUtils
2231: .isWriteable(bean, property));
2232: } catch (Throwable t) {
2233: fail("Property " + property
2234: + " isWriteable Threw exception: " + t);
2235: }
2236: try {
2237: property = "stringIndexed";
2238: assertTrue("Property " + property
2239: + " isWriteable expeced TRUE", PropertyUtils
2240: .isWriteable(bean, property));
2241: } catch (Throwable t) {
2242: fail("Property " + property
2243: + " isWriteable Threw exception: " + t);
2244: }
2245: try {
2246: property = "mappedProperty";
2247: assertTrue("Property " + property
2248: + " isWriteable expeced TRUE", PropertyUtils
2249: .isWriteable(bean, property));
2250: } catch (Throwable t) {
2251: fail("Property " + property
2252: + " isWriteable Threw exception: " + t);
2253: }
2254:
2255: }
2256:
2257: /**
2258: * Test the mappedPropertyType of MappedPropertyDescriptor.
2259: */
2260: public void testMappedPropertyType() throws Exception {
2261:
2262: MappedPropertyDescriptor desc;
2263:
2264: // Check a String property
2265: desc = (MappedPropertyDescriptor) PropertyUtils
2266: .getPropertyDescriptor(bean, "mappedProperty");
2267: assertEquals(String.class, desc.getMappedPropertyType());
2268:
2269: // Check an int property
2270: desc = (MappedPropertyDescriptor) PropertyUtils
2271: .getPropertyDescriptor(bean, "mappedIntProperty");
2272: assertEquals(Integer.TYPE, desc.getMappedPropertyType());
2273:
2274: }
2275:
2276: /**
2277: * Corner cases on setIndexedProperty invalid arguments.
2278: */
2279: public void testSetIndexedArguments() {
2280:
2281: // Use explicit index argument
2282:
2283: try {
2284: PropertyUtils.setIndexedProperty(null, "intArray", 0,
2285: new Integer(1));
2286: fail("Should throw IllegalArgumentException 1");
2287: } catch (IllegalArgumentException e) {
2288: // Expected response
2289: } catch (Throwable t) {
2290: fail("Threw " + t
2291: + " instead of IllegalArgumentException 1");
2292: }
2293:
2294: try {
2295: PropertyUtils.setIndexedProperty(bean, null, 0,
2296: new Integer(1));
2297: fail("Should throw IllegalArgumentException 2");
2298: } catch (IllegalArgumentException e) {
2299: // Expected response
2300: } catch (Throwable t) {
2301: fail("Threw " + t
2302: + " instead of IllegalArgumentException 2");
2303: }
2304:
2305: // Use index expression
2306:
2307: try {
2308: PropertyUtils.setIndexedProperty(null, "intArray[0]",
2309: new Integer(1));
2310: fail("Should throw IllegalArgumentException 3");
2311: } catch (IllegalArgumentException e) {
2312: // Expected response
2313: } catch (Throwable t) {
2314: fail("Threw " + t
2315: + " instead of IllegalArgumentException 3");
2316: }
2317:
2318: try {
2319: PropertyUtils.setIndexedProperty(bean, "[0]",
2320: new Integer(1));
2321: fail("Should throw NoSuchMethodException 4");
2322: } catch (NoSuchMethodException e) {
2323: // Expected response
2324: } catch (Throwable t) {
2325: fail("Threw " + t + " instead of NoSuchMethodException 4");
2326: }
2327:
2328: try {
2329: PropertyUtils.setIndexedProperty(bean, "intArray",
2330: new Integer(1));
2331: fail("Should throw IllegalArgumentException 5");
2332: } catch (IllegalArgumentException e) {
2333: // Expected response
2334: } catch (Throwable t) {
2335: fail("Threw " + t
2336: + " instead of IllegalArgumentException 5");
2337: }
2338:
2339: // Use explicit index argument
2340:
2341: try {
2342: PropertyUtils.setIndexedProperty(null, "intIndexed", 0,
2343: new Integer(1));
2344: fail("Should throw IllegalArgumentException 1");
2345: } catch (IllegalArgumentException e) {
2346: // Expected response
2347: } catch (Throwable t) {
2348: fail("Threw " + t
2349: + " instead of IllegalArgumentException 1");
2350: }
2351:
2352: try {
2353: PropertyUtils.setIndexedProperty(bean, null, 0,
2354: new Integer(1));
2355: fail("Should throw IllegalArgumentException 2");
2356: } catch (IllegalArgumentException e) {
2357: // Expected response
2358: } catch (Throwable t) {
2359: fail("Threw " + t
2360: + " instead of IllegalArgumentException 2");
2361: }
2362:
2363: // Use index expression
2364:
2365: try {
2366: PropertyUtils.setIndexedProperty(null, "intIndexed[0]",
2367: new Integer(1));
2368: fail("Should throw IllegalArgumentException 3");
2369: } catch (IllegalArgumentException e) {
2370: // Expected response
2371: } catch (Throwable t) {
2372: fail("Threw " + t
2373: + " instead of IllegalArgumentException 3");
2374: }
2375:
2376: try {
2377: PropertyUtils.setIndexedProperty(bean, "[0]",
2378: new Integer(1));
2379: fail("Should throw NoSuchMethodException 4");
2380: } catch (NoSuchMethodException e) {
2381: // Expected response
2382: } catch (Throwable t) {
2383: fail("Threw " + t + " instead of NoSuchMethodException 4");
2384: }
2385:
2386: try {
2387: PropertyUtils.setIndexedProperty(bean, "intIndexed",
2388: new Integer(1));
2389: fail("Should throw IllegalArgumentException 5");
2390: } catch (IllegalArgumentException e) {
2391: // Expected response
2392: } catch (Throwable t) {
2393: fail("Threw " + t
2394: + " instead of IllegalArgumentException 5");
2395: }
2396:
2397: }
2398:
2399: /**
2400: * Test setting an indexed value out of a multi-dimensional array
2401: */
2402: public void testSetIndexedArray() {
2403: String[] firstArray = new String[] { "FIRST-1", "FIRST-2",
2404: "FIRST-3" };
2405: String[] secondArray = new String[] { "SECOND-1", "SECOND-2",
2406: "SECOND-3", "SECOND-4" };
2407: String[][] mainArray = { firstArray, secondArray };
2408: TestBean bean = new TestBean(mainArray);
2409: assertEquals("BEFORE", "SECOND-3", bean.getString2dArray(1)[2]);
2410: try {
2411: PropertyUtils.setProperty(bean, "string2dArray[1][2]",
2412: "SECOND-3-UPDATED");
2413: } catch (Throwable t) {
2414: fail("Threw " + t + "");
2415: }
2416: assertEquals("AFTER", "SECOND-3-UPDATED", bean
2417: .getString2dArray(1)[2]);
2418: }
2419:
2420: /**
2421: * Test setting an indexed value out of List of Lists
2422: */
2423: public void testSetIndexedList() {
2424: String[] firstArray = new String[] { "FIRST-1", "FIRST-2",
2425: "FIRST-3" };
2426: String[] secondArray = new String[] { "SECOND-1", "SECOND-2",
2427: "SECOND-3", "SECOND-4" };
2428: List mainList = new ArrayList();
2429: mainList.add(Arrays.asList(firstArray));
2430: mainList.add(Arrays.asList(secondArray));
2431: TestBean bean = new TestBean(mainList);
2432: assertEquals("BEFORE", "SECOND-4", ((List) bean
2433: .getListIndexed().get(1)).get(3));
2434: try {
2435: PropertyUtils.setProperty(bean, "listIndexed[1][3]",
2436: "SECOND-4-UPDATED");
2437: } catch (Throwable t) {
2438: fail("Threw " + t + "");
2439: }
2440: assertEquals("AFTER", "SECOND-4-UPDATED", ((List) bean
2441: .getListIndexed().get(1)).get(3));
2442: }
2443:
2444: /**
2445: * Test setting a value out of a mapped Map
2446: */
2447: public void testSetIndexedMap() {
2448: Map firstMap = new HashMap();
2449: firstMap.put("FIRST-KEY-1", "FIRST-VALUE-1");
2450: firstMap.put("FIRST-KEY-2", "FIRST-VALUE-2");
2451: Map secondMap = new HashMap();
2452: secondMap.put("SECOND-KEY-1", "SECOND-VALUE-1");
2453: secondMap.put("SECOND-KEY-2", "SECOND-VALUE-2");
2454:
2455: List mainList = new ArrayList();
2456: mainList.add(firstMap);
2457: mainList.add(secondMap);
2458: TestBean bean = new TestBean(mainList);
2459:
2460: assertEquals("BEFORE", null, ((Map) bean.getListIndexed()
2461: .get(0)).get("FIRST-NEW-KEY"));
2462: assertEquals("BEFORE", "SECOND-VALUE-1", ((Map) bean
2463: .getListIndexed().get(1)).get("SECOND-KEY-1"));
2464: try {
2465: PropertyUtils.setProperty(bean,
2466: "listIndexed[0](FIRST-NEW-KEY)", "FIRST-NEW-VALUE");
2467: PropertyUtils.setProperty(bean,
2468: "listIndexed[1](SECOND-KEY-1)",
2469: "SECOND-VALUE-1-UPDATED");
2470: } catch (Throwable t) {
2471: fail("Threw " + t + "");
2472: }
2473: assertEquals("BEFORE", "FIRST-NEW-VALUE", ((Map) bean
2474: .getListIndexed().get(0)).get("FIRST-NEW-KEY"));
2475: assertEquals("AFTER", "SECOND-VALUE-1-UPDATED", ((Map) bean
2476: .getListIndexed().get(1)).get("SECOND-KEY-1"));
2477: }
2478:
2479: /**
2480: * Positive and negative tests on setIndexedProperty valid arguments.
2481: */
2482: public void testSetIndexedValues() {
2483:
2484: Object value = null;
2485:
2486: // Use explicit index argument
2487:
2488: try {
2489: PropertyUtils.setIndexedProperty(bean, "dupProperty", 0,
2490: "New 0");
2491: value = PropertyUtils.getIndexedProperty(bean,
2492: "dupProperty", 0);
2493: assertNotNull("Returned new value 0", value);
2494: assertTrue("Returned String new value 0",
2495: value instanceof String);
2496: assertEquals("Returned correct new value 0", "New 0",
2497: (String) value);
2498: } catch (Throwable t) {
2499: fail("Threw " + t);
2500: }
2501:
2502: try {
2503: PropertyUtils.setIndexedProperty(bean, "intArray", 0,
2504: new Integer(1));
2505: value = PropertyUtils.getIndexedProperty(bean, "intArray",
2506: 0);
2507: assertNotNull("Returned new value 0", value);
2508: assertTrue("Returned Integer new value 0",
2509: value instanceof Integer);
2510: assertEquals("Returned correct new value 0", 1,
2511: ((Integer) value).intValue());
2512: } catch (Throwable t) {
2513: fail("Threw " + t);
2514: }
2515:
2516: try {
2517: PropertyUtils.setIndexedProperty(bean, "intIndexed", 1,
2518: new Integer(11));
2519: value = PropertyUtils.getIndexedProperty(bean,
2520: "intIndexed", 1);
2521: assertNotNull("Returned new value 1", value);
2522: assertTrue("Returned Integer new value 1",
2523: value instanceof Integer);
2524: assertEquals("Returned correct new value 1", 11,
2525: ((Integer) value).intValue());
2526: } catch (Throwable t) {
2527: fail("Threw " + t);
2528: }
2529:
2530: try {
2531: PropertyUtils.setIndexedProperty(bean, "listIndexed", 2,
2532: "New Value 2");
2533: value = PropertyUtils.getIndexedProperty(bean,
2534: "listIndexed", 2);
2535: assertNotNull("Returned new value 2", value);
2536: assertTrue("Returned String new value 2",
2537: value instanceof String);
2538: assertEquals("Returned correct new value 2", "New Value 2",
2539: (String) value);
2540: } catch (Throwable t) {
2541: fail("Threw " + t);
2542: }
2543:
2544: try {
2545: PropertyUtils.setIndexedProperty(bean, "stringArray", 2,
2546: "New Value 2");
2547: value = PropertyUtils.getIndexedProperty(bean,
2548: "stringArray", 2);
2549: assertNotNull("Returned new value 2", value);
2550: assertTrue("Returned String new value 2",
2551: value instanceof String);
2552: assertEquals("Returned correct new value 2", "New Value 2",
2553: (String) value);
2554: } catch (Throwable t) {
2555: fail("Threw " + t);
2556: }
2557:
2558: try {
2559: PropertyUtils.setIndexedProperty(bean, "stringArray", 3,
2560: "New Value 3");
2561: value = PropertyUtils.getIndexedProperty(bean,
2562: "stringArray", 3);
2563: assertNotNull("Returned new value 3", value);
2564: assertTrue("Returned String new value 3",
2565: value instanceof String);
2566: assertEquals("Returned correct new value 3", "New Value 3",
2567: (String) value);
2568: } catch (Throwable t) {
2569: fail("Threw " + t);
2570: }
2571:
2572: // Use index expression
2573:
2574: try {
2575: PropertyUtils.setIndexedProperty(bean, "dupProperty[4]",
2576: "New 4");
2577: value = PropertyUtils.getIndexedProperty(bean,
2578: "dupProperty[4]");
2579: assertNotNull("Returned new value 4", value);
2580: assertTrue("Returned String new value 4",
2581: value instanceof String);
2582: assertEquals("Returned correct new value 4", "New 4",
2583: (String) value);
2584: } catch (Throwable t) {
2585: fail("Threw " + t);
2586: }
2587:
2588: try {
2589: PropertyUtils.setIndexedProperty(bean, "intArray[4]",
2590: new Integer(1));
2591: value = PropertyUtils.getIndexedProperty(bean,
2592: "intArray[4]");
2593: assertNotNull("Returned new value 4", value);
2594: assertTrue("Returned Integer new value 4",
2595: value instanceof Integer);
2596: assertEquals("Returned correct new value 4", 1,
2597: ((Integer) value).intValue());
2598: } catch (Throwable t) {
2599: fail("Threw " + t);
2600: }
2601:
2602: try {
2603: PropertyUtils.setIndexedProperty(bean, "intIndexed[3]",
2604: new Integer(11));
2605: value = PropertyUtils.getIndexedProperty(bean,
2606: "intIndexed[3]");
2607: assertNotNull("Returned new value 5", value);
2608: assertTrue("Returned Integer new value 5",
2609: value instanceof Integer);
2610: assertEquals("Returned correct new value 5", 11,
2611: ((Integer) value).intValue());
2612: } catch (Throwable t) {
2613: fail("Threw " + t);
2614: }
2615:
2616: try {
2617: PropertyUtils.setIndexedProperty(bean, "listIndexed[1]",
2618: "New Value 2");
2619: value = PropertyUtils.getIndexedProperty(bean,
2620: "listIndexed[1]");
2621: assertNotNull("Returned new value 6", value);
2622: assertTrue("Returned String new value 6",
2623: value instanceof String);
2624: assertEquals("Returned correct new value 6", "New Value 2",
2625: (String) value);
2626: } catch (Throwable t) {
2627: fail("Threw " + t);
2628: }
2629:
2630: try {
2631: PropertyUtils.setIndexedProperty(bean, "stringArray[1]",
2632: "New Value 2");
2633: value = PropertyUtils.getIndexedProperty(bean,
2634: "stringArray[2]");
2635: assertNotNull("Returned new value 6", value);
2636: assertTrue("Returned String new value 6",
2637: value instanceof String);
2638: assertEquals("Returned correct new value 6", "New Value 2",
2639: (String) value);
2640: } catch (Throwable t) {
2641: fail("Threw " + t);
2642: }
2643:
2644: try {
2645: PropertyUtils.setIndexedProperty(bean, "stringArray[0]",
2646: "New Value 3");
2647: value = PropertyUtils.getIndexedProperty(bean,
2648: "stringArray[0]");
2649: assertNotNull("Returned new value 7", value);
2650: assertTrue("Returned String new value 7",
2651: value instanceof String);
2652: assertEquals("Returned correct new value 7", "New Value 3",
2653: (String) value);
2654: } catch (Throwable t) {
2655: fail("Threw " + t);
2656: }
2657:
2658: // Index out of bounds tests
2659:
2660: try {
2661: PropertyUtils.setIndexedProperty(bean, "dupProperty", -1,
2662: "New -1");
2663: fail("Should have thrown ArrayIndexOutOfBoundsException");
2664: } catch (ArrayIndexOutOfBoundsException t) {
2665: // Expected results
2666: } catch (Throwable t) {
2667: fail("Threw " + t
2668: + " instead of ArrayIndexOutOfBoundsException");
2669: }
2670:
2671: try {
2672: PropertyUtils.setIndexedProperty(bean, "dupProperty", 5,
2673: "New 5");
2674: fail("Should have thrown ArrayIndexOutOfBoundsException");
2675: } catch (ArrayIndexOutOfBoundsException t) {
2676: // Expected results
2677: } catch (Throwable t) {
2678: fail("Threw " + t
2679: + " instead of ArrayIndexOutOfBoundsException");
2680: }
2681:
2682: try {
2683: PropertyUtils.setIndexedProperty(bean, "intArray", -1,
2684: new Integer(0));
2685: fail("Should have thrown ArrayIndexOutOfBoundsException");
2686: } catch (ArrayIndexOutOfBoundsException t) {
2687: // Expected results
2688: } catch (Throwable t) {
2689: fail("Threw " + t
2690: + " instead of ArrayIndexOutOfBoundsException");
2691: }
2692:
2693: try {
2694: PropertyUtils.setIndexedProperty(bean, "intArray", 5,
2695: new Integer(0));
2696: fail("Should have thrown ArrayIndexOutOfBoundsException");
2697: } catch (ArrayIndexOutOfBoundsException t) {
2698: // Expected results
2699: } catch (Throwable t) {
2700: fail("Threw " + t
2701: + " instead of ArrayIndexOutOfBoundsException");
2702: }
2703:
2704: try {
2705: PropertyUtils.setIndexedProperty(bean, "intIndexed", -1,
2706: new Integer(0));
2707: fail("Should have thrown ArrayIndexOutOfBoundsException");
2708: } catch (ArrayIndexOutOfBoundsException t) {
2709: // Expected results
2710: } catch (Throwable t) {
2711: fail("Threw " + t
2712: + " instead of ArrayIndexOutOfBoundsException");
2713: }
2714:
2715: try {
2716: PropertyUtils.setIndexedProperty(bean, "intIndexed", 5,
2717: new Integer(0));
2718: fail("Should have thrown ArrayIndexOutOfBoundsException");
2719: } catch (ArrayIndexOutOfBoundsException t) {
2720: // Expected results
2721: } catch (Throwable t) {
2722: fail("Threw " + t
2723: + " instead of ArrayIndexOutOfBoundsException");
2724: }
2725:
2726: try {
2727: PropertyUtils.setIndexedProperty(bean, "listIndexed", 5,
2728: "New String");
2729: fail("Should have thrown IndexOutOfBoundsException");
2730: } catch (IndexOutOfBoundsException t) {
2731: // Expected results
2732: } catch (Throwable t) {
2733: fail("Threw " + t + " instead of IndexOutOfBoundsException");
2734: }
2735:
2736: try {
2737: PropertyUtils.setIndexedProperty(bean, "listIndexed", -1,
2738: "New String");
2739: fail("Should have thrown IndexOutOfBoundsException");
2740: } catch (IndexOutOfBoundsException t) {
2741: // Expected results
2742: } catch (Throwable t) {
2743: fail("Threw " + t + " instead of IndexOutOfBoundsException");
2744: }
2745:
2746: try {
2747: PropertyUtils.setIndexedProperty(bean, "stringArray", -1,
2748: "New String");
2749: fail("Should have thrown ArrayIndexOutOfBoundsException");
2750: } catch (ArrayIndexOutOfBoundsException t) {
2751: // Expected results
2752: } catch (Throwable t) {
2753: fail("Threw " + t
2754: + " instead of ArrayIndexOutOfBoundsException");
2755: }
2756:
2757: try {
2758: PropertyUtils.setIndexedProperty(bean, "stringArray", 5,
2759: "New String");
2760: fail("Should have thrown ArrayIndexOutOfBoundsException");
2761: } catch (ArrayIndexOutOfBoundsException t) {
2762: // Expected results
2763: } catch (Throwable t) {
2764: fail("Threw " + t
2765: + " instead of ArrayIndexOutOfBoundsException");
2766: }
2767:
2768: try {
2769: PropertyUtils.setIndexedProperty(bean, "stringIndexed", -1,
2770: "New String");
2771: fail("Should have thrown ArrayIndexOutOfBoundsException");
2772: } catch (ArrayIndexOutOfBoundsException t) {
2773: // Expected results
2774: } catch (Throwable t) {
2775: fail("Threw " + t
2776: + " instead of ArrayIndexOutOfBoundsException");
2777: }
2778:
2779: try {
2780: PropertyUtils.setIndexedProperty(bean, "stringIndexed", 5,
2781: "New String");
2782: fail("Should have thrown ArrayIndexOutOfBoundsException");
2783: } catch (ArrayIndexOutOfBoundsException t) {
2784: // Expected results
2785: } catch (Throwable t) {
2786: fail("Threw " + t
2787: + " instead of ArrayIndexOutOfBoundsException");
2788: }
2789:
2790: }
2791:
2792: /**
2793: * Corner cases on getMappedProperty invalid arguments.
2794: */
2795: public void testSetMappedArguments() {
2796:
2797: // Use explicit key argument
2798:
2799: try {
2800: PropertyUtils.setMappedProperty(null, "mappedProperty",
2801: "First Key", "First Value");
2802: fail("Should throw IllegalArgumentException 1");
2803: } catch (IllegalArgumentException e) {
2804: // Expected response
2805: } catch (Throwable t) {
2806: fail("Threw " + t
2807: + " instead of IllegalArgumentException 1");
2808: }
2809:
2810: try {
2811: PropertyUtils.setMappedProperty(bean, null, "First Key",
2812: "First Value");
2813: fail("Should throw IllegalArgumentException 2");
2814: } catch (IllegalArgumentException e) {
2815: // Expected response
2816: } catch (Throwable t) {
2817: fail("Threw " + t
2818: + " instead of IllegalArgumentException 2");
2819: }
2820:
2821: try {
2822: PropertyUtils.setMappedProperty(bean, "mappedProperty",
2823: null, "First Value");
2824: fail("Should throw IllegalArgumentException 3");
2825: } catch (IllegalArgumentException e) {
2826: // Expected response
2827: } catch (Throwable t) {
2828: fail("Threw " + t
2829: + " instead of IllegalArgumentException 3");
2830: }
2831:
2832: // Use key expression
2833:
2834: try {
2835: PropertyUtils.setMappedProperty(null,
2836: "mappedProperty(First Key)", "First Value");
2837: fail("Should throw IllegalArgumentException 4");
2838: } catch (IllegalArgumentException e) {
2839: // Expected response
2840: } catch (Throwable t) {
2841: fail("Threw " + t
2842: + " instead of IllegalArgumentException 4");
2843: }
2844:
2845: try {
2846: PropertyUtils.setMappedProperty(bean, "(Second Key)",
2847: "Second Value");
2848: fail("Should throw IllegalArgumentException 5");
2849: } catch (NoSuchMethodException e) {
2850: // Expected response
2851: } catch (Throwable t) {
2852: fail("Threw " + t + " instead of NoSuchMethodException 5");
2853: }
2854:
2855: try {
2856: PropertyUtils.setMappedProperty(bean, "mappedProperty",
2857: "Third Value");
2858: fail("Should throw IllegalArgumentException 6");
2859: } catch (IllegalArgumentException e) {
2860: // Expected response
2861: } catch (Throwable t) {
2862: fail("Threw " + t
2863: + " instead of IllegalArgumentException 6");
2864: }
2865:
2866: }
2867:
2868: /**
2869: * Test setting an indexed value out of a mapped array
2870: */
2871: public void testSetMappedArray() {
2872: TestBean bean = new TestBean();
2873: String[] array = new String[] { "abc", "def", "ghi" };
2874: bean.getMapProperty().put("mappedArray", array);
2875:
2876: assertEquals("BEFORE", "def", ((String[]) bean.getMapProperty()
2877: .get("mappedArray"))[1]);
2878: try {
2879: PropertyUtils.setProperty(bean,
2880: "mapProperty(mappedArray)[1]", "DEF-UPDATED");
2881: } catch (Throwable t) {
2882: fail("Threw " + t + "");
2883: }
2884: assertEquals("AFTER", "DEF-UPDATED", ((String[]) bean
2885: .getMapProperty().get("mappedArray"))[1]);
2886: }
2887:
2888: /**
2889: * Test setting an indexed value out of a mapped List
2890: */
2891: public void testSetMappedList() {
2892: TestBean bean = new TestBean();
2893: List list = new ArrayList();
2894: list.add("klm");
2895: list.add("nop");
2896: list.add("qrs");
2897: bean.getMapProperty().put("mappedList", list);
2898:
2899: assertEquals("BEFORE", "klm", ((List) bean.getMapProperty()
2900: .get("mappedList")).get(0));
2901: try {
2902: PropertyUtils.setProperty(bean,
2903: "mapProperty(mappedList)[0]", "KLM-UPDATED");
2904: } catch (Throwable t) {
2905: fail("Threw " + t + "");
2906: }
2907: assertEquals("AFTER", "KLM-UPDATED", ((List) bean
2908: .getMapProperty().get("mappedList")).get(0));
2909: }
2910:
2911: /**
2912: * Test setting a value out of a mapped Map
2913: */
2914: public void testSetMappedMap() {
2915: TestBean bean = new TestBean();
2916: Map map = new HashMap();
2917: map.put("sub-key-1", "sub-value-1");
2918: map.put("sub-key-2", "sub-value-2");
2919: map.put("sub-key-3", "sub-value-3");
2920: bean.getMapProperty().put("mappedMap", map);
2921:
2922: assertEquals("BEFORE", "sub-value-3", ((Map) bean
2923: .getMapProperty().get("mappedMap")).get("sub-key-3"));
2924: try {
2925: PropertyUtils.setProperty(bean,
2926: "mapProperty(mappedMap)(sub-key-3)",
2927: "SUB-KEY-3-UPDATED");
2928: } catch (Throwable t) {
2929: fail("Threw " + t + "");
2930: }
2931: assertEquals("AFTER", "SUB-KEY-3-UPDATED", ((Map) bean
2932: .getMapProperty().get("mappedMap")).get("sub-key-3"));
2933: }
2934:
2935: /**
2936: * Positive and negative tests on setMappedProperty valid arguments.
2937: */
2938: public void testSetMappedValues() {
2939:
2940: Object value = null;
2941:
2942: // Use explicit key argument
2943:
2944: try {
2945: value = PropertyUtils.getMappedProperty(bean,
2946: "mappedProperty", "Fourth Key");
2947: assertNull("Can not find fourth value", value);
2948: } catch (Throwable t) {
2949: fail("Finding fourth value threw " + t);
2950: }
2951:
2952: try {
2953: PropertyUtils.setMappedProperty(bean, "mappedProperty",
2954: "Fourth Key", "Fourth Value");
2955: } catch (Throwable t) {
2956: fail("Setting fourth value threw " + t);
2957: }
2958:
2959: try {
2960: value = PropertyUtils.getMappedProperty(bean,
2961: "mappedProperty", "Fourth Key");
2962: assertEquals("Can find fourth value", "Fourth Value", value);
2963: } catch (Throwable t) {
2964: fail("Finding fourth value threw " + t);
2965: }
2966:
2967: // Use key expression with parentheses
2968:
2969: try {
2970: value = PropertyUtils.getMappedProperty(bean,
2971: "mappedProperty(Fifth Key)");
2972: assertNull("Can not find fifth value", value);
2973: } catch (Throwable t) {
2974: fail("Finding fifth value threw " + t);
2975: }
2976:
2977: try {
2978: PropertyUtils.setMappedProperty(bean,
2979: "mappedProperty(Fifth Key)", "Fifth Value");
2980: } catch (Throwable t) {
2981: fail("Setting fifth value threw " + t);
2982: }
2983:
2984: try {
2985: value = PropertyUtils.getMappedProperty(bean,
2986: "mappedProperty(Fifth Key)");
2987: assertEquals("Can find fifth value", "Fifth Value", value);
2988: } catch (Throwable t) {
2989: fail("Finding fifth value threw " + t);
2990: }
2991:
2992: // Use key expression with dotted expression
2993:
2994: try {
2995: value = PropertyUtils.getNestedProperty(bean,
2996: "mapProperty.Sixth Key");
2997: assertNull("Can not find sixth value", value);
2998: } catch (Throwable t) {
2999: fail("Finding fifth value threw " + t);
3000: }
3001:
3002: try {
3003: PropertyUtils.setNestedProperty(bean,
3004: "mapProperty.Sixth Key", "Sixth Value");
3005: } catch (Throwable t) {
3006: fail("Setting sixth value threw " + t);
3007: }
3008:
3009: try {
3010: value = PropertyUtils.getNestedProperty(bean,
3011: "mapProperty.Sixth Key");
3012: assertEquals("Can find sixth value", "Sixth Value", value);
3013: } catch (Throwable t) {
3014: fail("Finding sixth value threw " + t);
3015: }
3016:
3017: }
3018:
3019: /**
3020: * Test setting mapped values with periods in the key.
3021: */
3022: public void testSetMappedPeriods() {
3023:
3024: // -------- PropertyUtils.setMappedProperty()--------
3025: bean.setMappedProperty("key.with.a.dot", "Special Value");
3026: assertEquals("Can retrieve directly (A)", "Special Value", bean
3027: .getMappedProperty("key.with.a.dot"));
3028:
3029: try {
3030: PropertyUtils.setMappedProperty(bean, "mappedProperty",
3031: "key.with.a.dot", "Updated Special Value");
3032: assertEquals("Check set via setMappedProperty",
3033: "Updated Special Value", bean
3034: .getMappedProperty("key.with.a.dot"));
3035: } catch (Exception e) {
3036: fail("Thew exception: " + e);
3037: }
3038:
3039: // -------- PropertyUtils.setNestedProperty() --------
3040: bean.setMappedProperty("key.with.a.dot", "Special Value");
3041: assertEquals("Can retrieve directly (B)", "Special Value", bean
3042: .getMappedProperty("key.with.a.dot"));
3043: try {
3044: PropertyUtils.setNestedProperty(bean,
3045: "mappedProperty(key.with.a.dot)",
3046: "Updated Special Value");
3047: assertEquals("Check set via setNestedProperty (B)",
3048: "Updated Special Value", bean
3049: .getMappedProperty("key.with.a.dot"));
3050: } catch (Exception e) {
3051: fail("Thew exception: " + e);
3052: }
3053:
3054: // -------- PropertyUtils.setNestedProperty() --------
3055: TestBean testBean = new TestBean();
3056: bean.setMappedObjects("nested.property", testBean);
3057: assertEquals("Can retrieve directly (C)", "This is a string",
3058: testBean.getStringProperty());
3059: try {
3060: PropertyUtils.setNestedProperty(bean,
3061: "mappedObjects(nested.property).stringProperty",
3062: "Updated String Value");
3063: assertEquals("Check set via setNestedProperty (C)",
3064: "Updated String Value", testBean
3065: .getStringProperty());
3066: } catch (Exception e) {
3067: fail("Thew exception: " + e);
3068: }
3069:
3070: // -------- PropertyUtils.setNestedProperty() --------
3071: bean.getNested().setMappedProperty("Mapped Key",
3072: "Nested Mapped Value");
3073: try {
3074: assertEquals("Can retrieve via getNestedProperty (D)",
3075: "Nested Mapped Value",
3076: PropertyUtils.getNestedProperty(bean,
3077: "nested.mappedProperty(Mapped Key)"));
3078: PropertyUtils.setNestedProperty(bean,
3079: "nested.mappedProperty(Mapped Key)",
3080: "Updated Nested Mapped Value");
3081: assertEquals("Check set via setNestedProperty (D)",
3082: "Updated Nested Mapped Value",
3083: PropertyUtils.getNestedProperty(bean,
3084: "nested.mappedProperty(Mapped Key)"));
3085: } catch (Exception e) {
3086: fail("Thew exception: " + e);
3087: }
3088: }
3089:
3090: /**
3091: * Corner cases on setNestedProperty invalid arguments.
3092: */
3093: public void testSetNestedArguments() {
3094:
3095: try {
3096: PropertyUtils.setNestedProperty(null, "stringProperty", "");
3097: fail("Should throw IllegalArgumentException 1");
3098: } catch (IllegalArgumentException e) {
3099: // Expected response
3100: } catch (Throwable t) {
3101: fail("Threw " + t
3102: + " instead of IllegalArgumentException 1");
3103: }
3104:
3105: try {
3106: PropertyUtils.setNestedProperty(bean, null, "");
3107: fail("Should throw IllegalArgumentException 2");
3108: } catch (IllegalArgumentException e) {
3109: // Expected response
3110: } catch (Throwable t) {
3111: fail("Threw " + t
3112: + " instead of IllegalArgumentException 2");
3113: }
3114:
3115: }
3116:
3117: /**
3118: * Test setNextedProperty on a boolean property.
3119: */
3120: public void testSetNestedBoolean() {
3121:
3122: try {
3123: boolean oldValue = bean.getNested().getBooleanProperty();
3124: boolean newValue = !oldValue;
3125: PropertyUtils.setNestedProperty(bean,
3126: "nested.booleanProperty", new Boolean(newValue));
3127: assertTrue("Matched new value", newValue == bean
3128: .getNested().getBooleanProperty());
3129: } catch (IllegalAccessException e) {
3130: fail("IllegalAccessException");
3131: } catch (IllegalArgumentException e) {
3132: fail("IllegalArgumentException");
3133: } catch (InvocationTargetException e) {
3134: fail("InvocationTargetException");
3135: } catch (NoSuchMethodException e) {
3136: fail("NoSuchMethodException");
3137: }
3138:
3139: }
3140:
3141: /**
3142: * Test setNestedProperty on a double property.
3143: */
3144: public void testSetNestedDouble() {
3145:
3146: try {
3147: double oldValue = bean.getNested().getDoubleProperty();
3148: double newValue = oldValue + 1.0;
3149: PropertyUtils.setNestedProperty(bean,
3150: "nested.doubleProperty", new Double(newValue));
3151: assertEquals("Matched new value", newValue, bean
3152: .getNested().getDoubleProperty(), 0.005);
3153: } catch (IllegalAccessException e) {
3154: fail("IllegalAccessException");
3155: } catch (IllegalArgumentException e) {
3156: fail("IllegalArgumentException");
3157: } catch (InvocationTargetException e) {
3158: fail("InvocationTargetException");
3159: } catch (NoSuchMethodException e) {
3160: fail("NoSuchMethodException");
3161: }
3162:
3163: }
3164:
3165: /**
3166: * Test setNestedProperty on a float property.
3167: */
3168: public void testSetNestedFloat() {
3169:
3170: try {
3171: float oldValue = bean.getNested().getFloatProperty();
3172: float newValue = oldValue + (float) 1.0;
3173: PropertyUtils.setNestedProperty(bean,
3174: "nested.floatProperty", new Float(newValue));
3175: assertEquals("Matched new value", newValue, bean
3176: .getNested().getFloatProperty(), (float) 0.005);
3177: } catch (IllegalAccessException e) {
3178: fail("IllegalAccessException");
3179: } catch (IllegalArgumentException e) {
3180: fail("IllegalArgumentException");
3181: } catch (InvocationTargetException e) {
3182: fail("InvocationTargetException");
3183: } catch (NoSuchMethodException e) {
3184: fail("NoSuchMethodException");
3185: }
3186:
3187: }
3188:
3189: /**
3190: * Test setNestedProperty on a int property.
3191: */
3192: public void testSetNestedInt() {
3193:
3194: try {
3195: int oldValue = bean.getNested().getIntProperty();
3196: int newValue = oldValue + 1;
3197: PropertyUtils.setNestedProperty(bean, "nested.intProperty",
3198: new Integer(newValue));
3199: assertEquals("Matched new value", newValue, bean
3200: .getNested().getIntProperty());
3201: } catch (IllegalAccessException e) {
3202: fail("IllegalAccessException");
3203: } catch (IllegalArgumentException e) {
3204: fail("IllegalArgumentException");
3205: } catch (InvocationTargetException e) {
3206: fail("InvocationTargetException");
3207: } catch (NoSuchMethodException e) {
3208: fail("NoSuchMethodException");
3209: }
3210:
3211: }
3212:
3213: /**
3214: * Test setNestedProperty on a long property.
3215: */
3216: public void testSetNestedLong() {
3217:
3218: try {
3219: long oldValue = bean.getNested().getLongProperty();
3220: long newValue = oldValue + 1;
3221: PropertyUtils.setNestedProperty(bean,
3222: "nested.longProperty", new Long(newValue));
3223: assertEquals("Matched new value", newValue, bean
3224: .getNested().getLongProperty());
3225: } catch (IllegalAccessException e) {
3226: fail("IllegalAccessException");
3227: } catch (IllegalArgumentException e) {
3228: fail("IllegalArgumentException");
3229: } catch (InvocationTargetException e) {
3230: fail("InvocationTargetException");
3231: } catch (NoSuchMethodException e) {
3232: fail("NoSuchMethodException");
3233: }
3234:
3235: }
3236:
3237: /**
3238: * Test setNestedProperty on a read-only String property.
3239: */
3240: public void testSetNestedReadOnly() {
3241:
3242: try {
3243: String oldValue = bean.getNested()
3244: .getWriteOnlyPropertyValue();
3245: String newValue = oldValue + " Extra Value";
3246: PropertyUtils.setNestedProperty(bean,
3247: "nested.readOnlyProperty", newValue);
3248: fail("Should have thrown NoSuchMethodException");
3249: } catch (IllegalAccessException e) {
3250: fail("IllegalAccessException");
3251: } catch (IllegalArgumentException e) {
3252: fail("IllegalArgumentException");
3253: } catch (InvocationTargetException e) {
3254: fail("InvocationTargetException");
3255: } catch (NoSuchMethodException e) {
3256: // Correct result for this test
3257: }
3258:
3259: }
3260:
3261: /**
3262: * Test setNestedProperty on a short property.
3263: */
3264: public void testSetNestedShort() {
3265:
3266: try {
3267: short oldValue = bean.getNested().getShortProperty();
3268: short newValue = oldValue;
3269: newValue++;
3270: PropertyUtils.setNestedProperty(bean,
3271: "nested.shortProperty", new Short(newValue));
3272: assertEquals("Matched new value", newValue, bean
3273: .getNested().getShortProperty());
3274: } catch (IllegalAccessException e) {
3275: fail("IllegalAccessException");
3276: } catch (IllegalArgumentException e) {
3277: fail("IllegalArgumentException");
3278: } catch (InvocationTargetException e) {
3279: fail("InvocationTargetException");
3280: } catch (NoSuchMethodException e) {
3281: fail("NoSuchMethodException");
3282: }
3283:
3284: }
3285:
3286: /**
3287: * Test setNestedProperty on a String property.
3288: */
3289: public void testSetNestedString() {
3290:
3291: try {
3292: String oldValue = bean.getNested().getStringProperty();
3293: String newValue = oldValue + " Extra Value";
3294: PropertyUtils.setNestedProperty(bean,
3295: "nested.stringProperty", newValue);
3296: assertEquals("Matched new value", newValue, bean
3297: .getNested().getStringProperty());
3298: } catch (IllegalAccessException e) {
3299: fail("IllegalAccessException");
3300: } catch (IllegalArgumentException e) {
3301: fail("IllegalArgumentException");
3302: } catch (InvocationTargetException e) {
3303: fail("InvocationTargetException");
3304: } catch (NoSuchMethodException e) {
3305: fail("NoSuchMethodException");
3306: }
3307:
3308: }
3309:
3310: /**
3311: * Test setNestedProperty on an unknown property name.
3312: */
3313: public void testSetNestedUnknown() {
3314:
3315: try {
3316: String newValue = "New String Value";
3317: PropertyUtils.setNestedProperty(bean, "nested.unknown",
3318: newValue);
3319: fail("Should have thrown NoSuchMethodException");
3320: } catch (IllegalAccessException e) {
3321: fail("IllegalAccessException");
3322: } catch (IllegalArgumentException e) {
3323: fail("IllegalArgumentException");
3324: } catch (InvocationTargetException e) {
3325: fail("InvocationTargetException");
3326: } catch (NoSuchMethodException e) {
3327: // Correct result for this test
3328: }
3329:
3330: }
3331:
3332: /**
3333: * Test setNestedProperty on a write-only String property.
3334: */
3335: public void testSetNestedWriteOnly() {
3336:
3337: try {
3338: String oldValue = bean.getNested()
3339: .getWriteOnlyPropertyValue();
3340: String newValue = oldValue + " Extra Value";
3341: PropertyUtils.setNestedProperty(bean,
3342: "nested.writeOnlyProperty", newValue);
3343: assertEquals("Matched new value", newValue, bean
3344: .getNested().getWriteOnlyPropertyValue());
3345: } catch (IllegalAccessException e) {
3346: fail("IllegalAccessException");
3347: } catch (IllegalArgumentException e) {
3348: fail("IllegalArgumentException");
3349: } catch (InvocationTargetException e) {
3350: fail("InvocationTargetException");
3351: } catch (NoSuchMethodException e) {
3352: fail("NoSuchMethodException");
3353: }
3354:
3355: }
3356:
3357: /**
3358: * Corner cases on setSimpleProperty invalid arguments.
3359: */
3360: public void testSetSimpleArguments() {
3361:
3362: try {
3363: PropertyUtils.setSimpleProperty(null, "stringProperty", "");
3364: fail("Should throw IllegalArgumentException 1");
3365: } catch (IllegalArgumentException e) {
3366: // Expected response
3367: } catch (Throwable t) {
3368: fail("Threw " + t
3369: + " instead of IllegalArgumentException 1");
3370: }
3371:
3372: try {
3373: PropertyUtils.setSimpleProperty(bean, null, "");
3374: fail("Should throw IllegalArgumentException 2");
3375: } catch (IllegalArgumentException e) {
3376: // Expected response
3377: } catch (Throwable t) {
3378: fail("Threw " + t
3379: + " instead of IllegalArgumentException 2");
3380: }
3381:
3382: }
3383:
3384: /**
3385: * Test setSimpleProperty on a boolean property.
3386: */
3387: public void testSetSimpleBoolean() {
3388:
3389: try {
3390: boolean oldValue = bean.getBooleanProperty();
3391: boolean newValue = !oldValue;
3392: PropertyUtils.setSimpleProperty(bean, "booleanProperty",
3393: new Boolean(newValue));
3394: assertTrue("Matched new value", newValue == bean
3395: .getBooleanProperty());
3396: } catch (IllegalAccessException e) {
3397: fail("IllegalAccessException");
3398: } catch (IllegalArgumentException e) {
3399: fail("IllegalArgumentException");
3400: } catch (InvocationTargetException e) {
3401: fail("InvocationTargetException");
3402: } catch (NoSuchMethodException e) {
3403: fail("NoSuchMethodException");
3404: }
3405:
3406: }
3407:
3408: /**
3409: * Test setSimpleProperty on a double property.
3410: */
3411: public void testSetSimpleDouble() {
3412:
3413: try {
3414: double oldValue = bean.getDoubleProperty();
3415: double newValue = oldValue + 1.0;
3416: PropertyUtils.setSimpleProperty(bean, "doubleProperty",
3417: new Double(newValue));
3418: assertEquals("Matched new value", newValue, bean
3419: .getDoubleProperty(), 0.005);
3420: } catch (IllegalAccessException e) {
3421: fail("IllegalAccessException");
3422: } catch (IllegalArgumentException e) {
3423: fail("IllegalArgumentException");
3424: } catch (InvocationTargetException e) {
3425: fail("InvocationTargetException");
3426: } catch (NoSuchMethodException e) {
3427: fail("NoSuchMethodException");
3428: }
3429:
3430: }
3431:
3432: /**
3433: * Test setSimpleProperty on a float property.
3434: */
3435: public void testSetSimpleFloat() {
3436:
3437: try {
3438: float oldValue = bean.getFloatProperty();
3439: float newValue = oldValue + (float) 1.0;
3440: PropertyUtils.setSimpleProperty(bean, "floatProperty",
3441: new Float(newValue));
3442: assertEquals("Matched new value", newValue, bean
3443: .getFloatProperty(), (float) 0.005);
3444: } catch (IllegalAccessException e) {
3445: fail("IllegalAccessException");
3446: } catch (IllegalArgumentException e) {
3447: fail("IllegalArgumentException");
3448: } catch (InvocationTargetException e) {
3449: fail("InvocationTargetException");
3450: } catch (NoSuchMethodException e) {
3451: fail("NoSuchMethodException");
3452: }
3453:
3454: }
3455:
3456: /**
3457: * Negative test setSimpleProperty on an indexed property.
3458: */
3459: public void testSetSimpleIndexed() {
3460:
3461: try {
3462: PropertyUtils.setSimpleProperty(bean, "stringIndexed[0]",
3463: "New String Value");
3464: fail("Should have thrown IllegalArgumentException");
3465: } catch (IllegalAccessException e) {
3466: fail("IllegalAccessException");
3467: } catch (IllegalArgumentException e) {
3468: // Correct result for this test
3469: } catch (InvocationTargetException e) {
3470: fail("InvocationTargetException");
3471: } catch (NoSuchMethodException e) {
3472: fail("NoSuchMethodException");
3473: }
3474:
3475: }
3476:
3477: /**
3478: * Test setSimpleProperty on a int property.
3479: */
3480: public void testSetSimpleInt() {
3481:
3482: try {
3483: int oldValue = bean.getIntProperty();
3484: int newValue = oldValue + 1;
3485: PropertyUtils.setSimpleProperty(bean, "intProperty",
3486: new Integer(newValue));
3487: assertEquals("Matched new value", newValue, bean
3488: .getIntProperty());
3489: } catch (IllegalAccessException e) {
3490: fail("IllegalAccessException");
3491: } catch (IllegalArgumentException e) {
3492: fail("IllegalArgumentException");
3493: } catch (InvocationTargetException e) {
3494: fail("InvocationTargetException");
3495: } catch (NoSuchMethodException e) {
3496: fail("NoSuchMethodException");
3497: }
3498:
3499: }
3500:
3501: /**
3502: * Test setSimpleProperty on a long property.
3503: */
3504: public void testSetSimpleLong() {
3505:
3506: try {
3507: long oldValue = bean.getLongProperty();
3508: long newValue = oldValue + 1;
3509: PropertyUtils.setSimpleProperty(bean, "longProperty",
3510: new Long(newValue));
3511: assertEquals("Matched new value", newValue, bean
3512: .getLongProperty());
3513: } catch (IllegalAccessException e) {
3514: fail("IllegalAccessException");
3515: } catch (IllegalArgumentException e) {
3516: fail("IllegalArgumentException");
3517: } catch (InvocationTargetException e) {
3518: fail("InvocationTargetException");
3519: } catch (NoSuchMethodException e) {
3520: fail("NoSuchMethodException");
3521: }
3522:
3523: }
3524:
3525: /**
3526: * Negative test setSimpleProperty on a nested property.
3527: */
3528: public void testSetSimpleNested() {
3529:
3530: try {
3531: PropertyUtils.setSimpleProperty(bean,
3532: "nested.stringProperty", "New String Value");
3533: fail("Should have thrown IllegalArgumentException");
3534: } catch (IllegalAccessException e) {
3535: fail("IllegalAccessException");
3536: } catch (IllegalArgumentException e) {
3537: // Correct result for this test
3538: } catch (InvocationTargetException e) {
3539: fail("InvocationTargetException");
3540: } catch (NoSuchMethodException e) {
3541: fail("NoSuchMethodException");
3542: }
3543:
3544: }
3545:
3546: /**
3547: * Test setSimpleProperty on a read-only String property.
3548: */
3549: public void testSetSimpleReadOnly() {
3550:
3551: try {
3552: String oldValue = bean.getWriteOnlyPropertyValue();
3553: String newValue = oldValue + " Extra Value";
3554: PropertyUtils.setSimpleProperty(bean, "readOnlyProperty",
3555: newValue);
3556: fail("Should have thrown NoSuchMethodException");
3557: } catch (IllegalAccessException e) {
3558: fail("IllegalAccessException");
3559: } catch (IllegalArgumentException e) {
3560: fail("IllegalArgumentException");
3561: } catch (InvocationTargetException e) {
3562: fail("InvocationTargetException");
3563: } catch (NoSuchMethodException e) {
3564: // Correct result for this test
3565: assertEquals(
3566: "Property 'readOnlyProperty' has no setter method in class '"
3567: + bean.getClass() + "'", e.getMessage());
3568: }
3569:
3570: }
3571:
3572: /**
3573: * Test setSimpleProperty on a short property.
3574: */
3575: public void testSetSimpleShort() {
3576:
3577: try {
3578: short oldValue = bean.getShortProperty();
3579: short newValue = oldValue;
3580: newValue++;
3581: PropertyUtils.setSimpleProperty(bean, "shortProperty",
3582: new Short(newValue));
3583: assertEquals("Matched new value", newValue, bean
3584: .getShortProperty());
3585: } catch (IllegalAccessException e) {
3586: fail("IllegalAccessException");
3587: } catch (IllegalArgumentException e) {
3588: fail("IllegalArgumentException");
3589: } catch (InvocationTargetException e) {
3590: fail("InvocationTargetException");
3591: } catch (NoSuchMethodException e) {
3592: fail("NoSuchMethodException");
3593: }
3594:
3595: }
3596:
3597: /**
3598: * Test setSimpleProperty on a String property.
3599: */
3600: public void testSetSimpleString() {
3601:
3602: try {
3603: String oldValue = bean.getStringProperty();
3604: String newValue = oldValue + " Extra Value";
3605: PropertyUtils.setSimpleProperty(bean, "stringProperty",
3606: newValue);
3607: assertEquals("Matched new value", newValue, bean
3608: .getStringProperty());
3609: } catch (IllegalAccessException e) {
3610: fail("IllegalAccessException");
3611: } catch (IllegalArgumentException e) {
3612: fail("IllegalArgumentException");
3613: } catch (InvocationTargetException e) {
3614: fail("InvocationTargetException");
3615: } catch (NoSuchMethodException e) {
3616: fail("NoSuchMethodException");
3617: }
3618:
3619: }
3620:
3621: /**
3622: * Test setSimpleProperty on an unknown property name.
3623: */
3624: public void testSetSimpleUnknown() {
3625:
3626: try {
3627: String newValue = "New String Value";
3628: PropertyUtils.setSimpleProperty(bean, "unknown", newValue);
3629: fail("Should have thrown NoSuchMethodException");
3630: } catch (IllegalAccessException e) {
3631: fail("IllegalAccessException");
3632: } catch (IllegalArgumentException e) {
3633: fail("IllegalArgumentException");
3634: } catch (InvocationTargetException e) {
3635: fail("InvocationTargetException");
3636: } catch (NoSuchMethodException e) {
3637: // Correct result for this test
3638: assertEquals("Unknown property 'unknown' on class '"
3639: + bean.getClass() + "'", e.getMessage());
3640: }
3641:
3642: }
3643:
3644: /**
3645: * Test setSimpleProperty on a write-only String property.
3646: */
3647: public void testSetSimpleWriteOnly() {
3648:
3649: try {
3650: String oldValue = bean.getWriteOnlyPropertyValue();
3651: String newValue = oldValue + " Extra Value";
3652: PropertyUtils.setSimpleProperty(bean, "writeOnlyProperty",
3653: newValue);
3654: assertEquals("Matched new value", newValue, bean
3655: .getWriteOnlyPropertyValue());
3656: } catch (IllegalAccessException e) {
3657: fail("IllegalAccessException");
3658: } catch (IllegalArgumentException e) {
3659: fail("IllegalArgumentException");
3660: } catch (InvocationTargetException e) {
3661: fail("InvocationTargetException");
3662: } catch (NoSuchMethodException e) {
3663: fail("NoSuchMethodException");
3664: }
3665:
3666: }
3667:
3668: // ------------------------------------------------------ Protected Methods
3669:
3670: /**
3671: * Base for testGetDescriptorXxxxx() series of tests.
3672: *
3673: * @param name Name of the property to be retrieved
3674: * @param read Expected name of the read method (or null)
3675: * @param write Expected name of the write method (or null)
3676: */
3677: protected void testGetDescriptorBase(String name, String read,
3678: String write) {
3679:
3680: try {
3681: PropertyDescriptor pd = PropertyUtils
3682: .getPropertyDescriptor(bean, name);
3683: if ((read != null) || (write != null)) {
3684: assertNotNull("Got descriptor", pd);
3685: } else {
3686: assertNull("Got descriptor", pd);
3687: return;
3688: }
3689: Method rm = pd.getReadMethod();
3690: if (read != null) {
3691: assertNotNull("Got read method", rm);
3692: assertEquals("Got correct read method", rm.getName(),
3693: read);
3694: } else {
3695: assertNull("Got read method", rm);
3696: }
3697: Method wm = pd.getWriteMethod();
3698: if (write != null) {
3699: assertNotNull("Got write method", wm);
3700: assertEquals("Got correct write method", wm.getName(),
3701: write);
3702: } else {
3703: assertNull("Got write method", wm);
3704: }
3705: } catch (IllegalAccessException e) {
3706: fail("IllegalAccessException");
3707: } catch (InvocationTargetException e) {
3708: fail("InvocationTargetException");
3709: } catch (NoSuchMethodException e) {
3710: fail("NoSuchMethodException");
3711: }
3712:
3713: }
3714:
3715: /**
3716: * Base for testGetReadMethod() series of tests.
3717: *
3718: * @param bean Bean for which to retrieve read methods.
3719: * @param properties Property names to search for
3720: * @param className Class name where this method should be defined
3721: */
3722: protected void testGetReadMethod(Object bean, String properties[],
3723: String className) {
3724:
3725: PropertyDescriptor pd[] = PropertyUtils
3726: .getPropertyDescriptors(bean);
3727: for (int i = 0; i < properties.length; i++) {
3728:
3729: // Identify the property descriptor for this property
3730: if (properties[i].equals("intIndexed"))
3731: continue;
3732: if (properties[i].equals("stringIndexed"))
3733: continue;
3734: if (properties[i].equals("writeOnlyProperty"))
3735: continue;
3736: int n = -1;
3737: for (int j = 0; j < pd.length; j++) {
3738: if (properties[i].equals(pd[j].getName())) {
3739: n = j;
3740: break;
3741: }
3742: }
3743: assertTrue("PropertyDescriptor for " + properties[i],
3744: n >= 0);
3745:
3746: // Locate an accessible property reader method for it
3747: Method reader = PropertyUtils.getReadMethod(pd[n]);
3748: assertNotNull("Reader for " + properties[i], reader);
3749: Class clazz = reader.getDeclaringClass();
3750: assertNotNull("Declaring class for " + properties[i], clazz);
3751: assertEquals(
3752: "Correct declaring class for " + properties[i],
3753: clazz.getName(), className);
3754:
3755: // Actually call the reader method we received
3756: try {
3757: reader.invoke(bean, new Class[0]);
3758: } catch (Throwable t) {
3759: fail("Call for " + properties[i] + ": " + t);
3760: }
3761:
3762: }
3763:
3764: }
3765:
3766: /**
3767: * Base for testGetWriteMethod() series of tests.
3768: *
3769: * @param bean Bean for which to retrieve write methods.
3770: * @param properties Property names to search for
3771: * @param className Class name where this method should be defined
3772: */
3773: protected void testGetWriteMethod(Object bean, String properties[],
3774: String className) {
3775:
3776: PropertyDescriptor pd[] = PropertyUtils
3777: .getPropertyDescriptors(bean);
3778: for (int i = 0; i < properties.length; i++) {
3779:
3780: // Identify the property descriptor for this property
3781: if (properties[i].equals("intIndexed"))
3782: continue;
3783: if (properties[i].equals("listIndexed"))
3784: continue;
3785: if (properties[i].equals("nested"))
3786: continue; // This property is read only
3787: if (properties[i].equals("readOnlyProperty"))
3788: continue;
3789: if (properties[i].equals("stringIndexed"))
3790: continue;
3791: int n = -1;
3792: for (int j = 0; j < pd.length; j++) {
3793: if (properties[i].equals(pd[j].getName())) {
3794: n = j;
3795: break;
3796: }
3797: }
3798: assertTrue("PropertyDescriptor for " + properties[i],
3799: n >= 0);
3800:
3801: // Locate an accessible property reader method for it
3802: Method writer = PropertyUtils.getWriteMethod(pd[n]);
3803: assertNotNull("Writer for " + properties[i], writer);
3804: Class clazz = writer.getDeclaringClass();
3805: assertNotNull("Declaring class for " + properties[i], clazz);
3806: assertEquals(
3807: "Correct declaring class for " + properties[i],
3808: clazz.getName(), className);
3809:
3810: }
3811:
3812: }
3813:
3814: public void testNestedWithIndex() throws Exception {
3815: NestedTestBean nestedBean = new NestedTestBean("base");
3816: nestedBean.init();
3817: nestedBean.getSimpleBeanProperty().init();
3818:
3819: NestedTestBean
3820:
3821: // test first calling properties on indexed beans
3822:
3823: value = (NestedTestBean) PropertyUtils.getProperty(nestedBean,
3824: "indexedProperty[0]");
3825: assertEquals("Cannot get simple index(1)", "Bean@0", value
3826: .getName());
3827: assertEquals("Bug in NestedTestBean", "NOT SET", value
3828: .getTestString());
3829:
3830: value = (NestedTestBean) PropertyUtils.getProperty(nestedBean,
3831: "indexedProperty[1]");
3832: assertEquals("Cannot get simple index(1)", "Bean@1", value
3833: .getName());
3834: assertEquals("Bug in NestedTestBean", "NOT SET", value
3835: .getTestString());
3836:
3837: String prop = (String) PropertyUtils.getProperty(nestedBean,
3838: "indexedProperty[0].testString");
3839: assertEquals("Get property on indexes failed (1)", "NOT SET",
3840: prop);
3841:
3842: prop = (String) PropertyUtils.getProperty(nestedBean,
3843: "indexedProperty[1].testString");
3844: assertEquals("Get property on indexes failed (2)", "NOT SET",
3845: prop);
3846:
3847: PropertyUtils.setProperty(nestedBean,
3848: "indexedProperty[0].testString", "Test#1");
3849: assertEquals("Cannot set property on indexed bean (1)",
3850: "Test#1", nestedBean.getIndexedProperty(0)
3851: .getTestString());
3852:
3853: PropertyUtils.setProperty(nestedBean,
3854: "indexedProperty[1].testString", "Test#2");
3855: assertEquals("Cannot set property on indexed bean (2)",
3856: "Test#2", nestedBean.getIndexedProperty(1)
3857: .getTestString());
3858:
3859: // test first calling indexed properties on a simple property
3860:
3861: value = (NestedTestBean) PropertyUtils.getProperty(nestedBean,
3862: "simpleBeanProperty");
3863: assertEquals("Cannot get simple bean", "Simple Property Bean",
3864: value.getName());
3865: assertEquals("Bug in NestedTestBean", "NOT SET", value
3866: .getTestString());
3867:
3868: value = (NestedTestBean) PropertyUtils.getProperty(nestedBean,
3869: "simpleBeanProperty.indexedProperty[3]");
3870: assertEquals("Cannot get index property on property", "Bean@3",
3871: value.getName());
3872: assertEquals("Bug in NestedTestBean", "NOT SET", value
3873: .getTestString());
3874:
3875: PropertyUtils.setProperty(nestedBean,
3876: "simpleBeanProperty.indexedProperty[3].testString",
3877: "Test#3");
3878: assertEquals(
3879: "Cannot set property on indexed property on property",
3880: "Test#3", nestedBean.getSimpleBeanProperty()
3881: .getIndexedProperty(3).getTestString());
3882: }
3883:
3884: /** Text case for setting properties on inner classes */
3885: public void testGetSetInnerBean() throws Exception {
3886: BeanWithInnerBean bean = new BeanWithInnerBean();
3887:
3888: PropertyUtils.setProperty(bean, "innerBean.fish(loiterTimer)",
3889: "5");
3890: String out = (String) PropertyUtils.getProperty(bean
3891: .getInnerBean(), "fish(loiterTimer)");
3892: assertEquals(
3893: "(1) Inner class property set/get property failed.",
3894: "5", out);
3895:
3896: out = (String) PropertyUtils.getProperty(bean,
3897: "innerBean.fish(loiterTimer)");
3898:
3899: assertEquals(
3900: "(2) Inner class property set/get property failed.",
3901: "5", out);
3902: }
3903:
3904: /** Text case for setting properties on parent */
3905: public void testGetSetParentBean() throws Exception {
3906:
3907: SonOfAlphaBean bean = new SonOfAlphaBean("Roger");
3908:
3909: String out = (String) PropertyUtils.getProperty(bean, "name");
3910: assertEquals("(1) Get/Set On Parent.", "Roger", out);
3911:
3912: PropertyUtils.setProperty(bean, "name", "abcd");
3913: assertEquals("(2) Get/Set On Parent.", "abcd", bean.getName());
3914: }
3915:
3916: public void testSetNoGetter() throws Exception {
3917: BetaBean bean = new BetaBean("Cedric");
3918:
3919: // test standard no getter
3920: bean.setNoGetterProperty("Sigma");
3921: assertEquals("BetaBean test failed", "Sigma", bean.getSecret());
3922:
3923: assertNotNull("Descriptor is null", PropertyUtils
3924: .getPropertyDescriptor(bean, "noGetterProperty"));
3925:
3926: BeanUtils.setProperty(bean, "noGetterProperty", "Omega");
3927: assertEquals("Cannot set no-getter property", "Omega", bean
3928: .getSecret());
3929:
3930: // test mapped no getter descriptor
3931: MappedPropertyDescriptor descriptor = new MappedPropertyDescriptor(
3932: "noGetterMappedProperty", BetaBean.class);
3933:
3934: assertNotNull("Map Descriptor is null", PropertyUtils
3935: .getPropertyDescriptor(bean, "noGetterMappedProperty"));
3936:
3937: PropertyUtils.setMappedProperty(bean, "noGetterMappedProperty",
3938: "Epsilon", "Epsilon");
3939: assertEquals("Cannot set mapped no-getter property",
3940: "MAP:Epsilon", bean.getSecret());
3941: }
3942:
3943: /**
3944: * There is an issue in setNestedProperty/getNestedProperty when the
3945: * target bean is a map and the name string requests mapped or indexed
3946: * operations on a field. These are not supported for fields of a Map,
3947: * but it's an easy mistake to make and this test case ensures that an
3948: * appropriate exception is thrown when a user does this.
3949: * <p>
3950: * The problem is with passing strings of form "a(b)" or "a[3]" to
3951: * setNestedProperty or getNestedProperty when the target bean they
3952: * are applied to implements Map. These strings are actually requesting
3953: * "the result of calling mapped method a on the target object with
3954: * a parameter of b" or "the result of calling indexed method a on the
3955: * target object with a parameter of 3". And these requests are not valid
3956: * when the target is a Map as a Map only supports calling get(fieldName)
3957: * or put(fieldName), neither of which can be further indexed with a
3958: * string or an integer.
3959: * <p>
3960: * However it is likely that some users will assume that "a[3]" when applied
3961: * to a map will be equivalent to (map.get("a"))[3] with the appropriate
3962: * typecasting, or for "a(b)" to be equivalent to map.get("a").get("b").
3963: * <p>
3964: * Here we verify that an exception is thrown if the user makes this
3965: * mistake.
3966: */
3967: public void testNestedPropertyKeyOrIndexOnBeanImplementingMap()
3968: throws Exception {
3969: HashMap map = new HashMap();
3970: HashMap submap = new HashMap();
3971: BetaBean betaBean1 = new BetaBean("test1");
3972: BetaBean betaBean2 = new BetaBean("test2");
3973:
3974: // map.put("submap", submap)
3975: PropertyUtils.setNestedProperty(map, "submap", submap);
3976:
3977: // map.get("submap").put("beta1", betaBean1)
3978: PropertyUtils.setNestedProperty(map, "submap.beta1", betaBean1);
3979: assertEquals("Unexpected keys in map", "submap",
3980: keysToString(map));
3981: assertEquals("Unexpected keys in submap", "beta1",
3982: keysToString(submap));
3983:
3984: try {
3985: // One would expect that the command below would be equivalent to
3986: // Map m = (Map) map.get("submap");
3987: // m.put("beta2", betaBean2)
3988: // However this isn't how javabeans property methods work. A map
3989: // only effectively has "simple" properties, even when the
3990: // returned object is a Map or Array.
3991: PropertyUtils.setNestedProperty(map, "submap(beta2)",
3992: betaBean2);
3993:
3994: // What, no exception? In that case, setNestedProperties has
3995: // probably just tried to do
3996: // map.set("submap(beta2)", betaBean2)
3997: // which is almost certainly not what the used expected. This is
3998: // what beanutils 1.5.0 to 1.7.1 did....
3999: fail("Exception not thrown for invalid setNestedProperty syntax");
4000: } catch (IllegalArgumentException ex) {
4001: // ok, getting an exception was expected. As it is of a generic
4002: // type, let's check the message string to make sure it really
4003: // was caused by the issue we expected.
4004: int index = ex.getMessage().indexOf(
4005: "Indexed or mapped properties are not supported");
4006: assertTrue("Unexpected exception message", index >= 0);
4007: }
4008:
4009: try {
4010: // One would expect that "submap[3]" would be equivalent to
4011: // Object[] objects = (Object[]) map.get("submap");
4012: // return objects[3];
4013: // However this isn't how javabeans property methods work. A map
4014: // only effectively has "simple" properties, even when the
4015: // returned object is a Map or Array.
4016: Object o = PropertyUtils
4017: .getNestedProperty(map, "submap[3]");
4018:
4019: // What, no exception? In that case, getNestedProperties has
4020: // probably just tried to do
4021: // map.get("submap[3]")
4022: // which is almost certainly not what the used expected. This is
4023: // what beanutils 1.5.0 to 1.7.1 did....
4024: fail("Exception not thrown for invalid setNestedProperty syntax");
4025: } catch (IllegalArgumentException ex) {
4026: // ok, getting an exception was expected. As it is of a generic
4027: // type, let's check the message string to make sure it really
4028: // was caused by the issue we expected.
4029: int index = ex.getMessage().indexOf(
4030: "Indexed or mapped properties are not supported");
4031: assertTrue("Unexpected exception message", index >= 0);
4032: }
4033: }
4034:
4035: /**
4036: * Returns a single string containing all the keys in the map,
4037: * sorted in alphabetical order and separated by ", ".
4038: * <p>
4039: * If there are no keys, an empty string is returned.
4040: */
4041: private String keysToString(Map map) {
4042: Object[] mapKeys = map.keySet().toArray();
4043: java.util.Arrays.sort(mapKeys);
4044: StringBuffer buf = new StringBuffer();
4045: for (int i = 0; i < mapKeys.length; ++i) {
4046: if (i != 0)
4047: buf.append(", ");
4048: buf.append(mapKeys[i]);
4049: }
4050: return buf.toString();
4051: }
4052:
4053: /**
4054: * This tests to see that classes that implement Map always have their
4055: * custom properties ignored.
4056: * <p>
4057: * Note that this behaviour has changed several times over past releases
4058: * of beanutils, breaking backwards compatibility each time. Here's hoping
4059: * that the current 1.7.1 release is the last time this behaviour changes!
4060: */
4061: public void testMapExtensionDefault() throws Exception {
4062: ExtendMapBean bean = new ExtendMapBean();
4063:
4064: // setting property direct should work, and not affect map
4065: bean.setUnusuallyNamedProperty("bean value");
4066: assertEquals("Set property direct failed", "bean value", bean
4067: .getUnusuallyNamedProperty());
4068: assertNull("Get on unset map property failed", PropertyUtils
4069: .getNestedProperty(bean, "unusuallyNamedProperty"));
4070:
4071: // setting simple property should call the setter method only, and not
4072: // affect the map.
4073: PropertyUtils.setSimpleProperty(bean, "unusuallyNamedProperty",
4074: "new value");
4075: assertEquals("Set property on map failed (1)", "new value",
4076: bean.getUnusuallyNamedProperty());
4077: assertNull("Get on unset map property failed", PropertyUtils
4078: .getNestedProperty(bean, "unusuallyNamedProperty"));
4079:
4080: // setting via setNestedProperty should affect the map only, and not
4081: // call the setter method.
4082: PropertyUtils.setProperty(bean, "unusuallyNamedProperty",
4083: "next value");
4084: assertEquals(
4085: "setNestedProperty on map not visible to getNestedProperty",
4086: "next value", PropertyUtils.getNestedProperty(bean,
4087: "unusuallyNamedProperty"));
4088: assertEquals(
4089: "Set nested property on map unexpected affected simple property",
4090: "new value", bean.getUnusuallyNamedProperty());
4091: }
4092:
4093: /**
4094: * This tests to see that it is possible to subclass PropertyUtilsBean
4095: * and change the behaviour of setNestedProperty/getNestedProperty when
4096: * dealing with objects that implement Map.
4097: */
4098: public void testMapExtensionCustom() throws Exception {
4099: PropsFirstPropertyUtilsBean utilsBean = new PropsFirstPropertyUtilsBean();
4100: ExtendMapBean bean = new ExtendMapBean();
4101:
4102: // hardly worth testing this, really :-)
4103: bean.setUnusuallyNamedProperty("bean value");
4104: assertEquals("Set property direct failed", "bean value", bean
4105: .getUnusuallyNamedProperty());
4106:
4107: // setSimpleProperty should affect the simple property
4108: utilsBean.setSimpleProperty(bean, "unusuallyNamedProperty",
4109: "new value");
4110: assertEquals("Set property on map failed (1)", "new value",
4111: bean.getUnusuallyNamedProperty());
4112:
4113: // setNestedProperty with setter should affect the simple property
4114: // getNestedProperty with getter should obtain the simple property
4115: utilsBean.setProperty(bean, "unusuallyNamedProperty",
4116: "next value");
4117: assertEquals("Set property on map failed (2)", "next value",
4118: bean.getUnusuallyNamedProperty());
4119: assertEquals("setNestedProperty on non-simple property failed",
4120: "next value", utilsBean.getNestedProperty(bean,
4121: "unusuallyNamedProperty"));
4122:
4123: // setting property without setter should update the map
4124: // getting property without setter should fetch from the map
4125: utilsBean.setProperty(bean, "mapProperty", "value1");
4126: assertEquals("setNestedProperty on non-simple property failed",
4127: "value1", utilsBean.getNestedProperty(bean,
4128: "mapProperty"));
4129:
4130: HashMap myMap = new HashMap();
4131: myMap.put("thebean", bean);
4132: utilsBean.getNestedProperty(myMap, "thebean.mapitem");
4133: utilsBean.getNestedProperty(myMap, "thebean(mapitem)");
4134: }
4135:
4136: /**
4137: * Test {@link PropertyUtilsBean}'s invoke method throwing an IllegalArgumentException
4138: * and check that the "cause" has been properly initialized for JDK 1.4+
4139: * See BEANUTILS-266 for changes and reason for test
4140: */
4141: public void testExceptionFromInvoke() throws Exception {
4142: if (isPre14JVM()) {
4143: return;
4144: }
4145: try {
4146: PropertyUtils.setSimpleProperty(bean, "intProperty", "XXX");
4147: } catch (IllegalArgumentException t) {
4148: Throwable cause = (Throwable) PropertyUtils.getProperty(t,
4149: "cause");
4150: assertNotNull("Cause not found", cause);
4151: assertTrue(
4152: "Expected cause to be IllegalArgumentException, but was: "
4153: + cause.getClass(),
4154: cause instanceof IllegalArgumentException);
4155: // JDK 1.6 doesn't have "argument type mismatch" message
4156: // assertEquals("Check error message", "argument type mismatch", cause.getMessage());
4157: } catch (Throwable t) {
4158: fail("Expected IllegalArgumentException, but threw " + t);
4159: }
4160: }
4161:
4162: /**
4163: * Test for JDK 1.4
4164: */
4165: private boolean isPre14JVM() {
4166: String version = System
4167: .getProperty("java.specification.version");
4168: StringTokenizer tokenizer = new StringTokenizer(version, ".");
4169: if (tokenizer.nextToken().equals("1")) {
4170: String minorVersion = tokenizer.nextToken();
4171: if (minorVersion.equals("0"))
4172: return true;
4173: if (minorVersion.equals("1"))
4174: return true;
4175: if (minorVersion.equals("2"))
4176: return true;
4177: if (minorVersion.equals("3"))
4178: return true;
4179: }
4180: return false;
4181: }
4182: }
|