/* gnu.java.beans.decoder.ObjectHandler
   Copyright (C) 2004 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.decoder;

import java.beans.ExceptionListener;

import org.xml.sax.Attributes;

/** An ObjectHandler parses the &lt;object&gt; tag and thereby creates various
 * Context implementations.
 *
 * @author Robert Schuster
 *
 */
public class ObjectHandler extends AbstractElementHandler
{
  /**
   * XXX: Can all results be stored with an object id?
   *
   *
   * @param PersistenceParser
   */
  ObjectHandler(ElementHandler parent)
  {
    super(parent, true);
  }

  protected Context startElement(Attributes attributes, ExceptionListener exceptionListener)
    throws AssemblyException
  {
    String className = attributes.getValue("class");
    String methodName = attributes.getValue("method");
    String fieldName = attributes.getValue("field");
    String index = attributes.getValue("index");
    String propertyName = attributes.getValue("property");
    String id = attributes.getValue("id");
    String idRef = attributes.getValue("idref");

    /* first check if we just want to access an existing object (idref present)
     *
     * note: <object idref="foo" method="bar"/> is not valid to call method "bar"
     * on the object with id "foo". Instead this should return the object "foo"
     * itself. The right way to this is:
     * <object idref="foo">
     *         <object method="bar"/>
     * </object>
     *
     * This means that if idref is present class, method, field, index and
     * property are obsolete.
     */
    if (idRef != null)
      // reactivates an existing object and giving it another name if id exists
      return new ObjectContext(id, getObject(idRef));

    // decides whether we are in a static (className present) or dynamic context
    if (className != null)
      {
        try
          {
            Class klass = instantiateClass(className);

            // class name exists which means that we are in a static context.
            // so we may want to ...
            // access a static field if the fieldName exists
            if (fieldName != null)
              {
                try
                  {
                    return new ObjectContext(id,
                                             klass.getField(fieldName).get(null));
                  }
                catch (NoSuchFieldException nsfe)
                  {
                    throw new AssemblyException(nsfe);
                  }
                catch (IllegalAccessException iae)
                  {
                    throw new AssemblyException(iae);
                  }
              }

            // (falling through is important!)
            // run a constructor if methodName is "new" or null
            if (methodName == null || methodName.equals("new"))
              return new ConstructorContext(id, klass);

            // (falling through is important!)
            // run a static method on the given class (if methodName exists, which is implied already)
            return new StaticMethodContext(id, klass, methodName);
            // XXX: should fail if unexpected attributes are present?
          }
        catch (ClassNotFoundException cnfe)
          {
            throw new AssemblyException(cnfe);
          }
      }
    else
      {
        // className does not exist which means we are in the context of
        // some object and want to ...
        // access the get(int index) method if index != null
        if (index != null)
          {
            try
              {
                // Note: http://java.sun.com/products/jfc/tsc/articles/persistence3/ says
                // that <void index="4"/> will make up a get()-call. But this is wrong because
                // <void/> tags never return values (to the surrounding context)
                return new IndexContext(id, Integer.parseInt(index));
              }
            catch (NumberFormatException nfe)
              {
                throw new AssemblyException(nfe);
              }
          }

        // access a method if methodName exists
        if (methodName != null)
          return new MethodContext(id, methodName);

        // (falling through is important!)
        // access a property if a propertyName exists
        if (propertyName != null && propertyName.length() > 0)
          // this is reported as an ordinary method access where the propertyName is
          // converted into a 'getter'-method name: convert first character of property name
          // to upper case and prepend 'get'
          // Note: This will be a getter-method because the <object> tag implies that a return
          // value is expected.
          return new PropertyContext(id, propertyName);
      }

    throw new AssemblyException(new IllegalArgumentException("Wrong or missing attributes for <object> tag."));
  }
}
