Coverage Report - org.apache.commons.beanutils.LazyDynaList
 
Classes in this File Line Coverage Branch Coverage Complexity
LazyDynaList
68%
108/158
59%
59/100
4.45
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.commons.beanutils;
 18  
 
 19  
 import java.util.ArrayList;
 20  
 import java.util.Map;
 21  
 import java.util.Collection;
 22  
 import java.util.Iterator;
 23  
 import java.lang.reflect.Array;
 24  
 
 25  
 /**
 26  
  * <h2><i>Lazy</i> DynaBean List.</h2>
 27  
  * 
 28  
  * <p>There are two main purposes for this class:</p>
 29  
  *    <ul>
 30  
  *        <li>To provide <i>Lazy List</i> behaviour - automatically
 31  
  *            <i>growing</i> and <i>populating</i> the <code>List</code>
 32  
  *            with either <code>DynaBean</code>, <code>java.util.Map</code>
 33  
  *            or POJO Beans.</li>
 34  
  *        <li>To provide a straight forward way of putting a Collection
 35  
  *            or Array into the lazy list <i>and</i> a straight forward 
 36  
  *            way to get it out again at the end.</li>
 37  
  *    </ul>
 38  
  * 
 39  
  * <p>All elements added to the List are stored as <code>DynaBean</code>'s:</p>
 40  
  * <ul>
 41  
  *    <li><code>java.util.Map</code> elements are "wrapped" in a <code>LazyDynaMap</code>.</i> 
 42  
  *    <li>POJO Bean elements are "wrapped" in a <code>WrapDynaBean.</code></i> 
 43  
  *    <li><code>DynaBean</code>'s are stored un-changed.</i>
 44  
  * </ul>
 45  
  *  
 46  
  * <h4><code>toArray()</code></h4>
 47  
  * <p>The <code>toArray()</code> method returns an array of the
 48  
  *    elements of the appropriate type. If the <code>LazyDynaList</code>
 49  
  *    is populated with <code>java.util.Map</code> objects a 
 50  
  *    <code>Map[]</code> array is returned.
 51  
  *    If the list is populated with POJO Beans an appropriate
 52  
  *    array of the POJO Beans is returned. Otherwise a <code>DynaBean[]</code>
 53  
  *    array is returned.
 54  
  * </p>
 55  
  *  
 56  
  * <h4><code>toDynaBeanArray()</code></h4>
 57  
  * <p>The <code>toDynaBeanArray()</code> method returns a 
 58  
  *    <code>DynaBean[]</code> array of the elements in the List.
 59  
  * </p>
 60  
  *  
 61  
  * <p><strong>N.B.</strong>All the elements in the List must be the
 62  
  *    same type. If the <code>DynaClass</code> or <code>Class</code>
 63  
  *    of the <code>LazyDynaList</code>'s elements is
 64  
  *    not specified, then it will be automatically set to the type
 65  
  *    of the first element populated.
 66  
  * </p>
 67  
  * 
 68  
  * <h3>Example 1</h3>
 69  
  * <p>If you have an array of <code>java.util.Map[]</code> - you can put that into
 70  
  *    a <code>LazyDynaList</code>.</p>
 71  
  * 
 72  
  * <pre><code>
 73  
  *    TreeMap[] myArray = .... // your Map[]
 74  
  *    List lazyList = new LazyDynaList(myArray);
 75  
  * </code></pre>
 76  
  * 
 77  
  * <p>New elements of the appropriate Map type are
 78  
  *    automatically populated:</p>
 79  
  *  
 80  
  * <pre><code>
 81  
  *    // get(index) automatically grows the list
 82  
  *    DynaBean newElement = (DynaBean)lazyList.get(lazyList.size());
 83  
  *    newElement.put("someProperty", "someValue");
 84  
  * </code></pre>
 85  
  * 
 86  
  * <p>Once you've finished you can get back an Array of the
 87  
  *    elements of the appropriate type:</p>
 88  
  *  
 89  
  * <pre><code>
 90  
  *    // Retrieve the array from the list
 91  
  *    TreeMap[] myArray = (TreeMap[])lazyList.toArray());
 92  
  * </code></pre>
 93  
  * 
 94  
  * 
 95  
  * <h3>Example 2</h3>
 96  
  * <p>Alternatively you can create an <i>empty</i> List and
 97  
  *    specify the Class for List's elements. The LazyDynaList
 98  
  *    uses the Class to automatically populate elements:</p>
 99  
  * 
 100  
  * <pre><code>
 101  
  *    // e.g. For Maps
 102  
  *    List lazyList = new LazyDynaList(TreeMap.class);
 103  
  * 
 104  
  *    // e.g. For POJO Beans
 105  
  *    List lazyList = new LazyDynaList(MyPojo.class);
 106  
  * 
 107  
  *    // e.g. For DynaBeans
 108  
  *    List lazyList = new LazyDynaList(MyDynaBean.class);
 109  
  * </code></pre>
 110  
  * 
 111  
  * <h3>Example 3</h3>
 112  
  * <p>Alternatively you can create an <i>empty</i> List and specify the 
 113  
  *    DynaClass for List's elements. The LazyDynaList uses
 114  
  *    the DynaClass to automatically populate elements:</p>
 115  
  * 
 116  
  * <pre><code>
 117  
  *    // e.g. For Maps
 118  
  *    DynaClass dynaClass = new LazyDynaMap(new HashMap());
 119  
  *    List lazyList = new LazyDynaList(dynaClass);
 120  
  * 
 121  
  *    // e.g. For POJO Beans
 122  
  *    DynaClass dynaClass = (new WrapDynaBean(myPojo)).getDynaClass();
 123  
  *    List lazyList = new LazyDynaList(dynaClass);
 124  
  * 
 125  
  *    // e.g. For DynaBeans
 126  
  *    DynaClass dynaClass = new BasicDynaClass(properties);
 127  
  *    List lazyList = new LazyDynaList(dynaClass);
 128  
  * </code></pre>
 129  
  * 
 130  
  * <p><strong>N.B.</strong> You may wonder why control the type
 131  
  *    using a <code>DynaClass</code> rather than the <code>Class</code>
 132  
  *    as in the previous example - the reason is that some <code>DynaBean</code>
 133  
  *    implementations don't have a <i>default</i> empty constructor and
 134  
  *    therefore need to be instantiated using the <code>DynaClass.newInstance()</code>
 135  
  *    method.</p>
 136  
  * 
 137  
  * <h3>Example 4</h3>
 138  
  * <p>A slight variation - set the element type using either
 139  
  *    the <code>setElementType(Class)</code> method or the
 140  
  *    <code>setElementDynaClass(DynaClass)</code> method - then populate
 141  
  *    with the normal <code>java.util.List</code> methods(i.e.
 142  
  *    <code>add()</code>, <code>addAll()</code> or <code>set()</code>).</p>
 143  
  * 
 144  
  * <pre><code>
 145  
  *    // Create a new LazyDynaList (100 element capacity)
 146  
  *    LazyDynaList lazyList = new LazyDynaList(100);
 147  
  * 
 148  
  *    // Either Set the element type...
 149  
  *    lazyList.setElementType(TreeMap.class);
 150  
  * 
 151  
  *    // ...or the element DynaClass...
 152  
  *    lazyList.setElementDynaClass(new MyCustomDynaClass());
 153  
  * 
 154  
  *    // Populate from a collection
 155  
  *    lazyList.addAll(myCollection);
 156  
  *
 157  
  * </code></pre>
 158  
  * 
 159  
  * @author Niall Pemberton
 160  
  * @version $Revision: 926529 $ $Date: 2010-03-23 07:44:24 -0400 (Tue, 23 Mar 2010) $
 161  
  * @since 1.8.0
 162  
  */
 163  
 public class LazyDynaList extends ArrayList {
 164  
     
 165  
     /**
 166  
      * The DynaClass of the List's elements.
 167  
      */
 168  
     private DynaClass elementDynaClass;
 169  
     
 170  
     /**
 171  
      * The WrapDynaClass if the List's contains
 172  
      * POJO Bean elements.
 173  
      *
 174  
      * N.B. WrapDynaClass isn't serlializable, which
 175  
      *      is why its stored separately in a 
 176  
      *      transient instance variable.
 177  
      */
 178  
     private transient WrapDynaClass wrapDynaClass;
 179  
     
 180  
     /**
 181  
      * The type of the List's elements.
 182  
      */
 183  
     private Class elementType;
 184  
     
 185  
     /**
 186  
      * The DynaBean type of the List's elements.
 187  
      */
 188  
     private Class elementDynaBeanType;
 189  
 
 190  
 
 191  
     // ------------------- Constructors ------------------------------
 192  
 
 193  
     /**
 194  
      * Default Constructor.
 195  
      */
 196  
     public LazyDynaList() {
 197  2
         super();
 198  2
     }
 199  
 
 200  
     /**
 201  
      * Construct a LazyDynaList with the 
 202  
      * specified capacity.
 203  
      *
 204  
      * @param capacity The initial capacity of the list.
 205  
      */
 206  
     public LazyDynaList(int capacity) {
 207  0
         super(capacity);
 208  
         
 209  0
     }
 210  
 
 211  
     /**
 212  
      * Construct a  LazyDynaList with a
 213  
      * specified DynaClass for its elements.
 214  
      * 
 215  
      * @param elementDynaClass The DynaClass of the List's elements.
 216  
      */
 217  
     public LazyDynaList(DynaClass elementDynaClass) {
 218  6
         super();
 219  6
         setElementDynaClass(elementDynaClass);
 220  6
     }
 221  
 
 222  
     /**
 223  
      * Construct a  LazyDynaList with a
 224  
      * specified type for its elements.
 225  
      * 
 226  
      * @param elementType The Type of the List's elements.
 227  
      */
 228  
     public LazyDynaList(Class elementType) {
 229  3
         super();
 230  3
         setElementType(elementType);
 231  3
     }
 232  
     
 233  
     /**
 234  
      * Construct a  LazyDynaList populated with the
 235  
      * elements of a Collection.
 236  
      *
 237  
      * @param collection The Collection to poulate the List from.
 238  
      */
 239  
     public LazyDynaList(Collection collection) {
 240  0
         super(collection.size());
 241  0
         addAll(collection);
 242  0
     }
 243  
     
 244  
     /**
 245  
      * Construct a  LazyDynaList populated with the
 246  
      * elements of an Array.
 247  
      *
 248  
      * @param array The Array to poulate the List from.
 249  
      */
 250  
     public LazyDynaList(Object[] array) {
 251  0
         super(array.length);
 252  0
         for (int i = 0; i < array.length; i++) {
 253  0
             add(array[i]);
 254  
         }
 255  0
     }
 256  
 
 257  
 
 258  
     // ------------------- java.util.List Methods --------------------
 259  
 
 260  
     /**
 261  
      * <p>Insert an element at the specified index position.</p>
 262  
      * 
 263  
      * <p>If the index position is greater than the current 
 264  
      *    size of the List, then the List is automatically
 265  
      *    <i>grown</i> to the appropriate size.</p>
 266  
      *  
 267  
      * @param index The index position to insert the new element.
 268  
      * @param element The new element to add.
 269  
      */
 270  
     public void add(int index, Object element) {
 271  
 
 272  14
         DynaBean dynaBean = transform(element);
 273  
 
 274  8
         growList(index);
 275  
         
 276  8
         super.add(index, dynaBean);
 277  
 
 278  8
     }
 279  
 
 280  
     /**
 281  
      * <p>Add an element to the List.</p>
 282  
      *
 283  
      * @param element The new element to add.
 284  
      * @return true.
 285  
      */
 286  
     public boolean add(Object element) {
 287  
 
 288  2
         DynaBean dynaBean = transform(element);
 289  
 
 290  2
         return super.add(dynaBean);
 291  
 
 292  
     }
 293  
 
 294  
     /**
 295  
      * <p>Add all the elements from a Collection to the list.
 296  
      *
 297  
      * @param collection The Collection of new elements.
 298  
      * @return true if elements were added.
 299  
      */
 300  
     public boolean addAll(Collection collection) {
 301  
 
 302  0
         if (collection == null || collection.size() == 0) {
 303  0
             return false;
 304  
         }
 305  
         
 306  0
         ensureCapacity(size() + collection.size());
 307  
 
 308  0
         Iterator iterator = collection.iterator();
 309  0
         while (iterator.hasNext()) {
 310  0
             add(iterator.next());
 311  
         }
 312  
 
 313  0
         return true;
 314  
 
 315  
     }
 316  
 
 317  
     /**
 318  
      * <p>Insert all the elements from a Collection into the
 319  
      *    list at a specified position.
 320  
      *
 321  
      * <p>If the index position is greater than the current 
 322  
      *    size of the List, then the List is automatically
 323  
      *    <i>grown</i> to the appropriate size.</p>
 324  
      * 
 325  
      * @param collection The Collection of new elements.
 326  
      * @param index The index position to insert the new elements at.
 327  
      * @return true if elements were added.
 328  
      */
 329  
     public boolean addAll(int index, Collection collection) {
 330  
 
 331  2
         if (collection == null || collection.size() == 0) {
 332  0
             return false;
 333  
         }
 334  
         
 335  2
         ensureCapacity((index > size() ? index : size()) + collection.size());
 336  
         
 337  
         // Call "tranform" with first element, before
 338  
         // List is "grown" to ensure the correct DynaClass
 339  
         // is set.
 340  2
         if (size() == 0) {
 341  0
             transform(collection.iterator().next());
 342  
         }
 343  
 
 344  2
         growList(index);
 345  
 
 346  2
         Iterator iterator = collection.iterator();
 347  8
         while (iterator.hasNext()) {
 348  6
             add(index++, iterator.next());
 349  
         }
 350  
 
 351  2
         return true;
 352  
         
 353  
     }
 354  
 
 355  
     /**
 356  
      * <p>Return the element at the specified position.</p>
 357  
      *
 358  
      * <p>If the position requested is greater than the current 
 359  
      *    size of the List, then the List is automatically
 360  
      *    <i>grown</i> (and populated) to the appropriate size.</p>
 361  
      * 
 362  
      * @param index The index position to insert the new elements at.
 363  
      * @return The element at the specified position.
 364  
      */
 365  
     public Object get(int index) {
 366  
 
 367  98
         growList(index + 1);
 368  
 
 369  98
         return super.get(index);
 370  
 
 371  
     }
 372  
 
 373  
     /**
 374  
      * <p>Set the element at the specified position.</p>
 375  
      *
 376  
      * <p>If the position requested is greater than the current 
 377  
      *    size of the List, then the List is automatically
 378  
      *    <i>grown</i> (and populated) to the appropriate size.</p>
 379  
      * 
 380  
      * @param index The index position to insert the new element at.
 381  
      * @param element The new element.
 382  
      * @return The new element.
 383  
      */
 384  
     public Object set(int index, Object element) {
 385  
 
 386  0
         DynaBean dynaBean = transform(element);
 387  
 
 388  0
         growList(index + 1);
 389  
 
 390  0
         return super.set(index, dynaBean);
 391  
         
 392  
     }
 393  
 
 394  
     /**
 395  
      * <p>Converts the List to an Array.</p>
 396  
      *
 397  
      * <p>The type of Array created depends on the contents
 398  
      *    of the List:</p>
 399  
      * <ul>
 400  
      *    <li>If the List contains only LazyDynaMap type elements
 401  
      *        then a java.util.Map[] array will be created.</li>   
 402  
      *    <li>If the List contains only elements which are 
 403  
      *        "wrapped" DynaBeans then an Object[] of the most
 404  
      *        suitable type will be created.</li>
 405  
      *    <li>...otherwise a DynaBean[] will be created.</li>
 406  
      * 
 407  
      * @return An Array of the elements in this List.
 408  
      */
 409  
     public Object[] toArray() {
 410  
 
 411  12
         if (size() == 0 && elementType == null) {
 412  0
             return new LazyDynaBean[0];
 413  
         }
 414  
 
 415  12
         Object[] array = (Object[])Array.newInstance(elementType, size());
 416  38
         for (int i = 0; i < size(); i++) {
 417  26
             if (Map.class.isAssignableFrom(elementType)) {
 418  8
                 array[i] = ((LazyDynaMap)get(i)).getMap(); 
 419  18
             } else if (DynaBean.class.isAssignableFrom(elementType)) {
 420  12
                 array[i] = get(i);
 421  
             } else {
 422  6
                 array[i] = ((WrapDynaBean)get(i)).getInstance(); 
 423  
             }
 424  
         }
 425  12
         return array;
 426  
         
 427  
     }
 428  
 
 429  
     /**
 430  
      * <p>Converts the List to an Array of the specified type.</p>
 431  
      *
 432  
      * @param model The model for the type of array to return
 433  
      * @return An Array of the elements in this List.
 434  
      */
 435  
     public Object[] toArray(Object[] model) {
 436  
         
 437  
         // Allocate the Array
 438  0
         Class arrayType = model.getClass().getComponentType();
 439  0
         Object[] array = (Object[])Array.newInstance(arrayType, size());
 440  
 
 441  0
         if (size() == 0 && elementType == null) {
 442  0
             return new LazyDynaBean[0];
 443  
         }
 444  
 
 445  0
         if ((DynaBean.class.isAssignableFrom(arrayType))) {
 446  0
             for (int i = 0; i < size(); i++) {
 447  0
                 array[i] = get(i);
 448  
             }
 449  0
             return array;
 450  
         }
 451  
 
 452  0
         if ((arrayType.isAssignableFrom(elementType))) {
 453  0
             for (int i = 0; i < size(); i++) {
 454  0
                 if (Map.class.isAssignableFrom(elementType)) {
 455  0
                     array[i] = ((LazyDynaMap)get(i)).getMap(); 
 456  0
                 } else if (DynaBean.class.isAssignableFrom(elementType)) {
 457  0
                     array[i] = get(i);
 458  
                 } else {
 459  0
                     array[i] = ((WrapDynaBean)get(i)).getInstance(); 
 460  
                 }
 461  
             }
 462  0
             return array;
 463  
         }
 464  
 
 465  0
         throw new IllegalArgumentException("Invalid array type: " 
 466  
                   + arrayType.getName() + " - not compatible with '"
 467  
                   + elementType.getName());
 468  
         
 469  
     }
 470  
 
 471  
 
 472  
     // ------------------- Public Methods ----------------------------
 473  
 
 474  
     /**
 475  
      * <p>Converts the List to an DynaBean Array.</p>
 476  
      *
 477  
      * @return A DynaBean[] of the elements in this List.
 478  
      */
 479  
     public DynaBean[] toDynaBeanArray() {
 480  
 
 481  8
         if (size() == 0 && elementDynaBeanType == null) {
 482  0
             return new LazyDynaBean[0];
 483  
         }
 484  
         
 485  8
         DynaBean[] array = (DynaBean[])Array.newInstance(elementDynaBeanType, size());
 486  60
         for (int i = 0; i < size(); i++) {
 487  52
             array[i] = (DynaBean)get(i);
 488  
         }
 489  8
         return array;
 490  
         
 491  
     }
 492  
 
 493  
     /**
 494  
      * <p>Set the element Type and DynaClass.</p>
 495  
      *
 496  
      * @param elementType The type of the elements.
 497  
      * @exception IllegalArgumentException if the List already
 498  
      *            contains elements or the DynaClass is null.
 499  
      */
 500  
     public void setElementType(Class elementType) {
 501  
 
 502  4
         if (elementType == null) {
 503  0
             throw new IllegalArgumentException("Element Type is missing");
 504  
         }
 505  
 
 506  4
         boolean changeType = (this.elementType != null && !this.elementType.equals(elementType));
 507  4
         if (changeType && size() > 0) {
 508  0
             throw new IllegalStateException("Element Type cannot be reset");
 509  
         }
 510  
 
 511  4
         this.elementType = elementType;
 512  
 
 513  
         // Create a new object of the specified type
 514  4
         Object object = null;
 515  
         try {
 516  4
             object = elementType.newInstance();
 517  0
         } catch (Exception e) {
 518  0
             throw new IllegalArgumentException("Error creating type: " 
 519  
                            + elementType.getName() + " - " + e);
 520  4
         }
 521  
 
 522  
         // Create a DynaBean
 523  4
         DynaBean dynaBean = null;
 524  4
         if (Map.class.isAssignableFrom(elementType)) {
 525  1
             dynaBean = new LazyDynaMap((Map)object);
 526  1
             this.elementDynaClass = dynaBean.getDynaClass();
 527  3
         } else if (DynaBean.class.isAssignableFrom(elementType)) {
 528  1
             dynaBean = (DynaBean)object;
 529  1
             this.elementDynaClass = dynaBean.getDynaClass();
 530  
         } else {
 531  2
             dynaBean = new WrapDynaBean(object);
 532  2
             this.wrapDynaClass = (WrapDynaClass)dynaBean.getDynaClass();
 533  
         }
 534  
 
 535  4
         this.elementDynaBeanType = dynaBean.getClass();
 536  
 
 537  
         // Re-calculate the type
 538  4
         if (WrapDynaBean.class.isAssignableFrom(elementDynaBeanType )) {
 539  2
             this.elementType = ((WrapDynaBean)dynaBean).getInstance().getClass();
 540  2
         } else if (LazyDynaMap.class.isAssignableFrom(elementDynaBeanType )) {
 541  1
             this.elementType = ((LazyDynaMap)dynaBean).getMap().getClass();
 542  
         }
 543  
 
 544  4
     }
 545  
 
 546  
     /**
 547  
      * <p>Set the element Type and DynaClass.</p>
 548  
      *
 549  
      * @param elementDynaClass The DynaClass of the elements.
 550  
      * @exception IllegalArgumentException if the List already
 551  
      *            contains elements or the DynaClass is null.
 552  
      */
 553  
     public void setElementDynaClass(DynaClass elementDynaClass) {
 554  
 
 555  7
         if (elementDynaClass == null) {
 556  0
             throw new IllegalArgumentException("Element DynaClass is missing");
 557  
         }
 558  
 
 559  7
         if (size() > 0) {
 560  0
             throw new IllegalStateException("Element DynaClass cannot be reset");
 561  
         }
 562  
 
 563  
         // Try to create a new instance of the DynaBean
 564  
         try {
 565  7
             DynaBean dynaBean  = elementDynaClass.newInstance();
 566  7
             this.elementDynaBeanType = dynaBean.getClass();
 567  7
             if (WrapDynaBean.class.isAssignableFrom(elementDynaBeanType)) {
 568  2
                 this.elementType = ((WrapDynaBean)dynaBean).getInstance().getClass();
 569  2
                 this.wrapDynaClass = (WrapDynaClass)elementDynaClass;
 570  5
             } else if (LazyDynaMap.class.isAssignableFrom(elementDynaBeanType)) {
 571  2
                 this.elementType = ((LazyDynaMap)dynaBean).getMap().getClass();
 572  2
                 this.elementDynaClass = elementDynaClass;
 573  
             } else {
 574  3
                 this.elementType = dynaBean.getClass();
 575  3
                 this.elementDynaClass = elementDynaClass;
 576  
             }
 577  0
         } catch (Exception e) {
 578  0
             throw new IllegalArgumentException(
 579  
                         "Error creating DynaBean from " +
 580  
                         elementDynaClass.getClass().getName() + " - " + e);
 581  7
         }
 582  
 
 583  7
     }
 584  
 
 585  
 
 586  
     // ------------------- Private Methods ---------------------------
 587  
 
 588  
     /**
 589  
      * <p>Automatically <i>grown</i> the List
 590  
      *    to the appropriate size, populating with
 591  
      *    DynaBeans.</p>
 592  
      *
 593  
      * @param requiredSize the required size of the List.
 594  
      */
 595  
     private void growList(int requiredSize) {
 596  
         
 597  108
         if (requiredSize < size()) {
 598  69
             return;
 599  
         }
 600  
         
 601  39
         ensureCapacity(requiredSize + 1);
 602  
         
 603  61
         for (int i = size(); i < requiredSize; i++) {
 604  22
             DynaBean dynaBean = transform(null);
 605  22
             super.add(dynaBean);
 606  
         }
 607  
         
 608  39
     }
 609  
 
 610  
     /**
 611  
      * <p>Transform the element into a DynaBean:</p>
 612  
      * 
 613  
      * <ul>
 614  
      *    <li>Map elements are turned into LazyDynaMap's.</li>
 615  
      *    <li>POJO Beans are "wrapped" in a WrapDynaBean.</li>
 616  
      *    <li>DynaBeans are unchanged.</li>
 617  
      * </li>
 618  
      *
 619  
      * @param element The element to transformt.
 620  
      * @param The DynaBean to store in the List.
 621  
      */
 622  
     private DynaBean transform(Object element) {
 623  
 
 624  38
         DynaBean dynaBean     = null;
 625  38
         Class newDynaBeanType = null;
 626  38
         Class newElementType  = null;
 627  
 
 628  
         // Create a new element
 629  38
         if (element == null) {
 630  
 
 631  
             // Default Types to LazyDynaBean
 632  
             // if not specified
 633  23
             if (elementType == null) {
 634  1
                 setElementDynaClass(new LazyDynaClass());
 635  
             }
 636  
 
 637  
             // Get DynaClass (restore WrapDynaClass lost in serialization)
 638  23
             if (getDynaClass() == null) {
 639  1
                 setElementType(elementType);
 640  
             }
 641  
                          
 642  
             // Create a new DynaBean            
 643  
             try {
 644  23
                 dynaBean = getDynaClass().newInstance();
 645  23
                 newDynaBeanType = dynaBean.getClass();
 646  0
             } catch (Exception e) {
 647  0
                 throw new IllegalArgumentException("Error creating DynaBean: " 
 648  
                               + getDynaClass().getClass().getName() 
 649  
                               + " - " + e);
 650  23
             }
 651  
 
 652  
         } else {
 653  
 
 654  
             // Transform Object to a DynaBean
 655  15
             newElementType = element.getClass();
 656  15
             if (Map.class.isAssignableFrom(element.getClass())) {
 657  1
                 dynaBean = new LazyDynaMap((Map)element);
 658  14
             } else if (DynaBean.class.isAssignableFrom(element.getClass())) {
 659  8
                 dynaBean = (DynaBean)element;
 660  
             } else {
 661  6
                 dynaBean = new WrapDynaBean(element);
 662  
             }
 663  
 
 664  15
             newDynaBeanType = dynaBean.getClass();
 665  
 
 666  
         }
 667  
 
 668  
         // Re-calculate the element type
 669  38
         newElementType = dynaBean.getClass();
 670  38
         if (WrapDynaBean.class.isAssignableFrom(newDynaBeanType)) {
 671  12
             newElementType = ((WrapDynaBean)dynaBean).getInstance().getClass();
 672  26
         } else if (LazyDynaMap.class.isAssignableFrom(newDynaBeanType)) {
 673  8
             newElementType = ((LazyDynaMap)dynaBean).getMap().getClass();
 674  
         }
 675  
 
 676  
         // Check the new element type, matches all the 
 677  
         // other elements in the List
 678  38
         if (elementType != null && !newElementType.equals(elementType)) {
 679  6
             throw new IllegalArgumentException("Element Type "  + newElementType 
 680  
                        + " doesn't match other elements " + elementType);
 681  
         }
 682  
 
 683  32
         return dynaBean;
 684  
         
 685  
     }
 686  
 
 687  
     /**
 688  
      * Return the DynaClass.
 689  
      */
 690  
     private DynaClass getDynaClass() {
 691  46
         return (elementDynaClass == null ? wrapDynaClass : elementDynaClass);
 692  
     }
 693  
 }