craigmcc 01/05/19 17:32:24 Modified: beanutils/src/java/org/apache/commons/beanutils PropertyUtils.java beanutils/src/test/org/apache/commons/beanutils PropertyUtilsTestCase.java Log: Throw IllegalArgumentException (instead of returning misleading results) when the "bean" or "name" arguments to most method calls are null. Add relevant unit test cases to validate this behavior. Revision Changes Path 1.6 +94 -18 jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/PropertyUtils.java Index: PropertyUtils.java =================================================================== RCS file: /home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/PropertyUtils.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- PropertyUtils.java 2001/05/07 02:09:01 1.5 +++ PropertyUtils.java 2001/05/20 00:32:24 1.6 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/PropertyUtils.java,v 1.5 2001/05/07 02:09:01 craigmcc Exp $ - * $Revision: 1.5 $ - * $Date: 2001/05/07 02:09:01 $ + * $Header: /home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/PropertyUtils.java,v 1.6 2001/05/20 00:32:24 craigmcc Exp $ + * $Revision: 1.6 $ + * $Date: 2001/05/20 00:32:24 $ * * ==================================================================== * @@ -121,7 +121,7 @@ * @author Craig R. McClanahan * @author Ralph Schaer * @author Chris Audley - * @version $Revision: 1.5 $ $Date: 2001/05/07 02:09:01 $ + * @version $Revision: 1.6 $ $Date: 2001/05/20 00:32:24 $ */ public class PropertyUtils { @@ -195,6 +195,8 @@ * * @exception IllegalAccessException if the caller does not have * access to the property accessor method + * @exception IllegalArgumentException if the <code>dest</code> or + * <code>orig</code> argument is null * @exception InvocationTargetException if the property accessor method * throws an exception * @exception NoSuchMethodException if an accessor method for this @@ -204,6 +206,12 @@ throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + if (dest == null) + throw new IllegalArgumentException + ("No destination bean specified"); + if (orig == null) + throw new IllegalArgumentException("No origin bean specified"); + PropertyDescriptor origDescriptors[] = getPropertyDescriptors(orig); for (int i = 0; i < origDescriptors.length; i++) { String name = origDescriptors[i].getName(); @@ -230,6 +238,7 @@ * * @exception IllegalAccessException if the caller does not have * access to the property accessor method + * @exception IllegalArgumentException if <code>bean</code> is null * @exception InvocationTargetException if the property accessor method * throws an exception * @exception NoSuchMethodException if an accessor method for this @@ -240,7 +249,7 @@ NoSuchMethodException { if (bean == null) - return (Collections.EMPTY_MAP); + throw new IllegalArgumentException("No bean specified"); PropertyDescriptor descriptors[] = PropertyUtils.getPropertyDescriptors(bean); Map description = new HashMap(descriptors.length); @@ -267,6 +276,8 @@ * * @exception IllegalAccessException if the caller does not have * access to the property accessor method + * @exception IllegalArgumentException if <code>bean</code> or + * <code>name</code> is null * @exception InvocationTargetException if the property accessor method * throws an exception * @exception NoSuchMethodException if an accessor method for this @@ -276,6 +287,11 @@ throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + if (bean == null) + throw new IllegalArgumentException("No bean specified"); + if (name == null) + throw new IllegalArgumentException("No name specified"); + // Identify the index of the requested individual property int delim = name.indexOf(INDEXED_DELIM); int delim2 = name.indexOf(INDEXED_DELIM2); @@ -308,6 +324,8 @@ * * @exception IllegalAccessException if the caller does not have * access to the property accessor method + * @exception IllegalArgumentException if <code>bean</code> or + * <code>name</code> is null * @exception InvocationTargetException if the property accessor method * throws an exception * @exception NoSuchMethodException if an accessor method for this @@ -318,6 +336,11 @@ throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + if (bean == null) + throw new IllegalArgumentException("No bean specified"); + if (name == null) + throw new IllegalArgumentException("No name specified"); + // Retrieve the property descriptor for the specified property PropertyDescriptor descriptor = getPropertyDescriptor(bean, name); @@ -361,6 +384,8 @@ * * @exception IllegalAccessException if the caller does not have * access to the property accessor method + * @exception IllegalArgumentException if <code>bean</code> or + * <code>name</code> is null * @exception IllegalArgumentException if a nested reference to a * property returns null * @exception InvocationTargetException if the property accessor method @@ -372,6 +397,11 @@ throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + if (bean == null) + throw new IllegalArgumentException("No bean specified"); + if (name == null) + throw new IllegalArgumentException("No name specified"); + while (true) { int delim = name.indexOf(NESTED_DELIM); if (delim < 0) @@ -407,6 +437,8 @@ * * @exception IllegalAccessException if the caller does not have * access to the property accessor method + * @exception IllegalArgumentException if <code>bean</code> or + * <code>name</code> is null * @exception InvocationTargetException if the property accessor method * throws an exception * @exception NoSuchMethodException if an accessor method for this @@ -435,6 +467,8 @@ * * @exception IllegalAccessException if the caller does not have * access to the property accessor method + * @exception IllegalArgumentException if <code>bean</code> or + * <code>name</code> is null * @exception IllegalArgumentException if a nested reference to a * property returns null * @exception InvocationTargetException if the property accessor method @@ -447,6 +481,11 @@ throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + if (bean == null) + throw new IllegalArgumentException("No bean specified"); + if (name == null) + throw new IllegalArgumentException("No name specified"); + // Resolve nested references while (true) { int period = name.indexOf(NESTED_DELIM); @@ -489,11 +528,13 @@ * and caching them the first time a particular bean class is encountered. * * @param bean Bean for which property descriptors are requested + * + * @exception IllegalArgumentException if <code>bean</code> is null */ public static PropertyDescriptor[] getPropertyDescriptors(Object bean) { if (bean == null) - return (new PropertyDescriptor[0]); + throw new IllegalArgumentException("No bean specified"); // Look up any cached descriptors for this bean class String beanClassName = bean.getClass().getName(); @@ -537,6 +578,8 @@ * * @exception IllegalAccessException if the caller does not have * access to the property accessor method + * @exception IllegalArgumentException if <code>bean</code> or + * <code>name</code> is null * @exception IllegalArgumentException if a nested reference to a * property returns null * @exception InvocationTargetException if the property accessor method @@ -548,6 +591,11 @@ throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + if (bean == null) + throw new IllegalArgumentException("No bean specified"); + if (name == null) + throw new IllegalArgumentException("No name specified"); + PropertyDescriptor descriptor = getPropertyDescriptor(bean, name); if (descriptor != null) @@ -573,6 +621,8 @@ * * @exception IllegalAccessException if the caller does not have * access to the property accessor method + * @exception IllegalArgumentException if <code>bean</code> or + * <code>name</code> is null * @exception IllegalArgumentException if a nested reference to a * property returns null * @exception InvocationTargetException if the property accessor method @@ -584,6 +634,11 @@ throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + if (bean == null) + throw new IllegalArgumentException("No bean specified"); + if (name == null) + throw new IllegalArgumentException("No name specified"); + PropertyDescriptor descriptor = getPropertyDescriptor(bean, name); if (descriptor == null) @@ -619,6 +674,8 @@ * * @exception IllegalAccessException if the caller does not have * access to the property accessor method + * @exception IllegalArgumentException if <code>bean</code> or + * <code>name</code> is null * @exception IllegalArgumentException if the property name * is nested or indexed * @exception InvocationTargetException if the property accessor method @@ -630,6 +687,11 @@ throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + if (bean == null) + throw new IllegalArgumentException("No bean specified"); + if (name == null) + throw new IllegalArgumentException("No name specified"); + // Validate the syntax of the property name if (name.indexOf(NESTED_DELIM) >= 0) throw new IllegalArgumentException @@ -684,6 +746,8 @@ * * @exception IllegalAccessException if the caller does not have * access to the property accessor method + * @exception IllegalArgumentException if <code>bean</code> or + * <code>name</code> is null * @exception InvocationTargetException if the property accessor method * throws an exception * @exception NoSuchMethodException if an accessor method for this @@ -694,9 +758,10 @@ throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { - if (debug >= 1) - System.out.println("setIndexedProperty('" + bean + ", " + - name + ", " + value + ")"); + if (bean == null) + throw new IllegalArgumentException("No bean specified"); + if (name == null) + throw new IllegalArgumentException("No name specified"); // Identify the index of the requested individual property int delim = name.indexOf(INDEXED_DELIM); @@ -731,6 +796,8 @@ * * @exception IllegalAccessException if the caller does not have * access to the property accessor method + * @exception IllegalArgumentException if <code>bean</code> or + * <code>name</code> is null * @exception InvocationTargetException if the property accessor method * throws an exception * @exception NoSuchMethodException if an accessor method for this @@ -741,9 +808,10 @@ throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { - if (debug >= 1) - System.out.println("setIndexedProperty('" + bean + ", " + - name + ", " + index + ", " + value + ")"); + if (bean == null) + throw new IllegalArgumentException("No bean specified"); + if (name == null) + throw new IllegalArgumentException("No name specified"); // Retrieve the property descriptor for the specified property PropertyDescriptor descriptor = @@ -793,6 +861,8 @@ * * @exception IllegalAccessException if the caller does not have * access to the property accessor method + * @exception IllegalArgumentException if <code>bean</code> or + * <code>name</code> is null * @exception IllegalArgumentException if a nested reference to a * property returns null * @exception InvocationTargetException if the property accessor method @@ -805,9 +875,10 @@ throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { - if (debug >= 1) - System.out.println("setNestedProperty('" + bean + ", " + - name + ", " + value + ")"); + if (bean == null) + throw new IllegalArgumentException("No bean specified"); + if (name == null) + throw new IllegalArgumentException("No name specified"); while (true) { int delim = name.indexOf(NESTED_DELIM); @@ -845,6 +916,8 @@ * * @exception IllegalAccessException if the caller does not have * access to the property accessor method + * @exception IllegalArgumentException if <code>bean</code> or + * <code>name</code> is null * @exception InvocationTargetException if the property accessor method * throws an exception * @exception NoSuchMethodException if an accessor method for this @@ -869,6 +942,8 @@ * * @exception IllegalAccessException if the caller does not have * access to the property accessor method + * @exception IllegalArgumentException if <code>bean</code> or + * <code>name</code> is null * @exception IllegalArgumentException if the property name is * nested or indexed * @exception InvocationTargetException if the property accessor method @@ -881,9 +956,10 @@ throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { - if (debug >= 1) - System.out.println("setSimpleProperty('" + bean + ", " + - name + ", " + value + ")"); + if (bean == null) + throw new IllegalArgumentException("No bean specified"); + if (name == null) + throw new IllegalArgumentException("No name specified"); // Validate the syntax of the property name if (name.indexOf(NESTED_DELIM) >= 0) 1.6 +151 -4 jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/PropertyUtilsTestCase.java Index: PropertyUtilsTestCase.java =================================================================== RCS file: /home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/PropertyUtilsTestCase.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- PropertyUtilsTestCase.java 2001/05/07 02:09:02 1.5 +++ PropertyUtilsTestCase.java 2001/05/20 00:32:24 1.6 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/PropertyUtilsTestCase.java,v 1.5 2001/05/07 02:09:02 craigmcc Exp $ - * $Revision: 1.5 $ - * $Date: 2001/05/07 02:09:02 $ + * $Header: /home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/PropertyUtilsTestCase.java,v 1.6 2001/05/20 00:32:24 craigmcc Exp $ + * $Revision: 1.6 $ + * $Date: 2001/05/20 00:32:24 $ * * ==================================================================== * @@ -91,7 +91,7 @@ * </ul> * * @author Craig R. McClanahan - * @version $Revision: 1.5 $ $Date: 2001/05/07 02:09:02 $ + * @version $Revision: 1.6 $ $Date: 2001/05/20 00:32:24 $ */ public class PropertyUtilsTestCase extends TestCase { @@ -238,6 +238,32 @@ /** + * Corner cases on getPropertyDescriptor invalid arguments. + */ + public void testGetDescriptorArguments() { + + try { + PropertyUtils.getPropertyDescriptor(null, "stringProperty"); + fail("Should throw IllegalArgumentException 1"); + } catch (IllegalArgumentException e) { + ; // Expected response + } catch (Throwable t) { + fail("Threw " + t + " instead of IllegalArgumentException 1"); + } + + try { + PropertyUtils.getPropertyDescriptor(bean, null); + fail("Should throw IllegalArgumentException 2"); + } catch (IllegalArgumentException e) { + ; // Expected response + } catch (Throwable t) { + fail("Threw " + t + " instead of IllegalArgumentException 2"); + } + + } + + + /** * Positive getPropertyDescriptor on property <code>booleanProperty</code>. */ public void testGetDescriptorBoolean() { @@ -388,6 +414,49 @@ /** + * Corner cases on getPropertyDescriptors invalid arguments. + */ + public void testGetDescriptorsArguments() { + + try { + PropertyUtils.getPropertyDescriptors(null); + fail("Should throw IllegalArgumentException"); + } catch (IllegalArgumentException e) { + ; // Expected response + } catch (Throwable t) { + fail("Threw " + t + " instead of IllegalArgumentException"); + } + + } + + + /** + * Corner cases on getNestedProperty invalid arguments. + */ + public void testGetNestedArguments() { + + try { + PropertyUtils.getNestedProperty(null, "stringProperty"); + fail("Should throw IllegalArgumentException 1"); + } catch (IllegalArgumentException e) { + ; // Expected response + } catch (Throwable t) { + fail("Threw " + t + " instead of IllegalArgumentException 1"); + } + + try { + PropertyUtils.getNestedProperty(bean, null); + fail("Should throw IllegalArgumentException 2"); + } catch (IllegalArgumentException e) { + ; // Expected response + } catch (Throwable t) { + fail("Threw " + t + " instead of IllegalArgumentException 2"); + } + + } + + + /** * Test getNestedProperty on a boolean property. */ public void testGetNestedBoolean() { @@ -729,6 +798,32 @@ /** + * Corner cases on getSimpleProperty invalid arguments. + */ + public void testGetSimpleArguments() { + + try { + PropertyUtils.getSimpleProperty(null, "stringProperty"); + fail("Should throw IllegalArgumentException 1"); + } catch (IllegalArgumentException e) { + ; // Expected response + } catch (Throwable t) { + fail("Threw " + t + " instead of IllegalArgumentException 1"); + } + + try { + PropertyUtils.getSimpleProperty(bean, null); + fail("Should throw IllegalArgumentException 2"); + } catch (IllegalArgumentException e) { + ; // Expected response + } catch (Throwable t) { + fail("Threw " + t + " instead of IllegalArgumentException 2"); + } + + } + + + /** * Test getSimpleProperty on a boolean property. */ public void testGetSimpleBoolean() { @@ -1073,6 +1168,32 @@ /** + * Corner cases on setNestedProperty invalid arguments. + */ + public void testSetNestedArguments() { + + try { + PropertyUtils.setNestedProperty(null, "stringProperty", ""); + fail("Should throw IllegalArgumentException 1"); + } catch (IllegalArgumentException e) { + ; // Expected response + } catch (Throwable t) { + fail("Threw " + t + " instead of IllegalArgumentException 1"); + } + + try { + PropertyUtils.setNestedProperty(bean, null, ""); + fail("Should throw IllegalArgumentException 2"); + } catch (IllegalArgumentException e) { + ; // Expected response + } catch (Throwable t) { + fail("Threw " + t + " instead of IllegalArgumentException 2"); + } + + } + + + /** * Test setNextedProperty on a boolean property. */ public void testSetNestedBoolean() { @@ -1335,6 +1456,32 @@ } catch (NoSuchMethodException e) { fail("NoSuchMethodException"); } + + } + + + /** + * Corner cases on setSimpleProperty invalid arguments. + */ + public void testSetSimpleArguments() { + + try { + PropertyUtils.setSimpleProperty(null, "stringProperty", ""); + fail("Should throw IllegalArgumentException 1"); + } catch (IllegalArgumentException e) { + ; // Expected response + } catch (Throwable t) { + fail("Threw " + t + " instead of IllegalArgumentException 1"); + } + + try { + PropertyUtils.setSimpleProperty(bean, null, ""); + fail("Should throw IllegalArgumentException 2"); + } catch (IllegalArgumentException e) { + ; // Expected response + } catch (Throwable t) { + fail("Threw " + t + " instead of IllegalArgumentException 2"); + } }