package org.eclipse.jem.internal.proxy.initParser;
/*******************************************************************************
 * Copyright (c)  2001, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
/*
 *  $RCSfile: MethodHelper.java,v $
 *  $Revision: 1.2 $  $Date: 2004/02/03 23:18:36 $ 
 */


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.lang.reflect.*;

/**
 * This is a class to do message/constructor work. 
 * Specifically to find the most appropriate method.
 */
public class MethodHelper {
	
	/*
	 * The class that is used to represent Null class type.
	 * 
	 * @since 1.0.0
	 */
	private static class NULL_CLASS {
	}
	
	public static final Class NULL_TYPE = NULL_CLASS.class;
	
	static final ArrayList sPrimitivesOrder;
	static final int sCharPos;
	
	static {
		sPrimitivesOrder = new ArrayList(6);
		sPrimitivesOrder.add(Byte.TYPE);
		sPrimitivesOrder.add(Short.TYPE);
		sPrimitivesOrder.add(Integer.TYPE);
		sPrimitivesOrder.add(Long.TYPE);
		sPrimitivesOrder.add(Float.TYPE);
		sPrimitivesOrder.add(Double.TYPE);

		// char can be treated like a short for purposes of ordering.
		sCharPos = sPrimitivesOrder.indexOf(Short.TYPE);
	}
	
	/**
	 * Return whether the type2 can be assigned to type1 in
	 * method argument conversion.
	 */
	public static boolean isAssignableFrom(Class type1, Class type2) {
		if (type1 == type2)
			return true;	// They're the same, so assignable.
		if (type1.isPrimitive()) {
			if (type2.isPrimitive()) {
				if (type1 == Boolean.TYPE || type2 == Boolean.TYPE)
					return false;	// Since not equal and one is boolean and the other isn't, not assignable
				int type1Pos = (type1 != Character.TYPE) ? sPrimitivesOrder.indexOf(type1) : sCharPos;
				int type2Pos = (type2 != Character.TYPE) ? sPrimitivesOrder.indexOf(type2) : sCharPos;
				return type1Pos > type2Pos;	// It can be widened if type1 is higher in the order
			}
			return false;	// primitive to non-primitive, not assignable.
		} else
			if (type2 == NULL_TYPE)
				return true;	// NULL_TYPE represents null for us, and null can be assigned to any object
			else		
				return type1.isAssignableFrom(type2);	// Can type2 be assigned to type1
	}
	
	
	/**
	 * Every entry in Array2 can be assigned to the corresponding entry in Array1.
	 */
	public static boolean isAssignableFrom(Class[] types1, Class[] types2) {
		if (types1.length != types2.length)
			return false;	// Not the same size, so not compatible.
		for (int i=0; i<types1.length; i++) {
			if (!isAssignableFrom(types1[i], types2[i]))
				return false;
		}
		return true;	// All are assignable
	}
	
	/**
	 * Ambiguous Method Exception. I.E. There is more than one that could be used.
	 */
	public static class AmbiguousMethodException extends Exception {
		public AmbiguousMethodException() {
		}
		public AmbiguousMethodException(String msg) {
			super(msg);
		}
	}
		
	/**
	 * Return the index of the most compatible method/constructor from the lists passed in.
	 * MethodsList: List of methods (if null then this is for constructors)
	 * ParmsList: List of parms for each method (each entry will be Class[]).
	 */
	private static int findMostCompatible(List methods, List parms) throws AmbiguousMethodException {
		// The algorithm used is from the Java Language Specification 15.12.2.2
		// First find the maximally specific ones
		int maxSpecific = -1;	// Index of the most specific one
		Class[][] parmsCopy = (Class[][]) parms.toArray(new Class[parms.size()][]);
		int size = parmsCopy.length;
		// For each entry see if it is maximally specific
nextMethod:	for (int i=0; i<size; i++) {
			Class dclClassi = methods != null ? ((Method) methods.get(i)).getDeclaringClass() : null;
			Class[] parmsi = parmsCopy[i];
			for (int j=i+1; j<size; j++) {
				if (parmsCopy[j] == null)
					continue;	// This one was thrown out
				// Methodi is maximally specific if
				//   a) Methodi declaring class is assignable to Methodj declaring class
				//   b) Methodi parms are assignable to Methodj parms
				//
				// First see if Methodi is more specific, if it is
				// then throw out Methodj and continue
				// If Methodi is not compatible to Methodj, then test reverse comparison
				boolean moreSpecificClass = true;	// Default is more specific class
				Class dclClassj = null;
				if (dclClassi != null) {
					// Step a
					moreSpecificClass = isAssignableFrom(dclClassj = ((Method) methods.get(j)).getDeclaringClass(), dclClassi);
				}
				
				// Step b
				Class[] parmsj = parmsCopy[j];
				if (moreSpecificClass && isAssignableFrom(parmsj, parmsi)) {
					// Methodi is more specific than Methodj, throw j out, continue to next j
					parmsCopy[j] = null;
					continue;
				}
				
				// Now see if Methodj is more specific than Methodi
				moreSpecificClass = true;
				if (dclClassi != null)
					moreSpecificClass = isAssignableFrom(dclClassi, dclClassj);
				if (moreSpecificClass && isAssignableFrom(parmsi, parmsj)) {
					// Methodj is more specific than Methodi, go to the next i.
					continue nextMethod;
				}
				
				// Neither method is more specific
			}
			
			// None more specific than Methodi, so add i to the maximally specific list.
			if (maxSpecific != -1) {
				// A quick test, if there is already a maximally specific one and the
				// arglist differs, then it is immediately ambiguous. There can be
				// more than one with the same parm list because interface methods will also
				// show up in the methods list.
				if (!Arrays.equals(parmsCopy[maxSpecific], parmsi))
					throw new AmbiguousMethodException();
					
				// A quick test, if i is not abstract, then save this one as the most specific
				// because there will never be more than one non-abstract one of identical parm types.
				// So the one already in the maxSpecific must be an abstract.
				// If i is abstract, then don't replace the current most specific.
				// If this is constructors, we shouldn't be here because you can't have more
				// than one identical constructor
				if (!Modifier.isAbstract(((Method) methods.get(i)).getModifiers()))
					maxSpecific = i;	// Replace the max specific with this one
			} else
				maxSpecific = i;	// The first one
		}
		
		// maxSpecific has the choosen one, either the first of all the abstract ones, or the only
		// non-abstract one.
		return maxSpecific;		
	}
	
	/**
	 * Find the most compatible method for the given arguments.
	 */
	public static Method findCompatibleMethod(Class receiver, String methodName, Class[] arguments) throws EvaluationException {
		try {
			Method mthd = receiver.getMethod(methodName, arguments);
			return mthd;	// Found exact match
		} catch (NoSuchMethodException exc) {
			// Need to find most compatible one.
			Method mthds[] = receiver.getMethods();
			ArrayList parmsList = new ArrayList(mthds.length);	// The parm list from each compatible method.
			ArrayList mthdsList = new ArrayList(mthds.length);	// The list of compatible methods, same order as the parms above.
			for (int i = 0; i<mthds.length; i++) {
				Method mthd = mthds[i];
				if (!mthd.getName().equals(methodName))
					continue;	// Not compatible, not same name
				Class[] parms = mthd.getParameterTypes();
				if (!isAssignableFrom(parms, arguments))
					continue;	// Not compatible, parms
				// It is compatible with the requested method
				parmsList.add(parms);
				mthdsList.add(mthd);
			}
			
			// Now have list of compatible methods.
			if (parmsList.size() == 0)
				throw new EvaluationException(exc);	// None found, so rethrow the exception
			if (parmsList.size() == 1)
				return (Method) mthdsList.get(0);	// Only one, so return it
				
			// Now find the most compatible method
			try {
				int mostCompatible = findMostCompatible(mthdsList, parmsList);
				return (Method) mthdsList.get(mostCompatible);
			} catch (AmbiguousMethodException e) {
				throw new EvaluationException(new AmbiguousMethodException(methodName));	// Put the method name into the message
			}
		}
	}
	
	/**
	 * Find the most compatible constructor for the given arguments.
	 */
	public static java.lang.reflect.Constructor findCompatibleConstructor(Class receiver, Class[] arguments) throws EvaluationException {
		try {
			java.lang.reflect.Constructor ctor = receiver.getDeclaredConstructor(arguments);
			ctor.setAccessible(true);	// We allow all access, let ide and compiler handle security.
			return ctor;	// Found exact match
		} catch (NoSuchMethodException exc) {
			// Need to find most compatible one.
			java.lang.reflect.Constructor ctors[] = receiver.getDeclaredConstructors();
			ArrayList parmsList = new ArrayList(ctors.length);	// The parm list from each compatible method.
			ArrayList ctorsList = new ArrayList(ctors.length);	// The list of compatible methods, same order as the parms above.
			for (int i = 0; i<ctors.length; i++) {
				java.lang.reflect.Constructor ctor = ctors[i];
				Class[] parms = ctor.getParameterTypes();
				if (!isAssignableFrom(parms, arguments))
					continue;	// Not compatible, parms
				// It is compatible with the requested method
				parmsList.add(parms);
				ctorsList.add(ctor);
			}
			
			// Now have list of compatible methods.
			if (parmsList.size() == 0)
				throw new EvaluationException(exc);	// None found, so rethrow the exception
			if (parmsList.size() == 1) {
				java.lang.reflect.Constructor ctor = (java.lang.reflect.Constructor) ctorsList.get(0);	// Only one, so return it
				ctor.setAccessible(true);	// We allow all access, let ide and compilor handle security.
				return ctor;
			}
				
			// Now find the most compatible ctor
			try {
				int mostCompatible = findMostCompatible(null, parmsList);
				java.lang.reflect.Constructor ctor = (java.lang.reflect.Constructor) ctorsList.get(mostCompatible);
				ctor.setAccessible(true);	// We allow all access, let ide and compilor handle security.
				return ctor;
			} catch (AmbiguousMethodException e) {
				throw new EvaluationException(new AmbiguousMethodException(receiver.getName()));	// Put the class name into the message
			}
		}
	}	
				
		
}