/* Statement.java
   Copyright (C) 2004, 2005, 2006, 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 java.beans;

import gnu.java.lang.CPStringBuilder;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/**
 * <p>A Statement captures the execution of an object method.  It stores
 * the object, the method to call, and the arguments to the method and
 * provides the ability to execute the method on the object, using the
 * provided arguments.</p>
 *
 * @author Jerry Quinn (jlquinn@optonline.net)
 * @author Robert Schuster (robertschuster@fsfe.org)
 * @since 1.4
 */
public class Statement
{
  private Object target;
  private String methodName;
  private Object[] arguments;

  /**
   * One or the other of these will get a value after execute is
   * called once, but not both.
   */
  private transient Method method;
  private transient Constructor ctor;

  /**
   * <p>Constructs a statement representing the invocation of
   * object.methodName(arg[0], arg[1], ...);</p>
   *
   * <p>If the argument array is null it is replaced with an
   * array of zero length.</p>
   *
   * @param target The object to invoke the method on.
   * @param methodName The object method to invoke.
   * @param arguments An array of arguments to pass to the method.
   */
  public Statement(Object target, String methodName, Object[] arguments)
  {
    this.target = target;
    this.methodName = methodName;
    this.arguments = (arguments != null) ? arguments : new Object[0];
  }

  /**
   * Execute the statement.
   *
   * <p>Finds the specified method in the target object and calls it with
   * the arguments given in the constructor.</p>
   *
   * <p>The most specific method according to the JLS(15.11) is used when
   * there are multiple methods with the same name.</p>
   *
   * <p>Execute performs some special handling for methods and
   * parameters:
   * <ul>
   * <li>Static methods can be executed by providing the class as a
   * target.</li>
   *
   * <li>The method name new is reserved to call the constructor 
   * new() will construct an object and return it.  Not useful unless
   * an expression :-)</li>
   *
   * <li>If the target is an array, get and set as defined in
   * java.util.List are recognized as valid methods and mapped to the
   * methods of the same name in java.lang.reflect.Array.</li>
   *
   * <li>The native datatype wrappers Boolean, Byte, Character, Double,
   * Float, Integer, Long, and Short will map to methods that have
   * native datatypes as parameters, in the same way as Method.invoke.
   * However, these wrappers also select methods that actually take
   * the wrapper type as an argument.</li>
   * </ul>
   * </p>
   *
   * <p>The Sun spec doesn't deal with overloading between int and
   * Integer carefully.  If there are two methods, one that takes an
   * Integer and the other taking an int, the method chosen is not
   * specified, and can depend on the order in which the methods are
   * declared in the source file.</p>
   *
   * @throws Exception if an exception occurs while locating or
   * 		       invoking the method.
   */
  public void execute() throws Exception
  {
    doExecute();
  }
  
  private static Class wrappers[] = 
    {
      Boolean.class, Byte.class, Character.class, Double.class, Float.class,
      Integer.class, Long.class, Short.class
    };

  private static Class natives[] = 
    {
      Boolean.TYPE, Byte.TYPE, Character.TYPE, Double.TYPE, Float.TYPE,
      Integer.TYPE, Long.TYPE, Short.TYPE
    };

  /** Given a wrapper class, return the native class for it.
   * <p>For example, if <code>c</code> is <code>Integer</code>, 
   * <code>Integer.TYPE</code> is returned.</p>
   */
  private Class unwrap(Class c)
  {
    for (int i = 0; i < wrappers.length; i++)
      if (c == wrappers[i])
	return natives[i];
    return null;
  }

  /** Returns <code>true</code> if all args can be assigned to
   * <code>params</code>, <code>false</code> otherwise.
   *
   * <p>Arrays are guaranteed to be the same length.</p>
   */
  private boolean compatible(Class[] params, Class[] args)
  {
    for (int i = 0; i < params.length; i++)
      {
    // Argument types are derived from argument values. If one of them was
    // null then we cannot deduce its type. However null can be assigned to
    // any type.
    if (args[i] == null)
      continue;
    
    // Treat Integer like int if appropriate
	Class nativeType = unwrap(args[i]);
	if (nativeType != null && params[i].isPrimitive()
	    && params[i].isAssignableFrom(nativeType))
	  continue;
	if (params[i].isAssignableFrom(args[i]))
	  continue;

	return false;
      }
    return true;
  }

  /**
   * Returns <code>true</code> if the method arguments in first are
   * more specific than the method arguments in second, i.e. all
   * arguments in <code>first</code> can be assigned to those in
   * <code>second</code>.
   *
   * <p>A method is more specific if all parameters can also be fed to
   * the less specific method, because, e.g. the less specific method
   * accepts a base class of the equivalent argument for the more
   * specific one.</p>
   *
   * @param first a <code>Class[]</code> value
   * @param second a <code>Class[]</code> value
   * @return a <code>boolean</code> value
   */
  private boolean moreSpecific(Class[] first, Class[] second)
  {
    for (int j=0; j < first.length; j++)
      {
	if (second[j].isAssignableFrom(first[j]))
	  continue;
	return false;
      }
    return true;
  }

  final Object doExecute() throws Exception
  {
    Class klazz = (target instanceof Class)
	? (Class) target : target.getClass();
    Object args[] = (arguments == null) ? new Object[0] : arguments;
    Class argTypes[] = new Class[args.length];
    
    // Retrieve type or use null if the argument is null. The null argument
    // type is later used in compatible().
    for (int i = 0; i < args.length; i++)
      argTypes[i] = (args[i] != null) ? args[i].getClass() : null;

    if (target.getClass().isArray())
      {
	// FIXME: invoke may have to be used.  For now, cast to Number
	// and hope for the best.  If caller didn't behave, we go boom
	// and throw the exception.
	if (methodName.equals("get") && argTypes.length == 1)
	  return Array.get(target, ((Number)args[0]).intValue());
	if (methodName.equals("set") && argTypes.length == 2)
	  {
	    Object obj = Array.get(target, ((Number)args[0]).intValue());
	    Array.set(target, ((Number)args[0]).intValue(), args[1]);
	    return obj;
	  }
	throw new NoSuchMethodException("No matching method for statement " + toString());
      }

    // If we already cached the method, just use it.
    if (method != null)
      return method.invoke(target, args);
    else if (ctor != null)
      return ctor.newInstance(args);

    // Find a matching method to call.  JDK seems to go through all
    // this to find the method to call.

    // if method name or length don't match, skip
    // Need to go through each arg
    // If arg is wrapper - check if method arg is matchable builtin
    //  or same type or super
    //  - check that method arg is same or super

    if (methodName.equals("new") && target instanceof Class)
      {
	Constructor ctors[] = klazz.getConstructors();
	for (int i = 0; i < ctors.length; i++)
	  {
	    // Skip methods with wrong number of args.
	    Class ptypes[] = ctors[i].getParameterTypes();

	    if (ptypes.length != args.length)
	      continue;

	    // Check if method matches
	    if (!compatible(ptypes, argTypes))
	      continue;

	    // Use method[i] if it is more specific. 
	    // FIXME: should this check both directions and throw if
	    // neither is more specific?
	    if (ctor == null)
	      {
		ctor = ctors[i];
		continue;
	      }
	    Class mptypes[] = ctor.getParameterTypes();
	    if (moreSpecific(ptypes, mptypes))
	      ctor = ctors[i];
	  }
	if (ctor == null)
	  throw new InstantiationException("No matching constructor for statement " + toString());
	return ctor.newInstance(args);
      }

    Method methods[] = klazz.getMethods();

    for (int i = 0; i < methods.length; i++)
      {
	// Skip methods with wrong name or number of args.
	if (!methods[i].getName().equals(methodName))
	  continue;
	Class ptypes[] = methods[i].getParameterTypes();
	if (ptypes.length != args.length)
	  continue;

	// Check if method matches
	if (!compatible(ptypes, argTypes))
	  continue;

	// Use method[i] if it is more specific. 
	// FIXME: should this check both directions and throw if
	// neither is more specific?
	if (method == null)
	  {
	    method = methods[i];
	    continue;
	  }
	Class mptypes[] = method.getParameterTypes();
	if (moreSpecific(ptypes, mptypes))
	  method = methods[i];
      }
    if (method == null)
      throw new NoSuchMethodException("No matching method for statement " + toString());

    // If we were calling Class.forName(String) we intercept and call the
    // forName-variant that allows a ClassLoader argument. We take the
    // system classloader (aka application classloader) here to make sure
    // that application defined classes can be resolved. If we would not
    // do that the Class.forName implementation would use the class loader
    // of java.beans.Statement which is <null> and cannot resolve application
    // defined classes.
    if (method.equals(
           Class.class.getMethod("forName", new Class[] { String.class })))
      return Class.forName(
               (String) args[0], true, ClassLoader.getSystemClassLoader());

    try {
    return method.invoke(target, args);
    } catch(IllegalArgumentException iae){
      System.err.println("method: " + method);
      
      for(int i=0;i<args.length;i++){
        System.err.println("args[" + i + "]: " + args[i]);
      }
      throw iae;
    }
  }

  

  /** Return the statement arguments. */
  public Object[] getArguments() { return arguments; }

  /** Return the statement method name. */
  public String getMethodName() { return methodName; }

  /** Return the statement object. */
  public Object getTarget() { return target; }

  /** 
   * Returns a string representation of this <code>Statement</code>. 
   * 
   * @return A string representation of this <code>Statement</code>. 
   */
  public String toString()
  {
    CPStringBuilder result = new CPStringBuilder(); 

    String targetName;
    if (target != null)
      targetName = target.getClass().getSimpleName();
    else 
      targetName = "null";

    result.append(targetName);
    result.append(".");
    result.append(methodName);
    result.append("(");

    String sep = "";
    for (int i = 0; i < arguments.length; i++)
      {
        result.append(sep);
        result.append(
          ( arguments[i] == null ) ? "null" : 
            ( arguments[i] instanceof String ) ? "\"" + arguments[i] + "\"" :
            arguments[i].getClass().getSimpleName());
        sep = ", ";
      }
    result.append(");");

    return result.toString();
  }
  
}
