You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by cr...@apache.org on 2001/05/20 03:18:28 UTC

cvs commit: jakarta-struts/src/share/org/apache/struts/util BeanUtils.java ConvertUtils.java PropertyUtils.java

craigmcc    01/05/19 18:18:28

  Modified:    src/share/org/apache/struts/util BeanUtils.java
                        ConvertUtils.java PropertyUtils.java
  Log:
  Update to the current versions from the Commons Beanutils project.  After
  Struts 1.0 final, Struts will be modified to use the Commons packages
  directly.  This update also fixes two outstanding bug reports:
  
  PR: Bugzilla #1200 - access to public methods defined in nested interfaces
  Submitted by:	Rashid Desai <ra...@hotmail.com>
  
  PR: Bugzilla #1785 - misleading exception when "bean" is null
  Submitted by:  Stephen Breeser <st...@yahoo.com>
  
  Revision  Changes    Path
  1.28      +47 -83    jakarta-struts/src/share/org/apache/struts/util/BeanUtils.java
  
  Index: BeanUtils.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/BeanUtils.java,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- BeanUtils.java	2001/04/16 15:33:16	1.27
  +++ BeanUtils.java	2001/05/20 01:18:27	1.28
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/BeanUtils.java,v 1.27 2001/04/16 15:33:16 craigmcc Exp $
  - * $Revision: 1.27 $
  - * $Date: 2001/04/16 15:33:16 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/BeanUtils.java,v 1.28 2001/05/20 01:18:27 craigmcc Exp $
  + * $Revision: 1.28 $
  + * $Date: 2001/05/20 01:18:27 $
    *
    * ====================================================================
    *
  @@ -73,6 +73,8 @@
   import java.lang.reflect.Method;
   import java.util.ArrayList;
   import java.util.Collection;
  +import java.util.Collections;
  +import java.util.HashMap;
   import java.util.Iterator;
   import java.util.Map;
   
  @@ -80,13 +82,16 @@
   /**
    * Utility methods for populating JavaBeans properties via reflection.
    *
  + * @deprecated At some point after Struts 1.0 final, will be replaced by
  + *  an equivalent class in the Jakarta Commons Beanutils package.
  + *
    * @author Craig R. McClanahan
    * @author Ralph Schaer
    * @author Chris Audley
  - * @version $Revision: 1.27 $ $Date: 2001/04/16 15:33:16 $
  + * @version $Revision: 1.28 $ $Date: 2001/05/20 01:18:27 $
    */
   
  -public final class BeanUtils {
  +public class BeanUtils {
   
   
       // ------------------------------------------------------ Private Variables
  @@ -110,22 +115,6 @@
   
   
       /**
  -     * Return the input string with the first character capitalized.
  -     *
  -     * @param name The string to be modified and returned
  -     */
  -    public static String capitalize(String name) {
  -
  -        if ((name == null) || (name.length() < 1))
  -            return (name);
  -        char chars[] = name.toCharArray();
  -        chars[0] = Character.toUpperCase(chars[0]);
  -        return new String(chars);
  -
  -    }
  -
  -
  -    /**
        * Clone a bean based on the available property getters and setters,
        * even if the bean class itself does not implement Cloneable.
        *
  @@ -153,17 +142,36 @@
   
   
       /**
  -     * Filter the specified string for characters that are senstive to
  -     * HTML interpreters, returning the string with these characters replaced
  -     * by the corresponding character entities.
  +     * Return the entire set of properties for which the specified bean
  +     * provides a read method.  This map can be fed back to a call to
  +     * <code>BeanUtils.populate()</code> to reconsitute the same set of
  +     * properties, modulo differences for read-only and write-only
  +     * properties.
        *
  -     * @param value The string to be filtered and returned
  +     * @param bean Bean whose properties are to be extracted
        *
  -     * @deprecated Use ResponseUtils.filter() instead
  +     * @exception IllegalAccessException if the caller does not have
  +     *  access to the property accessor method
  +     * @exception InvocationTargetException if the property accessor method
  +     *  throws an exception
  +     * @exception NoSuchMethodException if an accessor method for this
  +     *  propety cannot be found
        */
  -    public static String filter(String value) {
  +    public static Map describe(Object bean)
  +        throws IllegalAccessException, InvocationTargetException,
  +               NoSuchMethodException {
   
  -        return (ResponseUtils.filter(value));
  +        if (bean == null)
  +            return (Collections.EMPTY_MAP);
  +        PropertyDescriptor descriptors[] =
  +            PropertyUtils.getPropertyDescriptors(bean);
  +        Map description = new HashMap(descriptors.length);
  +        for (int i = 0; i < descriptors.length; i++) {
  +            String name = descriptors[i].getName();
  +            if (descriptors[i].getReadMethod() != null)
  +                description.put(name, getProperty(bean, name));
  +        }
  +        return (description);
   
       }
   
  @@ -238,7 +246,7 @@
        * @exception NoSuchMethodException if an accessor method for this
        *  propety cannot be found
        */
  -    public static Object getIndexedProperty(Object bean, String name)
  +    public static String getIndexedProperty(Object bean, String name)
   	throws IllegalAccessException, InvocationTargetException,
   	       NoSuchMethodException {
   
  @@ -250,7 +258,8 @@
   
       /**
        * Return the value of the specified indexed property of the specified
  -     * bean, as a String.
  +     * bean, as a String.  The index is specified as a method parameter and
  +     * must *not* be included in the property name expression
        *
        * @param bean Bean whose property is to be extracted
        * @param name Simple property name of the property value to be extracted
  @@ -263,7 +272,7 @@
        * @exception NoSuchMethodException if an accessor method for this
        *  propety cannot be found
        */
  -    public static Object getIndexedProperty(Object bean,
  +    public static String getIndexedProperty(Object bean,
   					    String name, int index)
   	throws IllegalAccessException, InvocationTargetException,
   	       NoSuchMethodException {
  @@ -272,8 +281,7 @@
           sb.append(PropertyUtils.INDEXED_DELIM);
           sb.append(index);
           sb.append(PropertyUtils.INDEXED_DELIM2);
  -        Object value = PropertyUtils.getIndexedProperty(bean,
  -                                                        sb.toString());
  +        Object value = PropertyUtils.getIndexedProperty(bean, sb.toString());
           return (ConvertUtils.convert(value));
   
       }
  @@ -330,56 +338,6 @@
   
   
       /**
  -     * Return the value of the specified property of the specified
  -     * bean, with no type conversinos.
  -     *
  -     * @param bean Bean whose property is to be extracted
  -     * @param name Name of the property to be extracted
  -     *
  -     * @exception IllegalAccessException if the caller does not have
  -     *  access to the property accessor method
  -     * @exception InvocationTargetException if the property accessor method
  -     *  throws an exception
  -     * @exception NoSuchMethodException if an accessor method for this
  -     *  propety cannot be found
  -     *
  -     * @deprecated Use <code>PropertyUtils.getProperty()</code> instead.
  -     */
  -    public static Object getPropertyValue(Object bean, String name)
  -        throws IllegalAccessException, InvocationTargetException,
  -               NoSuchMethodException {
  -
  -        return (PropertyUtils.getProperty(bean, name));
  -
  -    }
  -
  -
  -    /**
  -     * Return the value of the specified scalar property of the specified
  -     * bean, as a String.
  -     *
  -     * @param bean Bean whose property is to be extracted
  -     * @param name Name of the property to be extracted
  -     *
  -     * @exception IllegalAccessException if the caller does not have
  -     *  access to the property accessor method
  -     * @exception InvocationTargetException if the property accessor method
  -     *  throws an exception
  -     * @exception NoSuchMethodException if an accessor method for this
  -     *  propety cannot be found
  -     *
  -     * @deprecated Use getSimpleProperty(Object,String) instead
  -     */
  -    public static String getScalarProperty(Object bean, String name)
  -        throws IllegalAccessException, InvocationTargetException,
  -               NoSuchMethodException {
  -
  -        return (getSimpleProperty(bean, name));
  -
  -    }
  -
  -
  -    /**
        * Return the value of the specified simple property of the specified
        * bean, converted to a String.
        *
  @@ -438,9 +396,11 @@
           if ((bean == null) || (properties == null))
               return;
   
  +        /*
           if (debug >= 1)
               System.out.println("BeanUtils.populate(" + bean + ", " +
                                  properties + ")");
  +        */
   
           // Loop through the property name/value pairs to be set
           Iterator names = properties.keySet().iterator();
  @@ -491,8 +451,10 @@
               if (setter == null)
                   setter = descriptor.getWriteMethod();
               if (setter == null) {
  +                /*
                   if (debug >= 1)
                       System.out.println("    No setter method, skipping");
  +                */
                   continue;
               }
               Class parameterTypes[] = setter.getParameterTypes();
  @@ -545,10 +507,12 @@
               try {
                   PropertyUtils.setProperty(bean, name, parameters[0]);
               } catch (NoSuchMethodException e) {
  +                /*
                   if (debug >= 1) {
                       System.out.println("    CANNOT HAPPEN: " + e);
                       e.printStackTrace(System.out);
                   }
  +                */
               }
   
           }
  
  
  
  1.8       +8 -5      jakarta-struts/src/share/org/apache/struts/util/ConvertUtils.java
  
  Index: ConvertUtils.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/ConvertUtils.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ConvertUtils.java	2001/02/12 00:32:12	1.7
  +++ ConvertUtils.java	2001/05/20 01:18:27	1.8
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/ConvertUtils.java,v 1.7 2001/02/12 00:32:12 craigmcc Exp $
  - * $Revision: 1.7 $
  - * $Date: 2001/02/12 00:32:12 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/ConvertUtils.java,v 1.8 2001/05/20 01:18:27 craigmcc Exp $
  + * $Revision: 1.8 $
  + * $Date: 2001/05/20 01:18:27 $
    *
    * ====================================================================
    *
  @@ -74,13 +74,16 @@
    * Object or Object array of a non-String and non-primitive type, it will be
    * converted to a scalar String or array of Strings, as appropriate.
    *
  + * @deprecated At some point after Struts 1.0 final, will be replaced by
  + *  an equivalent class in the Jakarta Commons Beanutils package.
  + *
    * @author Craig R. McClanahan
    * @author Ralph Schaer
    * @author Chris Audley
  - * @version $Revision: 1.7 $ $Date: 2001/02/12 00:32:12 $
  + * @version $Revision: 1.8 $ $Date: 2001/05/20 01:18:27 $
    */
   
  -public final class ConvertUtils {
  +public class ConvertUtils {
   
   
       // ------------------------------------------------------ Static Properties
  
  
  
  1.14      +230 -36   jakarta-struts/src/share/org/apache/struts/util/PropertyUtils.java
  
  Index: PropertyUtils.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/PropertyUtils.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- PropertyUtils.java	2001/02/12 00:32:14	1.13
  +++ PropertyUtils.java	2001/05/20 01:18:28	1.14
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/PropertyUtils.java,v 1.13 2001/02/12 00:32:14 craigmcc Exp $
  - * $Revision: 1.13 $
  - * $Date: 2001/02/12 00:32:14 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/PropertyUtils.java,v 1.14 2001/05/20 01:18:28 craigmcc Exp $
  + * $Revision: 1.14 $
  + * $Date: 2001/05/20 01:18:28 $
    *
    * ====================================================================
    *
  @@ -72,6 +72,9 @@
   import java.lang.reflect.InvocationTargetException;
   import java.lang.reflect.Method;
   import java.lang.reflect.Modifier;
  +import java.util.Collections;
  +import java.util.HashMap;
  +import java.util.Map;
   
   
   /**
  @@ -114,13 +117,16 @@
    *     forms combining nested and indexed references are also supported.</li>
    * </ul>
    *
  + * @deprecated At some point after Struts 1.0 final, will be replaced by
  + *  an equivalent class in the Jakarta Commons Beanutils package.
  + *
    * @author Craig R. McClanahan
    * @author Ralph Schaer
    * @author Chris Audley
  - * @version $Revision: 1.13 $ $Date: 2001/02/12 00:32:14 $
  + * @version $Revision: 1.14 $ $Date: 2001/05/20 01:18:28 $
    */
   
  -public final class PropertyUtils {
  +public class PropertyUtils {
   
   
       // ----------------------------------------------------- Manifest Constants
  @@ -191,6 +197,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
  @@ -200,6 +208,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();
  @@ -217,6 +231,41 @@
   
   
       /**
  +     * Return the entire set of properties for which the specified bean
  +     * provides a read method.  This map contains the unconverted property
  +     * values for all properties for which a read method is provided
  +     * (i.e. where the <code>getReadMethod()</code> returns non-null).
  +     *
  +     * @param bean Bean whose properties are to be extracted
  +     *
  +     * @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
  +     *  propety cannot be found
  +     */
  +    public static Map describe(Object bean)
  +        throws IllegalAccessException, InvocationTargetException,
  +               NoSuchMethodException {
  +
  +        if (bean == null)
  +            throw new IllegalArgumentException("No bean specified");
  +        PropertyDescriptor descriptors[] =
  +            PropertyUtils.getPropertyDescriptors(bean);
  +        Map description = new HashMap(descriptors.length);
  +        for (int i = 0; i < descriptors.length; i++) {
  +            String name = descriptors[i].getName();
  +            if (descriptors[i].getReadMethod() != null)
  +                description.put(name, getProperty(bean, name));
  +        }
  +        return (description);
  +
  +    }
  +
  +
  +    /**
        * Return the value of the specified indexed property of the specified
        * bean, with no type conversions.  The zero-relative index of the
        * required value must be included (in square brackets) as a suffix to
  @@ -229,6 +278,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
  @@ -238,6 +289,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);
  @@ -270,6 +326,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
  @@ -280,6 +338,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);
  @@ -323,6 +386,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
  @@ -334,6 +399,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)
  @@ -369,6 +439,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
  @@ -397,6 +469,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
  @@ -409,6 +483,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);
  @@ -451,16 +530,19 @@
        * 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();
  -	PropertyDescriptor descriptors[] =
  -	    (PropertyDescriptor[]) descriptorsCache.get(beanClassName);
  +	PropertyDescriptor descriptors[] = null;
  +        descriptors =
  +            (PropertyDescriptor[]) descriptorsCache.get(beanClassName);
   	if (descriptors != null)
   	    return (descriptors);
   
  @@ -474,7 +556,7 @@
   	descriptors = beanInfo.getPropertyDescriptors();
   	if (descriptors == null)
   	    descriptors = new PropertyDescriptor[0];
  -	descriptorsCache.put(beanClassName, descriptors);
  +        descriptorsCache.put(beanClassName, descriptors);
   	return (descriptors);
   
       }
  @@ -498,6 +580,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
  @@ -509,6 +593,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)
  @@ -534,6 +623,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
  @@ -545,6 +636,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)
  @@ -559,6 +655,19 @@
   
   
       /**
  +     * Return an accessible property getter method for this property,
  +     * if there is one; otherwise return <code>null</code>.
  +     *
  +     * @param descriptor Property descriptor to return a getter for
  +     */
  +    public static Method getReadMethod(PropertyDescriptor descriptor) {
  +
  +        return (getAccessibleMethod(descriptor.getReadMethod()));
  +
  +    }
  +
  +
  +    /**
        * Return the value of the specified simple property of the specified
        * bean, with no type conversions.
        *
  @@ -567,6 +676,10 @@
        *
        * @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
        *  throws an exception
        * @exception NoSuchMethodException if an accessor method for this
  @@ -576,6 +689,19 @@
   	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
  +                ("Nested property names are not allowed");
  +        else if (name.indexOf(INDEXED_DELIM) >= 0)
  +            throw new IllegalArgumentException
  +                ("Indexed property names are not allowed");
  +
   	// Retrieve the property getter method for the specified property
   	PropertyDescriptor descriptor =
   	    getPropertyDescriptor(bean, name);
  @@ -595,6 +721,19 @@
   
   
       /**
  +     * Return an accessible property setter method for this property,
  +     * if there is one; otherwise return <code>null</code>.
  +     *
  +     * @param descriptor Property descriptor to return a setter for
  +     */
  +    public static Method getWriteMethod(PropertyDescriptor descriptor) {
  +
  +        return (getAccessibleMethod(descriptor.getWriteMethod()));
  +
  +    }
  +
  +
  +    /**
        * Set the value of the specified indexed property of the specified
        * bean, with no type conversions.  The zero-relative index of the
        * required value must be included (in square brackets) as a suffix to
  @@ -609,6 +748,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
  @@ -619,9 +760,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);
  @@ -656,6 +798,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
  @@ -666,9 +810,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 =
  @@ -718,6 +863,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
  @@ -730,9 +877,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);
  @@ -770,6 +918,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
  @@ -794,6 +944,10 @@
        *
        * @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
        *  throws an exception
        * @exception NoSuchMethodException if an accessor method for this
  @@ -804,9 +958,18 @@
   	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)
  +            throw new IllegalArgumentException
  +                ("Nested property names are not allowed");
  +        else if (name.indexOf(INDEXED_DELIM) >= 0)
  +            throw new IllegalArgumentException
  +                ("Indexed property names are not allowed");
   
   	// Retrieve the property setter method for the specified property
   	PropertyDescriptor descriptor =
  @@ -855,9 +1018,16 @@
               return (method);
           }
   
  -        // Check the implemented interfaces
  +        // Check the implemented interfaces and subinterfaces
           String methodName = method.getName();
           Class[] parameterTypes = method.getParameterTypes();
  +        method =
  +            getAccessibleMethodFromInterfaceNest(clazz,
  +                                                 method.getName(),
  +                                                 method.getParameterTypes());
  +        return (method);
  +
  +        /*
           Class[] interfaces = clazz.getInterfaces();
           for (int i = 0; i < interfaces.length; i++) {
               // Is this interface public?
  @@ -877,32 +1047,56 @@
   
           // We are out of luck
           return (null);
  +        */
   
       }
   
   
       /**
  -     * Return an accessible property getter method for this property,
  -     * if there is one; otherwise return <code>null</code>.
  +     * Return an accessible method (that is, one that can be invoked via
  +     * reflection) that implements the specified method, by scanning through
  +     * all implemented interfaces and subinterfaces.  If no such Method
  +     * can be found, return <code>null</code>.
        *
  -     * @param descriptor Property descriptor to return a getter for
  +     * @param clazz Parent class for the interfaces to be checked
  +     * @param methodName Method name of the method we wish to call
  +     * @param parameterTypes The parameter type signatures
        */
  -    private static Method getReadMethod(PropertyDescriptor descriptor) {
  +    private static Method getAccessibleMethodFromInterfaceNest
  +        (Class clazz, String methodName, Class parameterTypes[]) {
   
  -        return (getAccessibleMethod(descriptor.getReadMethod()));
  +        Method method = null;
   
  -    }
  +        // Check the implemented interfaces of the parent class
  +        Class interfaces[] = clazz.getInterfaces();
  +        for (int i = 0; i < interfaces.length; i++) {
   
  +            // Is this interface public?
  +            if (!Modifier.isPublic(interfaces[i].getModifiers()))
  +                continue;
   
  -    /**
  -     * Return an accessible property setter method for this property,
  -     * if there is one; otherwise return <code>null</code>.
  -     *
  -     * @param descriptor Property descriptor to return a setter for
  -     */
  -    private static Method getWriteMethod(PropertyDescriptor descriptor) {
  +            // Does the method exist on this interface?
  +            try {
  +                method = interfaces[i].getDeclaredMethod(methodName,
  +                                                         parameterTypes);
  +            } catch (NoSuchMethodException e) {
  +                ;
  +            }
  +            if (method != null)
  +                break;
   
  -        return (getAccessibleMethod(descriptor.getWriteMethod()));
  +            // Recursively check our parent interfaces
  +            method =
  +                getAccessibleMethodFromInterfaceNest(interfaces[i],
  +                                                     methodName,
  +                                                     parameterTypes);
  +            if (method != null)
  +                break;
  +
  +        }
  +
  +        // Return whatever we have found
  +        return (method);
   
       }