/* CollectionPersistenceDelegate.java - A PersistenceDelegate for Collection subclasses.
 Copyright (C) 2005 Free Software Foundation, Inc.

 This file is part of GNU Classpath.

 GNU Classpath is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.

 GNU Classpath is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with GNU Classpath; see the file COPYING.  If not, write to the
 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 02110-1301 USA.

 Linking this library statically or dynamically with other modules is
 making a combined work based on this library.  Thus, the terms and
 conditions of the GNU General Public License cover the whole
 combination.

 As a special exception, the copyright holders of this library give you
 permission to link this library with independent modules to produce an
 executable, regardless of the license terms of these independent
 modules, and to copy and distribute the resulting executable under
 terms of your choice, provided that you also meet, for each linked
 independent module, the terms and conditions of the license of that
 module.  An independent module is a module which is not derived from
 or based on this library.  If you modify this library, you may extend
 this exception to your version of the library, but you are not
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */


package gnu.java.beans.encoder;

import java.util.Collection;
import java.beans.Encoder;
import java.beans.Expression;
import java.beans.PersistenceDelegate;
import java.beans.Statement;

import java.util.Iterator;

/** <p>A <code>PersistenceDelegate</code> implementation that calls
 * the no-argument constructor to create the Collection instance and
 * uses an iterator to add all the objects it reaches through it.</p>
 *
 * <p>It is used for <code>Set</code> and <code>List</code>
 * implementations.</p>
 *
 * @author Robert Schuster (robertschuster@fsfe.org)
 */
public class CollectionPersistenceDelegate extends PersistenceDelegate
{

  protected Expression instantiate(Object oldInstance, Encoder out)
  {
    return new Expression(
                          oldInstance,
                          oldInstance.getClass(),
                          "new",
                          null);
  }

  protected void initialize(Class type, Object oldInstance, Object newInstance,
                            Encoder out)
  {
    Iterator ite = ((Collection) oldInstance).iterator();

    while (ite.hasNext())
      {
        out.writeStatement(new Statement(oldInstance, "add",
                                         new Object[] { ite.next() }));

      }

  }

}
