You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ni...@apache.org on 2005/10/07 18:47:44 UTC

svn commit: r307162 - in /jakarta/commons/proper/beanutils/trunk: build.xml src/java/org/apache/commons/beanutils/LazyDynaList.java src/test/org/apache/commons/beanutils/LazyDynaListTestCase.java

Author: niallp
Date: Fri Oct  7 09:47:24 2005
New Revision: 307162

URL: http://svn.apache.org/viewcvs?rev=307162&view=rev
Log:
add LazyDynaList - based on suggestion from Vic Cekvenich

Added:
    jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/LazyDynaList.java   (with props)
    jakarta/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/LazyDynaListTestCase.java   (with props)
Modified:
    jakarta/commons/proper/beanutils/trunk/build.xml

Modified: jakarta/commons/proper/beanutils/trunk/build.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/beanutils/trunk/build.xml?rev=307162&r1=307161&r2=307162&view=diff
==============================================================================
--- jakarta/commons/proper/beanutils/trunk/build.xml (original)
+++ jakarta/commons/proper/beanutils/trunk/build.xml Fri Oct  7 09:47:24 2005
@@ -285,6 +285,7 @@
                                 test.lazy.dynaclass,
                                 test.lazy.dynabean,
                                 test.lazy.dynamap,
+                                test.lazy.dynalist,
                                 test.indexed.properties,
                                 test.mapped.properties
                                "
@@ -499,6 +500,21 @@
       <sysproperty key="org.apache.commons.logging.simplelog.defaultlog"
                  value="${test.level}"/>
       <arg value="org.apache.commons.beanutils.LazyDynaMapTestCase"/>
+      <classpath refid="test.classpath"/>
+    </java>
+  </target>
+
+  <target name="test.lazy.dynalist" depends="compile.tests">
+    <echo message="Running LazyDynaList tests ..."/>
+    <java classname="${test.runner}" fork="yes"
+        failonerror="${test.failonerror}">
+      <sysproperty key="org.apache.commons.logging.LogFactory"
+                 value="${test.factory}"/>
+      <sysproperty key="org.apache.commons.logging.Log"
+                 value="${test.log}"/>
+      <sysproperty key="org.apache.commons.logging.simplelog.defaultlog"
+                 value="${test.level}"/>
+      <arg value="org.apache.commons.beanutils.LazyDynaListTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
   </target>

Added: jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/LazyDynaList.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/LazyDynaList.java?rev=307162&view=auto
==============================================================================
--- jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/LazyDynaList.java (added)
+++ jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/LazyDynaList.java Fri Oct  7 09:47:24 2005
@@ -0,0 +1,684 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.beanutils;
+
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Collection;
+import java.util.Iterator;
+import java.lang.reflect.Array;
+
+/**
+ * <h2><i>Lazy</i> DynaBean List.</h2>
+ * 
+ * <p>There are two main purposes for this class:</p>
+ *    <ul>
+ *        <li>To provide <i>Lazy List</i> behaviour - automatically
+ *            <i>growing</i> and <i>populating</i> the <code>List</code>
+ *            with either <code>DynaBean</code>, <code>java.util.Map</code>
+ *            or POJO Beans.</li>
+ *        <li>To provide a straight forward way of putting a Collection
+ *            or Array into the lazy list <i>and</i> a straight forward 
+ *            way to get it out again at the end.</li>
+ *    </ul>
+ * 
+ * <p>All elements added to the List are stored as <code>DynaBean</code>'s:</p>
+ * <ul>
+ *    <li><code>java.util.Map</code> elements are "wrapped" in a <code>LazyDynaMap</code>.</i> 
+ *    <li>POJO Bean elements are "wrapped" in a <code>WrapDynaBean.</code></i> 
+ *    <li><code>DynaBean</code>'s are stored un-changed.</i>
+ * </ul>
+ *  
+ * <h4><code>toArray()</code></h4>
+ * <p>The <code>toArray()</code> method returns an array of the
+ *    elements of the appropriate type. If the <code>LazyDynaList</code>
+ *    is populated with <code>java.util.Map</code> objects a 
+ *    <code>Map[]</code> array is returned.
+ *    If the list is populated with POJO Beans an appropriate
+ *    array of the POJO Beans is returned. Otherwise a <code>DynaBean[]</code>
+ *    array is returned.
+ * </p>
+ *  
+ * <h4><code>toDynaBeanArray()</code></h4>
+ * <p>The <code>toDynaBeanArray()</code> method returns a 
+ *    <code>DynaBean[]</code> array of the elements in the List.
+ * </p>
+ *  
+ * <p><strong>N.B.</strong>All the elements in the List must be the
+ *    same type. If the <code>DynaClass</code> or <code>Class</code>
+ *    of the <code>LazyDynaList</code>'s elements is
+ *    not specified, then it will be automatically set to the type
+ *    of the first element populated.
+ * </p>
+ * 
+ * <h3>Example 1</h3>
+ * <p>If you have an array of <code>java.util.Map[]</code> - you can put that into
+ *    a <code>LazyDynaList</code>.</p>
+ * 
+ * <pre><code>
+ *    TreeMap[] myArray = .... // your Map[]
+ *    List lazyList = new LazyDynaList(myArray);
+ * </code></pre>
+ * 
+ * <p>New elements of the appropriate Map type are
+ *    automatically populated:</p>
+ *  
+ * <pre><code>
+ *    // get(index) automatically grows the list
+ *    DynaBean newElement = (DynaBean)lazyList.get(lazyList.size());
+ *    newElement.put("someProperty", "someValue");
+ * </code></pre>
+ * 
+ * <p>Once you've finished you can get back an Array of the
+ *    elements of the appropriate type:</p>
+ *  
+ * <pre><code>
+ *    // Retrieve the array from the list
+ *    TreeMap[] myArray = (TreeMap[])lazyList.toArray());
+ * </code></pre>
+ * 
+ * 
+ * <h3>Example 2</h3>
+ * <p>Alternatively you can create an <i>empty</i> List and
+ *    specify the Class for List's elements. The LazyDynaList
+ *    uses the Class to automatically populate elements:</p>
+ * 
+ * <pre><code>
+ *    // e.g. For Maps
+ *    List lazyList = new LazyDynaList(TreeMap.class);
+ * 
+ *    // e.g. For POJO Beans
+ *    List lazyList = new LazyDynaList(MyPojo.class);
+ * 
+ *    // e.g. For DynaBeans
+ *    List lazyList = new LazyDynaList(MyDynaBean.class);
+ * </code></pre>
+ * 
+ * <h3>Example 3</h3>
+ * <p>Alternatively you can create an <i>empty</i> List and specify the 
+ *    DynaClass for List's elements. The LazyDynaList uses
+ *    the DynaClass to automatically populate elements:</p>
+ * 
+ * <pre><code>
+ *    // e.g. For Maps
+ *    DynaClass dynaClass = new LazyDynaMap(new HashMap());
+ *    List lazyList = new LazyDynaList(dynaClass);
+ * 
+ *    // e.g. For POJO Beans
+ *    DynaClass dynaClass = (new WrapDynaBean(myPojo)).getDynaClass();
+ *    List lazyList = new LazyDynaList(dynaClass);
+ * 
+ *    // e.g. For DynaBeans
+ *    DynaClass dynaClass = new BasicDynaClass(properties);
+ *    List lazyList = new LazyDynaList(dynaClass);
+ * </code></pre>
+ * 
+ * <p><strong>N.B.</strong> You may wonder why control the type
+ *    using a <code>DynaClass</code> rather than the <code>Class</code>
+ *    as in the previous example - the reason is that some <code>DynaBean</code>
+ *    implementations don't have a <i>default</i> empty constructor and
+ *    therefore need to be instantiated using the <code>DynaClass.newInstance()</code>
+ *    method.</p>
+ * 
+ * <h3>Example 4</h3>
+ * <p>A slight variation - set the element type using either
+ *    the <code>setElementType(Class)</code> method or the
+ *    <code>setElementDynaClass(DynaClass)</code> method - then populate
+ *    with the normal <code>java.util.List</code> methods(i.e.
+ *    <code>add()</code>, <code>addAll()</code> or <code>set()</code>).</p>
+ * 
+ * <pre><code>
+ *    // Create a new LazyDynaList (100 element capacity)
+ *    LazyDynaList lazyList = new LazyDynaList(100);
+ * 
+ *    // Either Set the element type...
+ *    lazyList.setElementType(TreeMap.class);
+ * 
+ *    // ...or the element DynaClass...
+ *    lazyList.setElementDynaClass(new MyCustomDynaClass());
+ * 
+ *    // Populate from a collection
+ *    lazyList.addAll(myCollection);
+ *
+ * </code></pre>
+ * 
+ * @author Niall Pemberton
+ * @version $Revision$ $Date$
+ */
+public class LazyDynaList extends ArrayList {
+    
+    /**
+     * The DynaClass of the List's elements.
+     */
+    private DynaClass elementDynaClass;
+    
+    /**
+     * The WrapDynaClass if the List's contains
+     * POJO Bean elements.
+     *
+     * N.B. WrapDynaClass isn't serlializable, which
+     *      is why its stored separately in a 
+     *      transient instance variable.
+     */
+    private transient WrapDynaClass wrapDynaClass;
+    
+    /**
+     * The type of the List's elements.
+     */
+    private Class elementType;
+    
+    /**
+     * The DynaBean type of the List's elements.
+     */
+    private Class elementDynaBeanType;
+
+
+    // ------------------- Constructors ------------------------------
+
+    /**
+     * Default Constructor.
+     */
+    public LazyDynaList() {
+        super();
+    }
+
+    /**
+     * Construct a LazyDynaList with the 
+     * specified capacity.
+     *
+     * @param capacity The initial capacity of the list.
+     */
+    public LazyDynaList(int capacity) {
+        super(capacity);
+        
+    }
+
+    /**
+     * Construct a  LazyDynaList with a
+     * specified DynaClass for its elements.
+     * 
+     * @param elementDynaClass The DynaClass of the List's elements.
+     */
+    public LazyDynaList(DynaClass elementDynaClass) {
+        super();
+        setElementDynaClass(elementDynaClass);
+    }
+
+    /**
+     * Construct a  LazyDynaList with a
+     * specified type for its elements.
+     * 
+     * @param elementType The Type of the List's elements.
+     */
+    public LazyDynaList(Class elementType) {
+        super();
+        setElementType(elementType);
+    }
+    
+    /**
+     * Construct a  LazyDynaList populated with the
+     * elements of a Collection.
+     *
+     * @param collection The Collection to poulate the List from.
+     */
+    public LazyDynaList(Collection collection) {
+        super(collection.size());
+        addAll(collection);
+    }
+    
+    /**
+     * Construct a  LazyDynaList populated with the
+     * elements of an Array.
+     *
+     * @param array The Array to poulate the List from.
+     */
+    public LazyDynaList(Object[] array) {
+        super(array.length);
+        for (int i = 0; i < array.length; i++) {
+            add(array[i]);
+        }
+    }
+
+
+    // ------------------- java.util.List Methods --------------------
+
+    /**
+     * <p>Insert an element at the specified index position.</p>
+     * 
+     * <p>If the index position is greater than the current 
+     *    size of the List, then the List is automatically
+     *    <i>grown</i> to the appropriate size.</p>
+     *  
+     * @param index The index position to insert the new element.
+     * @param element The new element to add.
+     */
+    public void add(int index, Object element) {
+
+        DynaBean dynaBean = transform(element);
+
+        growList(index);
+        
+        super.add(index, dynaBean);
+
+    }
+
+    /**
+     * <p>Add an element to the List.</p>
+     *
+     * @param element The new element to add.
+     * @return true.
+     */
+    public boolean add(Object element) {
+
+        DynaBean dynaBean = transform(element);
+
+        return super.add(dynaBean);
+
+    }
+
+    /**
+     * <p>Add all the elements from a Collection to the list.
+     *
+     * @param collection The Collection of new elements.
+     * @return true if elements were added.
+     */
+    public boolean addAll(Collection collection) {
+
+        if (collection == null || collection.size() == 0) {
+            return false;
+        }
+        
+        ensureCapacity(size() + collection.size());
+
+        Iterator iterator = collection.iterator();
+        while (iterator.hasNext()) {
+            add(iterator.next());
+        }
+
+        return true;
+
+    }
+
+    /**
+     * <p>Insert all the elements from a Collection into the
+     *    list at a specified position.
+     *
+     * <p>If the index position is greater than the current 
+     *    size of the List, then the List is automatically
+     *    <i>grown</i> to the appropriate size.</p>
+     * 
+     * @param collection The Collection of new elements.
+     * @param index The index position to insert the new elements at.
+     * @return true if elements were added.
+     */
+    public boolean addAll(int index, Collection collection) {
+
+        if (collection == null || collection.size() == 0) {
+            return false;
+        }
+        
+        ensureCapacity((index > size() ? index : size()) + collection.size());
+        
+        // Call "tranform" with first element, before
+        // List is "grown" to ensure the correct DynaClass
+        // is set.
+        if (size() == 0) {
+            transform(collection.iterator().next());
+        }
+
+        growList(index);
+
+        Iterator iterator = collection.iterator();
+        while (iterator.hasNext()) {
+            add(index++, iterator.next());
+        }
+
+        return true;
+        
+    }
+
+    /**
+     * <p>Return the element at the specified position.</p>
+     *
+     * <p>If the position requested is greater than the current 
+     *    size of the List, then the List is automatically
+     *    <i>grown</i> (and populated) to the appropriate size.</p>
+     * 
+     * @param index The index position to insert the new elements at.
+     * @return The element at the specified position.
+     */
+    public Object get(int index) {
+
+        growList(index + 1);
+
+        return super.get(index);
+
+    }
+
+    /**
+     * <p>Set the element at the specified position.</p>
+     *
+     * <p>If the position requested is greater than the current 
+     *    size of the List, then the List is automatically
+     *    <i>grown</i> (and populated) to the appropriate size.</p>
+     * 
+     * @param index The index position to insert the new element at.
+     * @param element The new element.
+     * @return The new element.
+     */
+    public Object set(int index, Object element) {
+
+        DynaBean dynaBean = transform(element);
+
+        growList(index + 1);
+
+        return super.set(index, dynaBean);
+        
+    }
+
+    /**
+     * <p>Converts the List to an Array.</p>
+     *
+     * <p>The type of Array created depends on the contents
+     *    of the List:</p>
+     * <ul>
+     *    <li>If the List contains only LazyDynaMap type elements
+     *        then a java.util.Map[] array will be created.</li>   
+     *    <li>If the List contains only elements which are 
+     *        "wrapped" DynaBeans then an Object[] of the most
+     *        suitable type will be created.</li>
+     *    <li>...otherwise a DynaBean[] will be created.</li>
+     * 
+     * @return An Array of the elements in this List.
+     */
+    public Object[] toArray() {
+
+        if (size() == 0 && elementType == null) {
+            return new LazyDynaBean[0];
+        }
+
+        Object[] array = (Object[])Array.newInstance(elementType, size());
+        for (int i = 0; i < size(); i++) {
+            if (Map.class.isAssignableFrom(elementType)) {
+                array[i] = ((LazyDynaMap)get(i)).getMap(); 
+            } else if (DynaBean.class.isAssignableFrom(elementType)) {
+                array[i] = (DynaBean)get(i);
+            } else {
+                array[i] = ((WrapDynaBean)get(i)).getInstance(); 
+            }
+        }
+        return array;
+        
+    }
+
+    /**
+     * <p>Converts the List to an Array of the specified type.</p>
+     *
+     * @return An Array of the elements in this List.
+     */
+    public Object[] toArray(Object[] model) {
+        
+        // Allocate the Array
+        Class arrayType = model.getClass().getComponentType();
+        Object[] array = (Object[])Array.newInstance(arrayType, size());
+
+        if (size() == 0 && elementType == null) {
+            return new LazyDynaBean[0];
+        }
+
+        if ((DynaBean.class.isAssignableFrom(arrayType))) {
+            for (int i = 0; i < size(); i++) {
+                array[i] = get(i);
+            }
+            return array;
+        }
+
+        if ((arrayType.isAssignableFrom(elementType))) {
+            for (int i = 0; i < size(); i++) {
+                if (Map.class.isAssignableFrom(elementType)) {
+                    array[i] = ((LazyDynaMap)get(i)).getMap(); 
+                } else if (DynaBean.class.isAssignableFrom(elementType)) {
+                    array[i] = get(i);
+                } else {
+                    array[i] = ((WrapDynaBean)get(i)).getInstance(); 
+                }
+            }
+            return array;
+        }
+
+        throw new IllegalArgumentException("Invalid array type: " 
+                  + arrayType.getName() + " - not compatible with '"
+                  + elementType.getName());
+        
+    }
+
+
+    // ------------------- Public Methods ----------------------------
+
+    /**
+     * <p>Converts the List to an DynaBean Array.</p>
+     *
+     * @return A DynaBean[] of the elements in this List.
+     */
+    public DynaBean[] toDynaBeanArray() {
+
+        if (size() == 0 && elementDynaBeanType == null) {
+            return new LazyDynaBean[0];
+        }
+        
+        DynaBean[] array = (DynaBean[])Array.newInstance(elementDynaBeanType, size());
+        for (int i = 0; i < size(); i++) {
+            array[i] = (DynaBean)get(i);
+        }
+        return array;
+        
+    }
+
+    /**
+     * <p>Set the element Type and DynaClass.</p>
+     *
+     * @param elementType The type of the elements.
+     * @exception IllegalArgumentException if the List already
+     *            contains elements or the DynaClass is null.
+     */
+    public void setElementType(Class elementType) {
+
+        if (elementType == null) {
+            throw new IllegalArgumentException("Element Type is missing");
+        }
+
+        if (size() > 0) {
+            throw new IllegalStateException("Element Type cannot be reset");
+        }
+
+        this.elementType = elementType;
+
+        // Create a new object of the specified type
+        Object object = null;
+        try {
+            object = elementType.newInstance();
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Error creating type: " 
+                           + elementType.getName() + " - " + e);
+        }
+
+        // Create a DynaBean
+        DynaBean dynaBean = null;
+        if (Map.class.isAssignableFrom(elementType)) {
+            dynaBean = new LazyDynaMap((Map)object);
+            this.elementDynaClass = dynaBean.getDynaClass();
+        } else if (DynaBean.class.isAssignableFrom(elementType)) {
+            dynaBean = (DynaBean)object;
+            this.elementDynaClass = dynaBean.getDynaClass();
+        } else {
+            dynaBean = new WrapDynaBean(object);
+            this.wrapDynaClass = (WrapDynaClass)dynaBean.getDynaClass();
+        }
+
+        this.elementDynaBeanType = dynaBean.getClass();
+
+        // Re-calculate the type
+        if (WrapDynaBean.class.isAssignableFrom(elementDynaBeanType )) {
+            this.elementType = ((WrapDynaBean)dynaBean).getInstance().getClass();
+        } else if (LazyDynaMap.class.isAssignableFrom(elementDynaBeanType )) {
+            this.elementType = ((LazyDynaMap)dynaBean).getMap().getClass();
+        }
+
+    }
+
+    /**
+     * <p>Set the element Type and DynaClass.</p>
+     *
+     * @param elementDynaClass The DynaClass of the elements.
+     * @exception IllegalArgumentException if the List already
+     *            contains elements or the DynaClass is null.
+     */
+    public void setElementDynaClass(DynaClass elementDynaClass) {
+
+        if (elementDynaClass == null) {
+            throw new IllegalArgumentException("Element DynaClass is missing");
+        }
+
+        if (size() > 0) {
+            throw new IllegalStateException("Element DynaClass cannot be reset");
+        }
+
+        // Try to create a new instance of the DynaBean
+        try {
+            DynaBean dynaBean  = elementDynaClass.newInstance();
+            this.elementDynaBeanType = dynaBean.getClass();
+            if (WrapDynaBean.class.isAssignableFrom(elementDynaBeanType)) {
+                this.elementType = ((WrapDynaBean)dynaBean).getInstance().getClass();
+                this.wrapDynaClass = (WrapDynaClass)elementDynaClass;
+            } else if (LazyDynaMap.class.isAssignableFrom(elementDynaBeanType)) {
+                this.elementType = ((LazyDynaMap)dynaBean).getMap().getClass();
+                this.elementDynaClass = elementDynaClass;
+            } else {
+                this.elementType = dynaBean.getClass();
+                this.elementDynaClass = elementDynaClass;
+            }
+        } catch (Exception e) {
+            throw new IllegalArgumentException(
+                        "Error creating DynaBean from " +
+                        elementDynaClass.getClass().getName() + " - " + e);
+        }
+
+    }
+
+
+    // ------------------- Private Methods ---------------------------
+
+    /**
+     * <p>Automatically <i>grown</i> the List
+     *    to the appropriate size, populating with
+     *    DynaBeans.</p>
+     *
+     * @param requiredSize the required size of the List.
+     */
+    private void growList(int requiredSize) {
+        
+        if (requiredSize < size()) {
+            return;
+        }
+        
+        ensureCapacity(requiredSize + 1);
+        
+        for (int i = size(); i < requiredSize; i++) {
+            DynaBean dynaBean = transform(null);
+            super.add(dynaBean);
+        }
+        
+    }
+
+    /**
+     * <p>Transform the element into a DynaBean:</p>
+     * 
+     * <ul>
+     *    <li>Map elements are turned into LazyDynaMap's.</li>
+     *    <li>POJO Beans are "wrapped" in a WrapDynaBean.</li>
+     *    <li>DynaBeans are unchanged.</li>
+     * </li>
+     *
+     * @param element The element to transformt.
+     * @param The DynaBean to store in the List.
+     */
+    private DynaBean transform(Object element) {
+
+        DynaBean dynaBean     = null;
+        Class newDynaBeanType = null;
+        Class newElementType  = null;
+
+        // Create a new element
+        if (element == null) {
+
+            // Default Types to LazyDynaBean
+            // if not specified
+            if (elementType == null) {
+                setElementDynaClass(new LazyDynaClass());
+            }
+
+            // Get DynaClass (restore WrapDynaClass lost in serialization)
+            DynaClass dynaClass = (elementDynaClass == null) ? wrapDynaClass : elementDynaClass;
+            if (dynaClass == null) {
+                setElementType(elementType);
+            }
+                         
+            // Create a new DynaBean            
+            try {
+                dynaBean = dynaClass.newInstance();
+                newDynaBeanType = dynaBean.getClass();
+            } catch (Exception e) {
+                throw new IllegalArgumentException("Error creating DynaBean: " 
+                              + dynaClass.getClass().getName() 
+                              + " - " + e);
+            }
+
+        } else {
+
+            // Transform Object to a DynaBean
+            newElementType = element.getClass();
+            if (Map.class.isAssignableFrom(element.getClass())) {
+                dynaBean = new LazyDynaMap((Map)element);
+            } else if (DynaBean.class.isAssignableFrom(element.getClass())) {
+                dynaBean = (DynaBean)element;
+            } else {
+                dynaBean = new WrapDynaBean(element);
+            }
+
+            newDynaBeanType = dynaBean.getClass();
+
+        }
+
+        // Re-calculate the element type
+        newElementType = dynaBean.getClass();
+        if (WrapDynaBean.class.isAssignableFrom(newDynaBeanType)) {
+            newElementType = ((WrapDynaBean)dynaBean).getInstance().getClass();
+        } else if (LazyDynaMap.class.isAssignableFrom(newDynaBeanType)) {
+            newElementType = ((LazyDynaMap)dynaBean).getMap().getClass();
+        }
+
+        // Check the new element type, matches all the 
+        // other elements in the List
+        if (newElementType != elementType) {
+            throw new IllegalArgumentException("Element Type "  + newElementType 
+                       + " doesn't match other elements " + elementType);
+        }
+
+        return dynaBean;
+        
+    }
+    
+}

Propchange: jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/LazyDynaList.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/proper/beanutils/trunk/src/java/org/apache/commons/beanutils/LazyDynaList.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: jakarta/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/LazyDynaListTestCase.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/LazyDynaListTestCase.java?rev=307162&view=auto
==============================================================================
--- jakarta/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/LazyDynaListTestCase.java (added)
+++ jakarta/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/LazyDynaListTestCase.java Fri Oct  7 09:47:24 2005
@@ -0,0 +1,559 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.beanutils;
+
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.TreeMap;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import junit.framework.TestCase;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * <p>Test Case for the <code>LazyDynaList</code>class.</p>
+ *
+ * @author Niall Pemberton
+ */
+public class LazyDynaListTestCase extends TestCase {
+
+    private static final String BASIC_PROP1 = "BasicDynaClass_Property1";
+    private static final String BASIC_PROP2 = "BasicDynaClass_Property2";
+
+    protected DynaProperty[] properties = new DynaProperty[] {
+                                               new DynaProperty(BASIC_PROP1, String.class),
+                                               new DynaProperty(BASIC_PROP2, HashMap.class)};
+
+    protected DynaClass treeMapDynaClass = new LazyDynaMap(new TreeMap());
+    protected DynaClass hashMapDynaClass = new LazyDynaMap(new HashMap());
+    protected DynaClass pojoDynaClass = new WrapDynaBean(new TestBean()).getDynaClass();
+    protected DynaClass basicDynaClass = new BasicDynaClass("test", BasicDynaBean.class, properties);
+
+    // ---------------------------------------------------------- Constructors
+
+    /**
+     * Construct a new instance of this test case.
+     *
+     * @param name Name of the test case
+     */
+    public LazyDynaListTestCase(String name) {
+        super(name);
+    }
+
+    // -------------------------------------------------- Overall Test Methods
+
+    /**
+     * Run thus Test
+     */
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(suite());
+    }
+
+    /**
+     * Return the tests included in this test suite.
+     */
+    public static Test suite() {
+        return (new TestSuite(LazyDynaListTestCase.class));
+    }
+
+    /**
+     * Set up instance variables required by this test case.
+     */
+    public void setUp() throws Exception {
+    }
+
+    /**
+     * Tear down instance variables required by this test case.
+     */
+    public void tearDown() {
+    }
+
+    // ------------------------------------------------ Individual Test Methods
+
+    /**
+     * Test DynaBean Create
+     */
+    public void testDynaBeanDynaClass() {
+
+        // Create LazyArrayList for DynaBeans
+        LazyDynaList list = new LazyDynaList(basicDynaClass);
+
+        // test
+        dynaBeanTest(list, BasicDynaBean.class, basicDynaClass, new BenchBean());
+    }
+
+    /**
+     * Test DynaBean Create
+     */
+    public void testDynaBeanType() {
+
+        // Create LazyArrayList for DynaBeans
+        LazyDynaList list = new LazyDynaList(LazyDynaBean.class);
+
+   
+        LazyDynaBean bean = new LazyDynaBean();
+        bean.set("prop1", "val");
+
+        // test
+        dynaBeanTest(list, LazyDynaBean.class, bean.getDynaClass(), new BenchBean());
+    }
+
+    /**
+     * Test Map Create
+     */
+    public void testMapDynaClass() {
+
+        // Create LazyArrayList for TreeMap's
+        LazyDynaList list = new LazyDynaList(treeMapDynaClass);
+
+        // test
+        mapTest(list, TreeMap.class, new BenchBean());
+
+    }
+
+    /**
+     * Test Map Create
+     */
+    public void testMapType() {
+
+        // Create LazyArrayList for HashMap's
+        LazyDynaList list = new LazyDynaList(HashMap.class);
+
+        // test
+        mapTest(list, HashMap.class, new BenchBean());
+
+    }
+
+    /**
+     * Test Pojo Create
+     */
+    public void testPojoDynaClass() {
+
+        // Create LazyArrayList for POJO's
+        LazyDynaList list = new LazyDynaList(pojoDynaClass);
+
+        // test
+        pojoTest(list, TestBean.class, new BenchBean());
+
+    }
+
+    /**
+     * Test Pojo Create
+     */
+    public void testPojoType() {
+
+        // Create LazyArrayList for POJO's
+        LazyDynaList list = new LazyDynaList(TestBean.class);
+
+        // test
+        pojoTest(list, TestBean.class, new BenchBean());
+
+    }
+
+    /**
+     * Test Collection
+     */
+    public void testCollection(LazyDynaList list, Class testClass, DynaClass testDynaClass, Object wrongBean) {
+
+        // ----- Create Collection & Array of Maps -----
+        int size = 5;
+        List testList = new ArrayList(size);
+        TreeMap[] testArray = new TreeMap[size];
+        for (int i = 0; i < size; i++) {
+            testArray[i] = new TreeMap();
+            testArray[i].put("prop"+i, "val"+i);
+            testList.add(testArray[i]);
+        }
+
+
+        // ----- Create LazyArrayList from Collection -----
+        LazyDynaList lazyList = new LazyDynaList(testList);
+        assertEquals("1. check size", size, lazyList.size());
+
+        DynaBean[] dynaArray = lazyList.toDynaBeanArray();
+        TreeMap[]  mapArray  = (TreeMap[])lazyList.toArray();
+
+        // Check values
+        assertEquals("2. check size", size, dynaArray.length);
+        assertEquals("3. check size", size, mapArray.length);
+        for (int i = 0; i < size; i++) {
+            assertEquals("4."+i+" DynaBean error ", "val"+i, dynaArray[i].get("prop"+i));
+            assertEquals("5."+i+" Map error ", "val"+i, mapArray[i].get("prop"+i));
+        }
+
+
+
+        // ----- Create LazyArrayList from Array -----
+        lazyList = new LazyDynaList(testArray);
+        assertEquals("6. check size", size, lazyList.size());
+
+        dynaArray = lazyList.toDynaBeanArray();
+        mapArray  = (TreeMap[])lazyList.toArray();
+
+        // Check values
+        assertEquals("7. check size", size, dynaArray.length);
+        assertEquals("8. check size", size, mapArray.length);
+        for (int i = 0; i < size; i++) {
+            assertEquals("9."+i+" DynaBean error ", "val"+i, dynaArray[i].get("prop"+i));
+            assertEquals("10."+i+" Map error ", "val"+i, mapArray[i].get("prop"+i));
+        }
+
+    }
+
+
+    /**
+     * Test DynaBean Create
+     */
+    private void dynaBeanTest(LazyDynaList list, Class testClass, DynaClass testDynaClass, Object wrongBean) {
+
+        // Test get(index) created correct DynaBean - Second
+        Object dynaBean = list.get(1);
+        assertNotNull("1. DynaBean Not Created", dynaBean);
+        assertEquals("2. Wrong Type", testClass, dynaBean.getClass());
+
+        // Test toArray() creates correct Array - Second
+        Object array = list.toArray();
+        assertNotNull("3. Array Not Created", array);
+        assertEquals("4. Not DynaBean[]", testClass, array.getClass().getComponentType());
+        DynaBean[] dynaArray = (DynaBean[])array;
+        assertEquals("5. Array Size Wrong", 2, dynaArray.length);
+
+        // Test get(index) created correct DynaBean - Fourth
+        dynaBean = list.get(3);
+        assertNotNull("6. DynaBean Not Created", dynaBean);
+        assertEquals("7. Wrong type", testClass, dynaBean.getClass());
+
+        // Test toArray() creates correct Array - Fourth
+        array = list.toArray();
+        assertNotNull("8. Array Not Created", array);
+        assertEquals("9. Not DynaBean[]", testClass, array.getClass().getComponentType());
+        dynaArray = (DynaBean[])array;
+        assertEquals("10. Array Size Wrong", 4, dynaArray.length);
+
+        // Test fail if different type added
+        try {
+            list.add(2, wrongBean);
+            fail("Expected IllegalArgumentException");
+        } catch(IllegalArgumentException ignore) {
+            // expected result
+        }
+
+
+        // find a String property to set
+        String testProperty = findStringProperty(testDynaClass);
+        assertNotNull("Test Property Not Found", testProperty);
+        dynaArray = list.toDynaBeanArray();
+        for (int i = 0; i < dynaArray.length; i++) {
+            dynaArray[i].set(testProperty, "orig_pos"+i);
+        }
+
+        // Create Collection
+        List collection = new ArrayList();
+        try {
+            collection.add(testDynaClass.newInstance());
+            collection.add(testDynaClass.newInstance());
+            collection.add(testDynaClass.newInstance());
+        } catch(Exception ex) {
+            fail("1. FAILED: " + ex);
+        }
+        int expectedSize = dynaArray.length + collection.size();
+        String origValue = (String)((DynaBean)collection.get(0)).get(testProperty);
+        ((DynaBean)collection.get(0)).set(testProperty, origValue+"_updated_"+0);
+        ((DynaBean)collection.get(1)).set(testProperty, origValue+"_updated_"+1);
+        ((DynaBean)collection.get(2)).set(testProperty, origValue+"_updated_"+2);
+
+        // Test Insert - addAll(index, Collection)
+        list.addAll(1, collection);
+        dynaArray = list.toDynaBeanArray();
+
+        // Check array after insert
+        dynaArray = list.toDynaBeanArray();
+        assertEquals("11. Array Size Wrong", expectedSize, dynaArray.length);
+
+        // Check Beans have inserted correctly - by checking the property values
+        assertEquals("12. Wrong Value", "orig_pos0",             dynaArray[0].get(testProperty));
+        assertEquals("13. Wrong Value", origValue+"_updated_"+0, dynaArray[1].get(testProperty));
+        assertEquals("14. Wrong Value", origValue+"_updated_"+1, dynaArray[2].get(testProperty));
+        assertEquals("15. Wrong Value", origValue+"_updated_"+2, dynaArray[3].get(testProperty));
+        assertEquals("16. Wrong Value", "orig_pos1",             dynaArray[4].get(testProperty));
+
+
+        // Test Insert - add(index, Object)
+        try {
+            DynaBean extraElement = (DynaBean)testDynaClass.newInstance();
+            extraElement.set(testProperty, "extraOne");
+            list.add(2, extraElement);
+            dynaArray = list.toDynaBeanArray();
+            assertEquals("17. Wrong Value", origValue+"_updated_"+0, dynaArray[1].get(testProperty));
+            assertEquals("18. Wrong Value", "extraOne",              dynaArray[2].get(testProperty));
+            assertEquals("19. Wrong Value", origValue+"_updated_"+1, dynaArray[3].get(testProperty));
+        } catch(Exception ex) {
+            fail("2. FAILED: " + ex);
+        }
+
+    }
+
+    /**
+     * Test Map Create
+     */
+    private String findStringProperty(DynaClass dynaClass) {
+        DynaProperty[] properties = dynaClass.getDynaProperties();
+        for (int i = 0; i < properties.length; i++) {
+            if (properties[i].getType() == String.class) {
+                return properties[i].getName();
+            }
+        }
+        return null;
+    }
+
+
+
+    /**
+     * Test Map Create
+     */
+    private void mapTest(LazyDynaList list, Class testClass, Object wrongBean) {
+
+        // Test get(index) created correct DynaBean - First
+        Object dynaBean = list.get(0);
+        assertNotNull("1. DynaBean Not Created", dynaBean);
+        assertEquals("2. Not LazyDynaMap", LazyDynaMap.class, dynaBean.getClass());
+
+        // Test get(index) created correct Map - First
+        Object map = ((LazyDynaMap)dynaBean).getMap();
+        assertNotNull("3. Map Not Created", map);
+        assertEquals("4. Wrong Map", testClass, map.getClass());
+
+        // Test toArray() creates correct Array - First
+        Object array = list.toArray();
+        assertNotNull("5. Array Not Created", array);
+        assertEquals("6. Not Map[]", testClass, array.getClass().getComponentType());
+        Map[] mapArray = (Map[])array;
+        assertEquals("7. Array Size Wrong", 1, mapArray.length);
+
+        // Test get(index) created correct DynaBean - Third
+        dynaBean = list.get(2);
+        assertNotNull("8. DynaBean Not Created", dynaBean);
+        assertEquals("9. Not LazyDynaMap", LazyDynaMap.class, dynaBean.getClass());
+
+        // Test get(index) created correct Map - Third
+        map = ((LazyDynaMap)dynaBean).getMap();
+        assertNotNull("10. Map Not Created", map);
+        assertEquals("11. Wrong Map", testClass, map.getClass());
+
+        // Test toArray() creates correct Array - Third
+        array = list.toArray();
+        assertNotNull("12. Array Not Created", array);
+        assertEquals("13. Not Map[]", testClass, array.getClass().getComponentType());
+        mapArray = (Map[])array;
+        assertEquals("14. Array Size Wrong", 3, mapArray.length);
+
+        // Test fail if different type added
+        try {
+            list.add(2, wrongBean);
+            fail("Expected IllegalArgumentException");
+        } catch(IllegalArgumentException ignore) {
+            // expected result
+        }
+
+    }
+
+    /**
+     * Test Pojo Create
+     */
+    private void pojoTest(LazyDynaList list, Class testClass, Object wrongBean) {
+
+        // Test get(index) created correct DynaBean - First
+        Object dynaBean = list.get(0);
+        assertNotNull("1. DynaBean Not Created", dynaBean);
+        assertEquals("2. Not WrapDynaBean", WrapDynaBean.class, dynaBean.getClass());
+
+        // Test get(index) created correct POJO - First
+        Object pojoBean = ((WrapDynaBean)dynaBean).getInstance();
+        assertNotNull("3. POJO Not Created", pojoBean);
+        assertEquals("4. Not WrapDynaBean", testClass, pojoBean.getClass());
+
+        // Test toArray() creates correct Array - First
+        Object array = list.toArray();
+        assertNotNull("5. Array Not Created", array);
+        assertEquals("6. Wrong array", testClass, array.getClass().getComponentType());
+        Object[] pojoArray = (Object[])array;
+        assertEquals("7. Array Size Wrong", 1, pojoArray.length);
+
+        // Test get(index) created correct DynaBean - Second
+        dynaBean = list.get(1);
+        assertNotNull("8. DynaBean Not Created", dynaBean);
+        assertEquals("9. Not WrapDynaBean", WrapDynaBean.class, dynaBean.getClass());
+
+        // Test get(index) created correct POJO - Second
+        pojoBean = ((WrapDynaBean)dynaBean).getInstance();
+        assertNotNull("10. POJO Not Created", pojoBean);
+        assertEquals("11. Not WrapDynaBean", testClass, pojoBean.getClass());
+
+        // Test toArray() creates correct Array - Second
+        array = list.toArray();
+        assertNotNull("12. Array Not Created", array);
+        assertEquals("13. Wrong array", testClass, array.getClass().getComponentType());
+        pojoArray = (Object[])array;
+        assertEquals("14. Array Size Wrong", 2, pojoArray.length);
+
+        // Test fail if different type added
+        try {
+            list.add(2, wrongBean);
+            fail("Expected IllegalArgumentException");
+        } catch(IllegalArgumentException ignore) {
+            // expected result
+        }
+
+    }
+
+    /**
+     * Test DynaBean serialization.
+     */
+    public void testSerializationDynaBean() {
+
+        // Create LazyArrayList for DynaBeans
+        LazyDynaList target = new LazyDynaList(basicDynaClass);
+        BasicDynaBean bean = (BasicDynaBean)target.get(0);
+
+        // Set a Property
+        assertNull("pre-set check", bean.get(BASIC_PROP1));
+        bean.set(BASIC_PROP1, "value1");
+        assertEquals("post-set check", "value1", bean.get(BASIC_PROP1));
+
+        // Serialize/Deserialize
+        LazyDynaList result = (LazyDynaList)serializeDeserialize(target, "DynaBean");
+        target = null;
+        bean = null;
+
+        // Confirm property value
+        bean = (BasicDynaBean)result.get(0);
+        assertEquals("post-serialize check", "value1", bean.get(BASIC_PROP1));
+
+    }
+
+    /**
+     * Test DynaBean serialization.
+     */
+    public void testSerializationLazyDynaBean() {
+
+        // Create LazyArrayList for DynaBeans
+        LazyDynaList target = new LazyDynaList();
+        LazyDynaBean bean = (LazyDynaBean)target.get(0);
+
+        // Set a Property
+        assertNull("pre-set check", bean.get(BASIC_PROP1));
+        bean.set(BASIC_PROP1, "value1");
+        assertEquals("post-set check", "value1", bean.get(BASIC_PROP1));
+
+        // Serialize/Deserialize
+        LazyDynaList result = (LazyDynaList)serializeDeserialize(target, "DynaBean");
+        target = null;
+        bean = null;
+
+        // Confirm property value
+        bean = (LazyDynaBean)result.get(0);
+        assertEquals("post-serialize check", "value1", bean.get(BASIC_PROP1));
+
+    }
+
+    /**
+     * Test Map serialization.
+     */
+    public void testSerializationMap() {
+
+        // Create LazyArrayList for DynaBeans
+        LazyDynaList target = new LazyDynaList(treeMapDynaClass);
+        LazyDynaMap bean = (LazyDynaMap)target.get(0);
+
+        // Set a Property
+        assertNull("pre-set check", bean.get(BASIC_PROP1));
+        bean.set(BASIC_PROP1, "value1");
+        assertEquals("post-set check", "value1", bean.get(BASIC_PROP1));
+
+        // Serialize/Deserialize
+        LazyDynaList result = (LazyDynaList)serializeDeserialize(target, "Map");
+        target = null;
+        bean = null;
+
+        // Confirm property value
+        bean = (LazyDynaMap)result.get(0);
+        assertEquals("post-serialize check", "value1", bean.get(BASIC_PROP1));
+
+    }
+
+    /**
+     * Test POJO (WrapDynaBean) serialization.
+     */
+    public void testSerializationPojo() {
+
+        // Create LazyArrayList for DynaBeans
+        LazyDynaList target = new LazyDynaList(pojoDynaClass);
+        WrapDynaBean bean = (WrapDynaBean)target.get(0);
+
+        // Set a Property
+        assertEquals("pre-set check", "This is a string", bean.get("stringProperty"));
+        bean.set("stringProperty", "value1");
+        assertEquals("post-set check", "value1", bean.get("stringProperty"));
+
+        // Serialize/Deserialize
+        LazyDynaList result = (LazyDynaList)serializeDeserialize(target, "POJO");
+        target = null;
+        bean = null;
+
+        // Confirm property value
+        bean = (WrapDynaBean)result.get(0);
+        assertEquals("post-serialize check", "value1", bean.get("stringProperty"));
+
+    }
+
+    /**
+     * Do serialization and deserialization.
+     */
+    private Object serializeDeserialize(Object target, String text) {
+
+        // Serialize the test object
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+            oos.writeObject(target);
+            oos.flush();
+            oos.close();
+        } catch (Exception e) {
+            fail(text + ": Exception during serialization: " + e);
+        }
+
+        // Deserialize the test object
+        Object result = null;
+        try {
+            ByteArrayInputStream bais =
+                new ByteArrayInputStream(baos.toByteArray());
+            ObjectInputStream ois = new ObjectInputStream(bais);
+            result = ois.readObject();
+            bais.close();
+        } catch (Exception e) {
+            fail(text + ": Exception during deserialization: " + e);
+        }
+        return result;
+
+    }
+
+}
\ No newline at end of file

Propchange: jakarta/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/LazyDynaListTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/proper/beanutils/trunk/src/test/org/apache/commons/beanutils/LazyDynaListTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org