You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by cr...@apache.org on 2002/01/12 21:44:05 UTC

cvs commit: jakarta-commons/beanutils/src/test/org/apache/commons/beanutils WrapDynaBeanTestCase.java BasicDynaBeanTestCase.java TestBean.java

craigmcc    02/01/12 12:44:05

  Modified:    beanutils build.xml
               beanutils/src/java/org/apache/commons/beanutils
                        BasicDynaClass.java PropertyUtils.java
               beanutils/src/test/org/apache/commons/beanutils
                        BasicDynaBeanTestCase.java TestBean.java
  Added:       beanutils/src/java/org/apache/commons/beanutils
                        WrapDynaBean.java WrapDynaClass.java
               beanutils/src/test/org/apache/commons/beanutils
                        WrapDynaBeanTestCase.java
  Log:
  Add an implementation of DynaBean that wraps existing standard JavaBeans
  with the DynaBean APIs.  Add test cases to make sure that all the tests
  passed by BasicDynaBean also pass, except for the contains() and remove()
  method tests -- these methods are not currently supported by the
  WrapDynaBean implementation.
  
  Canonical usage pattern:
  
    MyAddressClass myBean = ...;
    WrapDynaBean dynaBean = new WrapDynaBean(myBean);
    String name = (String) dynaBean.get("name");
    dynaBean.put("country", "US");
  
  Revision  Changes    Path
  1.26      +11 -1     jakarta-commons/beanutils/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/beanutils/build.xml,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- build.xml	9 Jan 2002 19:42:07 -0000	1.25
  +++ build.xml	12 Jan 2002 20:44:05 -0000	1.26
  @@ -3,7 +3,7 @@
   
   <!--
           "Bean Utilities" component of the Jakarta Commons Subproject
  -        $Id: build.xml,v 1.25 2002/01/09 19:42:07 craigmcc Exp $
  +        $Id: build.xml,v 1.26 2002/01/12 20:44:05 craigmcc Exp $
   -->
   
   
  @@ -215,6 +215,7 @@
   
     <target name="test"  depends="compile.tests,
                                   test.basic.dynabean,
  +                                test.wrap.dynabean,
                                   test.dyna.property,
                                   test.property,
                                   test.dyna.bean,
  @@ -230,6 +231,15 @@
       <java classname="${test.runner}" fork="yes"
           failonerror="${test.failonerror}">
         <arg value="org.apache.commons.beanutils.BasicDynaBeanTestCase"/>
  +      <classpath refid="test.classpath"/>
  +    </java>
  +  </target>
  +
  +  <target name="test.wrap.dynabean" depends="compile.tests">
  +    <echo message="Running WrapDynaBean tests ..."/>
  +    <java classname="${test.runner}" fork="yes"
  +        failonerror="${test.failonerror}">
  +      <arg value="org.apache.commons.beanutils.WrapDynaBeanTestCase"/>
         <classpath refid="test.classpath"/>
       </java>
     </target>
  
  
  
  1.5       +19 -16    jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/BasicDynaClass.java
  
  Index: BasicDynaClass.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/BasicDynaClass.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- BasicDynaClass.java	11 Jan 2002 02:25:43 -0000	1.4
  +++ BasicDynaClass.java	12 Jan 2002 20:44:05 -0000	1.5
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/BasicDynaClass.java,v 1.4 2002/01/11 02:25:43 craigmcc Exp $
  - * $Revision: 1.4 $
  - * $Date: 2002/01/11 02:25:43 $
  + * $Header: /home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/BasicDynaClass.java,v 1.5 2002/01/12 20:44:05 craigmcc Exp $
  + * $Revision: 1.5 $
  + * $Date: 2002/01/12 20:44:05 $
    *
    * ====================================================================
    *
  @@ -78,7 +78,7 @@
    * used to associate the DynaBean instance with this DynaClass.</p>
    *
    * @author Craig McClanahan
  - * @version $Revision: 1.4 $ $Date: 2002/01/11 02:25:43 $
  + * @version $Revision: 1.5 $ $Date: 2002/01/12 20:44:05 $
    */
   
   public class BasicDynaClass implements DynaClass {
  @@ -187,18 +187,6 @@
   
   
       /**
  -     * Return the Class object we will use to create new instances in the
  -     * <code>newInstance()</code> method.  This Class <strong>MUST</strong>
  -     * implement the <code>DynaBean</code> interface.
  -     */
  -    public Class getDynaBeanClass() {
  -
  -        return (this.dynaBeanClass);
  -
  -    }
  -
  -
  -    /**
        * Return the name of this DynaClass (analogous to the
        * <code>getName()</code> method of <code>java.lang.Class</code), which
        * allows the same <code>DynaClass</code> implementation class to support
  @@ -266,6 +254,21 @@
               throw new InstantiationException
                   (e.getTargetException().getMessage());
           }
  +
  +    }
  +
  +
  +    // --------------------------------------------------------- Public Methods
  +
  +
  +    /**
  +     * Return the Class object we will use to create new instances in the
  +     * <code>newInstance()</code> method.  This Class <strong>MUST</strong>
  +     * implement the <code>DynaBean</code> interface.
  +     */
  +    public Class getDynaBeanClass() {
  +
  +        return (this.dynaBeanClass);
   
       }
   
  
  
  
  1.20      +51 -23    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.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- PropertyUtils.java	11 Jan 2002 02:25:43 -0000	1.19
  +++ PropertyUtils.java	12 Jan 2002 20:44:05 -0000	1.20
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/PropertyUtils.java,v 1.19 2002/01/11 02:25:43 craigmcc Exp $
  - * $Revision: 1.19 $
  - * $Date: 2002/01/11 02:25:43 $
  + * $Header: /home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/PropertyUtils.java,v 1.20 2002/01/12 20:44:05 craigmcc Exp $
  + * $Revision: 1.20 $
  + * $Date: 2002/01/12 20:44:05 $
    *
    * ====================================================================
    *
  @@ -133,7 +133,7 @@
    * @author Gregor Ra�man
    * @author Jan Sorensen
    * @author Scott Sanders
  - * @version $Revision: 1.19 $ $Date: 2002/01/11 02:25:43 $
  + * @version $Revision: 1.20 $ $Date: 2002/01/12 20:44:05 $
    */
   
   public class PropertyUtils {
  @@ -581,6 +581,24 @@
   
   
       /**
  +     * Return the mapped property descriptors for this bean class.
  +     *
  +     * @param beanClass Bean class to be introspected
  +     */
  +    // FIXME - does not work with DynaBeans
  +    public static FastHashMap getMappedPropertyDescriptors(Class beanClass) {
  +
  +        if (beanClass == null) {
  +            return null;
  +        }
  +
  +        // Look up any cached descriptors for this bean class
  +        return (FastHashMap) mappedDescriptorsCache.get(beanClass);
  +
  +    }
  +
  +
  +    /**
        * Return the mapped property descriptors for this bean.
        *
        * @param bean Bean to be introspected
  @@ -591,10 +609,7 @@
           if (bean == null) {
               return null;
           }
  -
  -        // Look up any cached descriptors for this bean class
  -        Class beanClass = bean.getClass();
  -        return (FastHashMap) mappedDescriptorsCache.get(beanClass);
  +        return (getMappedPropertyDescriptors(bean.getClass()));
   
       }
   
  @@ -806,13 +821,7 @@
               }
           }
           if (result != null) {
  -            if (mappedDescriptors == null) {
  -                mappedDescriptors = new FastHashMap();
  -                mappedDescriptors.setFast(true);
  -                mappedDescriptorsCache.put
  -                        (bean.getClass(), mappedDescriptors);
  -            }
  -            mappedDescriptors.put(name, result);
  +            mappedDescriptorsCache.put(name, result);
           }
           return result;
   
  @@ -820,22 +829,22 @@
   
   
       /**
  -     * Retrieve the property descriptors for the specified bean, introspecting
  +     * Retrieve the property descriptors for the specified class, introspecting
        * and caching them the first time a particular bean class is encountered.
        *
  -     * @param bean Bean for which property descriptors are requested
  +     * @param beanClass Bean class for which property descriptors are requested
        *
  -     * @exception IllegalArgumentException if <code>bean</code> is null
  +     * @exception IllegalArgumentException if <code>beanClass</code> is null
        */
       // FIXME - does not work with DynaBeans
  -    public static PropertyDescriptor[] getPropertyDescriptors(Object bean) {
  +    public static PropertyDescriptor[]
  +        getPropertyDescriptors(Class beanClass) {
   
  -        if (bean == null) {
  -            throw new IllegalArgumentException("No bean specified");
  +        if (beanClass == null) {
  +            throw new IllegalArgumentException("No bean class specified");
           }
   
           // Look up any cached descriptors for this bean class
  -        Class beanClass = bean.getClass();
           PropertyDescriptor descriptors[] = null;
           descriptors =
                   (PropertyDescriptor[]) descriptorsCache.get(beanClass);
  @@ -846,7 +855,7 @@
           // Introspect the bean and cache the generated descriptors
           BeanInfo beanInfo = null;
           try {
  -            beanInfo = Introspector.getBeanInfo(bean.getClass());
  +            beanInfo = Introspector.getBeanInfo(beanClass);
           } catch (IntrospectionException e) {
               return (new PropertyDescriptor[0]);
           }
  @@ -856,6 +865,25 @@
           }
           descriptorsCache.put(beanClass, descriptors);
           return (descriptors);
  +
  +    }
  +
  +
  +    /**
  +     * Retrieve the property descriptors for the specified bean, introspecting
  +     * 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
  +     */
  +    // FIXME - does not work with DynaBeans
  +    public static PropertyDescriptor[] getPropertyDescriptors(Object bean) {
  +
  +        if (bean == null) {
  +            throw new IllegalArgumentException("No bean specified");
  +        }
  +        return (getPropertyDescriptors(bean.getClass()));
   
       }
   
  
  
  
  1.1                  jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/WrapDynaBean.java
  
  Index: WrapDynaBean.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/WrapDynaBean.java,v 1.1 2002/01/12 20:44:05 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2002/01/12 20:44:05 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  
  package org.apache.commons.beanutils;
  
  
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  
  /**
   * <p>Implementation of <code>DynaBean</code> that wraps a standard JavaBean
   * instance, so that DynaBean APIs can be used to access its properties.</p>
   *
   * <p><strong>IMPLEMENTATION NOTE</strong> - This implementation does not
   * support the <code>contains()</code> and <code>remove()</code> methods.</p>
   *
   * @author Craig McClanahan
   * @version $Revision: 1.1 $ $Date: 2002/01/12 20:44:05 $
   */
  
  public class WrapDynaBean implements DynaBean {
  
  
       // ---------------------------------------------------------- Constructors
  
  
      /**
       * Construct a new <code>DynaBean</code> associated with the specified
       * JavaBean instance.
       *
       * @param instance JavaBean instance to be wrapped
       */
      public WrapDynaBean(Object instance) {
  
          super();
          this.instance = instance;
          this.dynaClass = WrapDynaClass.createDynaClass(instance.getClass());
  
      }
  
  
       // ---------------------------------------------------- Instance Variables
  
  
      /**
       * The <code>DynaClass</code> "base class" that this DynaBean
       * is associated with.
       */
      protected WrapDynaClass dynaClass = null;
  
  
      /**
       * The JavaBean instance wrapped by this WrapDynaBean.
       */
      protected Object instance = null;
  
  
       // ------------------------------------------------------ DynaBean Methods
  
  
      /**
       * Does the specified mapped property contain a value for the specified
       * key value?
       *
       * @param name Name of the property to check
       * @param key Name of the key to check
       *
       * @exception IllegalArgumentException if there is no property
       *  of the specified name
       */
      public boolean contains(String name, String key) {
  
          throw new UnsupportedOperationException
              ("WrapDynaBean does not support contains()");
  
      }
  
  
      /**
       * Return the value of a simple property with the specified name.
       *
       * @param name Name of the property whose value is to be retrieved
       *
       * @exception IllegalArgumentException if there is no property
       *  of the specified name
       */
      public Object get(String name) {
  
          DynaProperty descriptor = getDynaProperty(name);
          Object value = null;
          try {
              value = PropertyUtils.getSimpleProperty(instance, name);
          } catch (Throwable t) {
              throw new IllegalArgumentException
                  ("Property '" + name + "' has no read method");
          }
          return (value);
  
      }
   
  
      /**
       * Return the value of an indexed property with the specified name.
       *
       * @param name Name of the property whose value is to be retrieved
       * @param index Index of the value to be retrieved
       *
       * @exception IllegalArgumentException if there is no property
       *  of the specified name
       * @exception IllegalArgumentException if the specified property
       *  exists, but is not indexed
       * @exception IndexOutOfBoundsException if the specified index
       *  is outside the range of the underlying property
       * @exception NullPointerException if no array or List has been
       *  initialized for this property
       */
      public Object get(String name, int index) {
  
          DynaProperty descriptor = getDynaProperty(name);
          Object value = null;
          try {
              value = PropertyUtils.getIndexedProperty(instance, name, index);
          } catch (IndexOutOfBoundsException e) {
              throw e;
          } catch (Throwable t) {
              throw new IllegalArgumentException
                  ("Property '" + name + "' has no indexed read method");
          }
          return (value);
  
      }
  
  
      /**
       * Return the value of a mapped property with the specified name,
       * or <code>null</code> if there is no value for the specified key.
       *
       * @param name Name of the property whose value is to be retrieved
       * @param key Key of the value to be retrieved
       *
       * @exception IllegalArgumentException if there is no property
       *  of the specified name
       * @exception IllegalArgumentException if the specified property
       *  exists, but is not mapped
       */
      public Object get(String name, String key) {
  
          Object value = null;
          try {
              value = PropertyUtils.getMappedProperty(instance, name, key);
          } catch (Throwable t) {
              throw new IllegalArgumentException
                  ("Property '" + name + "' has no mapped read method");
          }
          return (value);
  
      }
  
  
      /**
       * Return the <code>DynaClass</code> instance that describes the set of
       * properties available for this DynaBean.
       */
      public DynaClass getDynaClass() {
  
          return (this.dynaClass);
  
      }
  
  
      /**
       * Remove any existing value for the specified key on the
       * specified mapped property.
       *
       * @param name Name of the property for which a value is to
       *  be removed
       * @param key Key of the value to be removed
       *
       * @exception IllegalArgumentException if there is no property
       *  of the specified name
       */
      public void remove(String name, String key) {
  
  
          throw new UnsupportedOperationException
              ("WrapDynaBean does not support contains()");
  
      }
  
  
      /**
       * Set the value of a simple property with the specified name.
       *
       * @param name Name of the property whose value is to be set
       * @param value Value to which this property is to be set
       *
       * @exception ConversionException if the specified value cannot be
       *  converted to the type required for this property
       * @exception IllegalArgumentException if there is no property
       *  of the specified name
       * @exception NullPointerException if an attempt is made to set a
       *  primitive property to null
       */
      public void set(String name, Object value) {
  
          DynaProperty descriptor = getDynaProperty(name);
          try {
              PropertyUtils.setSimpleProperty(instance, name, value);
          } catch (Throwable t) {
              throw new IllegalArgumentException
                  ("Property '" + name + "' has no write method");
          }
  
      }
  
  
      /**
       * Set the value of an indexed property with the specified name.
       *
       * @param name Name of the property whose value is to be set
       * @param index Index of the property to be set
       * @param value Value to which this property is to be set
       *
       * @exception ConversionException if the specified value cannot be
       *  converted to the type required for this property
       * @exception IllegalArgumentException if there is no property
       *  of the specified name
       * @exception IllegalArgumentException if the specified property
       *  exists, but is not indexed
       * @exception IndexOutOfBoundsException if the specified index
       *  is outside the range of the underlying property
       */
      public void set(String name, int index, Object value) {
  
          DynaProperty descriptor = getDynaProperty(name);
          try {
              PropertyUtils.setIndexedProperty(instance, name, index, value);
          } catch (IndexOutOfBoundsException e) {
              throw e;
          } catch (Throwable t) {
              throw new IllegalArgumentException
                  ("Property '" + name + "' has no indexed write method");
          }
  
      }
  
  
      /**
       * Set the value of a mapped property with the specified name.
       *
       * @param name Name of the property whose value is to be set
       * @param key Key of the property to be set
       * @param value Value to which this property is to be set
       *
       * @exception ConversionException if the specified value cannot be
       *  converted to the type required for this property
       * @exception IllegalArgumentException if there is no property
       *  of the specified name
       * @exception IllegalArgumentException if the specified property
       *  exists, but is not mapped
       */
      public void set(String name, String key, Object value) {
  
          try {
              PropertyUtils.setMappedProperty(instance, name, key, value);
          } catch (Throwable t) {
              throw new IllegalArgumentException
                  ("Property '" + name + "' has no mapped write method");
          }
  
      }
  
  
      // ------------------------------------------------------ Protected Methods
  
  
      /**
       * Return the property descriptor for the specified property name.
       *
       * @param name Name of the property for which to retrieve the descriptor
       *
       * @exception IllegalArgumentException if this is not a valid property
       *  name for our DynaClass
       */
      protected DynaProperty getDynaProperty(String name) {
  
          DynaProperty descriptor = getDynaClass().getDynaProperty(name);
          if (descriptor == null) {
              throw new IllegalArgumentException
                  ("Invalid property name '" + name + "'");
          }
          return (descriptor);
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/WrapDynaClass.java
  
  Index: WrapDynaClass.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/WrapDynaClass.java,v 1.1 2002/01/12 20:44:05 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2002/01/12 20:44:05 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  
  package org.apache.commons.beanutils;
  
  
  import java.beans.PropertyDescriptor;
  import java.lang.reflect.Constructor;
  import java.lang.reflect.InvocationTargetException;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  
  
  /**
   * <p>Implementation of <code>DynaClass</code> for DynaBeans that wrap
   * standard JavaBean instances.</p>
   *
   * @author Craig McClanahan
   * @version $Revision: 1.1 $ $Date: 2002/01/12 20:44:05 $
   */
  
  public class WrapDynaClass implements DynaClass {
  
  
      // ----------------------------------------------------------- Constructors
  
  
      /**
       * Construct a new WrapDynaClass for the specified JavaBean class.  This
       * constructor is private; WrapDynaClass instances will be created as
       * needed via calls to the <code>createDynaClass(Class)</code> method.
       *
       * @param beanClass JavaBean class to be introspected around
       */
      private WrapDynaClass(Class beanClass) {
  
          this.beanClass = beanClass;
          introspect();
  
      }
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * The JavaBean <code>Class</code> which is represented by this
       * <code>WrapDynaClass</code>.
       */
      protected Class beanClass = null;
  
  
      /**
       * The set of PropertyDescriptors for this bean class.
       */
      protected PropertyDescriptor descriptors[] = null;
  
  
      /**
       * The set of PropertyDescriptors for this bean class, keyed by the
       * property name.  Individual descriptor instances will be the same
       * instances as those in the <code>descriptors</code> list.
       */
      protected HashMap descriptorsMap = new HashMap();
  
  
      /**
       * The set of dynamic properties that are part of this DynaClass.
       */
      protected DynaProperty properties[] = null;
  
  
      /**
       * The set of dynamic properties that are part of this DynaClass,
       * keyed by the property name.  Individual descriptor instances will
       * be the same instances as those in the <code>properties</code> list.
       */
      protected HashMap propertiesMap = new HashMap();
  
  
      // ------------------------------------------------------- Static Variables
  
  
      /**
       * The set of <code>WrapDynaBean</code> instances that have ever been
       * created, keyed by the underlying bean Class.
       */
      protected static HashMap dynaClasses = new HashMap();
  
  
      // ------------------------------------------------------ DynaClass Methods
  
  
      /**
       * Return the name of this DynaClass (analogous to the
       * <code>getName()</code> method of <code>java.lang.Class</code), which
       * allows the same <code>DynaClass</code> implementation class to support
       * different dynamic classes, with different sets of properties.
       */
      public String getName() {
  
          return (this.beanClass.getName());
  
      }
  
  
      /**
       * Return a property descriptor for the specified property, if it exists;
       * otherwise, return <code>null</code>.
       *
       * @param name Name of the dynamic property for which a descriptor
       *  is requested
       *
       * @exception IllegalArgumentException if no property name is specified
       */
      public DynaProperty getDynaProperty(String name) {
  
          if (name == null) {
              throw new IllegalArgumentException
                  ("No property name specified");
          }
          return ((DynaProperty) propertiesMap.get(name));
  
      }
  
  
      /**
       * <p>Return an array of <code>ProperyDescriptors</code> for the properties
       * currently defined in this DynaClass.  If no properties are defined, a
       * zero-length array will be returned.</p>
       *
       * <p><strong>FIXME</strong> - Should we really be implementing
       * <code>getBeanInfo()</code> instead, which returns property descriptors
       * and a bunch of other stuff?</p>
       */
      public DynaProperty[] getDynaProperties() {
  
          return (properties);
  
      }
  
  
      /**
       * <p>Instantiate and return a new DynaBean instance, associated
       * with this DynaClass.  <strong>NOTE</strong> - This operation is not
       * supported, and throws an exception.  You should create new
       * <code>WrapDynaBean</code> instances by calling its constructor:</p>
       * <pre>
       *   Object javaBean = ...;
       *   DynaBean wrapper = new WrapDynaBean(javaBean);
       * </pre>
       *
       * @exception IllegalAccessException if the Class or the appropriate
       *  constructor is not accessible
       * @exception InstantiationException if this Class represents an abstract
       *  class, an array class, a primitive type, or void; or if instantiation
       *  fails for some other reason
       */
      public DynaBean newInstance()
          throws IllegalAccessException, InstantiationException {
  
          throw new UnsupportedOperationException("newInstance() not supported");
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Return the PropertyDescriptor for the specified property name, if any;
       * otherwise return <code>null</code>.
       *
       * @param name Name of the property to be retrieved
       */
      public PropertyDescriptor getPropertyDescriptor(String name) {
  
          return ((PropertyDescriptor) descriptorsMap.get(name));
  
      }
  
  
      // --------------------------------------------------------- Static Methods
  
  
      /**
       * Clear our cache of WrapDynaClass instances.
       */
      public static void clear() {
  
          synchronized (dynaClasses) {
              dynaClasses.clear();
          }
  
      }
  
  
      /**
       * Create (if necessary) and return a new <code>WrapDynaClass</code>
       * instance for the specified bean class.
       *
       * @param beanClass Bean class for which a WrapDynaClass is requested
       */
      public static WrapDynaClass createDynaClass(Class beanClass) {
  
          synchronized (dynaClasses) {
              WrapDynaClass dynaClass =
                  (WrapDynaClass) dynaClasses.get(beanClass);
              if (dynaClass == null) {
                  dynaClass = new WrapDynaClass(beanClass);
                  dynaClasses.put(beanClass, dynaClass);
              }
              return (dynaClass);
          }
  
      }
  
  
      // ------------------------------------------------------ Protected Methods
  
  
      /**
       * Introspect our bean class to identify the supported properties.
       */
      protected void introspect() {
  
          // Look up the property descriptors for this bean class
          PropertyDescriptor regulars[] =
              PropertyUtils.getPropertyDescriptors(beanClass);
          if (regulars == null) {
              regulars = new PropertyDescriptor[0];
          }
          HashMap mappeds =
              PropertyUtils.getMappedPropertyDescriptors(beanClass);
          if (mappeds == null) {
              mappeds = new HashMap();
          }
  
          // Construct corresponding DynaProperty information
          properties = new DynaProperty[regulars.length + mappeds.size()];
          for (int i = 0; i < regulars.length; i++) {
              descriptorsMap.put(regulars[i].getName(),
                                 regulars[i]);
              properties[i] =
                  new DynaProperty(regulars[i].getName(),
                                   regulars[i].getPropertyType());
              propertiesMap.put(properties[i].getName(),
                                properties[i]);
          }
          int j = regulars.length;
          Iterator names = mappeds.keySet().iterator();
          while (names.hasNext()) {
              String name = (String) names.next();
              PropertyDescriptor descriptor =
                  (PropertyDescriptor) mappeds.get(name);
              properties[j] =
                  new DynaProperty(descriptor.getName(),
                                   Map.class);
              propertiesMap.put(properties[j].getName(),
                                properties[j]);
              System.out.println("Adding mapped property " + properties[j]);
              j++;
          }
  
      }
  
  
  }
  
  
  
  1.3       +4 -48     jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/BasicDynaBeanTestCase.java
  
  Index: BasicDynaBeanTestCase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/BasicDynaBeanTestCase.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- BasicDynaBeanTestCase.java	11 Jan 2002 02:25:43 -0000	1.2
  +++ BasicDynaBeanTestCase.java	12 Jan 2002 20:44:05 -0000	1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/BasicDynaBeanTestCase.java,v 1.2 2002/01/11 02:25:43 craigmcc Exp $
  - * $Revision: 1.2 $
  - * $Date: 2002/01/11 02:25:43 $
  + * $Header: /home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/BasicDynaBeanTestCase.java,v 1.3 2002/01/12 20:44:05 craigmcc Exp $
  + * $Revision: 1.3 $
  + * $Date: 2002/01/12 20:44:05 $
    *
    * ====================================================================
    *
  @@ -85,7 +85,7 @@
    * because the two classes provide similar levels of functionality.</p>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.2 $ $Date: 2002/01/11 02:25:43 $
  + * @version $Revision: 1.3 $ $Date: 2002/01/12 20:44:05 $
    */
   
   public class BasicDynaBeanTestCase extends TestCase {
  @@ -560,25 +560,6 @@
   
   
       /**
  -     * Test getSimpleProperty on an indexed property.
  -     */
  -    public void testGetSimpleIndexed() {
  -
  -        int intIndexed[] = new int[0];
  -        Object value = null;
  -        try {
  -            value = bean.get("intIndexed");
  -            assertTrue
  -                ("Got correct type",
  -                 intIndexed.getClass().isAssignableFrom(value.getClass()));
  -        } catch (Throwable t) {
  -            fail("Exception: " + t);
  -        }
  -
  -    }
  -
  -
  -    /**
        * Test getSimpleProperty on a int property.
        */
       public void testGetSimpleInt() {
  @@ -882,31 +863,6 @@
           }
   
       }
  -
  -
  -    /**
  -     * Negative test setSimpleProperty on an indexed property.
  -     */
  -    /*
  -    public void testSetSimpleIndexed() {
  -
  -        try {
  -            BasicDynaBean.setSimpleProperty(bean,
  -                                            "stringIndexed[0]",
  -                                            "New String Value");
  -            fail("Should have thrown IllegalArgumentException");
  -        } catch (IllegalAccessException e) {
  -            fail("IllegalAccessException");
  -        } catch (IllegalArgumentException e) {
  -            ; // Correct result for this test
  -        } catch (InvocationTargetException e) {
  -            fail("InvocationTargetException");
  -        } catch (NoSuchMethodException e) {
  -            fail("NoSuchMethodException");
  -        }
  -
  -    }
  -    */
   
   
       /**
  
  
  
  1.6       +10 -4     jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/TestBean.java
  
  Index: TestBean.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/TestBean.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- TestBean.java	4 Jan 2002 21:25:17 -0000	1.5
  +++ TestBean.java	12 Jan 2002 20:44:05 -0000	1.6
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/TestBean.java,v 1.5 2002/01/04 21:25:17 sanders Exp $
  - * $Revision: 1.5 $
  - * $Date: 2002/01/04 21:25:17 $
  + * $Header: /home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/TestBean.java,v 1.6 2002/01/12 20:44:05 craigmcc Exp $
  + * $Revision: 1.6 $
  + * $Date: 2002/01/12 20:44:05 $
    *
    * ====================================================================
    *
  @@ -72,7 +72,7 @@
    * General purpose test bean for JUnit tests for the "beanutils" component.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.5 $ $Date: 2002/01/04 21:25:17 $
  + * @version $Revision: 1.6 $ $Date: 2002/01/12 20:44:05 $
    */
   
   public class TestBean {
  @@ -226,6 +226,12 @@
       }
   
       public void setMappedProperty(String key, String value) {
  +        // Create the map the very first time
  +        if (mappedProperty == null) {
  +            mappedProperty = new HashMap();
  +            mappedProperty.put("First Key", "First Value");
  +            mappedProperty.put("Second Key", "Second Value");
  +        }
           mappedProperty.put(key, value);
       }
   
  
  
  
  1.1                  jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/WrapDynaBeanTestCase.java
  
  Index: WrapDynaBeanTestCase.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/WrapDynaBeanTestCase.java,v 1.1 2002/01/12 20:44:05 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2002/01/12 20:44:05 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  
  package org.apache.commons.beanutils;
  
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  import java.beans.PropertyDescriptor;
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  import org.apache.commons.beanutils.priv.PrivateBeanFactory;
  import org.apache.commons.beanutils.priv.PrivateDirect;
  import org.apache.commons.beanutils.priv.PrivateIndirect;
  
  
  /**
   * <p>Test Case for the <code>WrapDynaBean</code> implementation class.
   * These tests were based on the ones in <code>PropertyUtilsTestCase</code>
   * because the two classes provide similar levels of functionality.</p>
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2002/01/12 20:44:05 $
   */
  
  public class WrapDynaBeanTestCase extends BasicDynaBeanTestCase {
  
  
      // ---------------------------------------------------- Instance Variables
  
  
      // ---------------------------------------------------------- Constructors
  
  
      /**
       * Construct a new instance of this test case.
       *
       * @param name Name of the test case
       */
      public WrapDynaBeanTestCase(String name) {
  
          super(name);
  
      }
  
  
      // -------------------------------------------------- Overall Test Methods
  
  
      /**
       * Set up instance variables required by this test case.
       */
      public void setUp() throws Exception {
  
          bean = new WrapDynaBean(new TestBean());
  
      }
  
  
      /**
       * Return the tests included in this test suite.
       */
      public static Test suite() {
  
          return (new TestSuite(WrapDynaBeanTestCase.class));
  
      }
  
  
      /**
       * Tear down instance variables required by this test case.
       */
      public void tearDown() {
  
          bean = null;
  
      }
  
  
  
      // ------------------------------------------------ Individual Test Methods
  
  
      /**
       * The <code>contains()</code> method is not supported by the
       * <code>WrapDynaBean</code> implementation class.
       */
      public void testMappedContains() {
  
          try {
              assertTrue("Can see first key",
                         bean.contains("mappedProperty", "First Key"));
              fail("Should have thrown UnsupportedOperationException");
          } catch (UnsupportedOperationException t) {
              ; // Expected result
          } catch (Throwable t) {
              fail("Exception: " + t);
          }
  
  
          try {
              assertTrue("Can not see unknown key",
                         !bean.contains("mappedProperty", "Unknown Key"));
              fail("Should have thrown UnsupportedOperationException");
          } catch (UnsupportedOperationException t) {
              ; // Expected result
          } catch (Throwable t) {
              fail("Exception: " + t);
          }
  
      }
  
  
  
      /**
       * The <code>remove()</code> method is not supported by the
       * <code>WrapDynaBean</code> implementation class.
       */
      public void testMappedRemove() {
  
          try {
              assertTrue("Can see first key",
                         bean.contains("mappedProperty", "First Key"));
              bean.remove("mappedProperty", "First Key");
              fail("Should have thrown UnsupportedOperationException");
              //            assertTrue("Can not see first key",
              //         !bean.contains("mappedProperty", "First Key"));
          } catch (UnsupportedOperationException t) {
              ; // Expected result
          } catch (Throwable t) {
              fail("Exception: " + t);
          }
  
          try {
              assertTrue("Can not see unknown key",
                         !bean.contains("mappedProperty", "Unknown Key"));
              bean.remove("mappedProperty", "Unknown Key");
              fail("Should have thrown UnsupportedOperationException");
              //            assertTrue("Can not see unknown key",
              //         !bean.contains("mappedProperty", "Unknown Key"));
          } catch (UnsupportedOperationException t) {
              ; // Expected result
          } catch (Throwable t) {
              fail("Exception: " + t);
          }
  
      }
  
  
  }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>