/*******************************************************************************
 * Copyright (c) 2001, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jem.internal.proxy.ide;
/*
 *  $RCSfile: IDEMethodProxy.java,v $
 *  $Revision: 1.9 $  $Date: 2005/08/24 20:39:06 $ 
 */

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;

import org.eclipse.jem.internal.proxy.core.*;

public class IDEMethodProxy extends IDEAccessibleObjectProxy implements IMethodProxy {

	protected IDEMethodProxy(IDEProxyFactoryRegistry aRegistry, Method aMethod) {
		super(aRegistry, aMethod);
	}

	public IBeanTypeProxy getClassType() {
		return ((IDEStandardBeanTypeProxyFactory) fProxyFactoryRegistry.getBeanTypeProxyFactory()).getBeanTypeProxy(
			((Method) getBean()).getDeclaringClass());
	}
	public IBeanTypeProxy getReturnType() {
		return ((IDEStandardBeanTypeProxyFactory) fProxyFactoryRegistry.getBeanTypeProxyFactory()).getBeanTypeProxy(
			((Method) getBean()).getReturnType());
	}
	public IBeanTypeProxy[] getParameterTypes() {
		Class[] parmClasses = ((Method) getBean()).getParameterTypes();
		IBeanTypeProxy[] parmTypes = new IBeanTypeProxy[parmClasses.length];
		IDEStandardBeanTypeProxyFactory factory = (IDEStandardBeanTypeProxyFactory) fProxyFactoryRegistry.getBeanTypeProxyFactory();
		for (int i = 0; i < parmClasses.length; i++) {
			parmTypes[i] = factory.getBeanTypeProxy(parmClasses[i]);
		}
		return parmTypes;
	}
	public String getName() {
		return ((Method) getBean()).getName();
	}

	/**
	 * The type proxy is constant proxy out of the method factory.
	 */
	public IBeanTypeProxy getTypeProxy() {
		return ((IDEMethodProxyFactory) fProxyFactoryRegistry.getMethodProxyFactory()).methodType;
	}

	/**
	 * Invoke the method directly.  Because we are an IDEMethodProxy we can assume that IBeanProxy
	 * is an IDEBeanProxy and we can get its bean directly
	 */
	public IBeanProxy invoke(IBeanProxy subject) throws ThrowableProxy {
		try {
			Object result = ((Method) getBean()).invoke(subject != null ? ((IIDEBeanProxy) subject).getBean() : null, new Object[0]);
			if (result == null) {
				return null;
			} else {
				// The result may be a java.lang.Integer when we really want to create an int
				// Reflection always give you the big object
				Class returnType = ((Method) getBean()).getReturnType();
				return getBeanProxy(returnType, result);
			}
		} catch (InvocationTargetException e) {
			// This is a wrappered exception. Return the wrappered one so it looks like
			// it was the real one.
			IBeanTypeProxy exceptionTypeProxy =
				((IDEStandardBeanTypeProxyFactory) fProxyFactoryRegistry.getBeanTypeProxyFactory()).getBeanTypeProxy(
					e.getTargetException().getClass());
			throw new IDEThrowableProxy(e.getTargetException(), exceptionTypeProxy);
		} catch (Exception exc) {
			IBeanTypeProxy exceptionTypeProxy =
				((IDEStandardBeanTypeProxyFactory) fProxyFactoryRegistry.getBeanTypeProxyFactory()).getBeanTypeProxy(exc.getClass());
			throw new IDEThrowableProxy(exc, exceptionTypeProxy);
		}
	}
	/**
	 * Do not throw an exception
	 */
	public IBeanProxy invokeCatchThrowableExceptions(IBeanProxy subject) {
		try {
			return invoke(subject);
		} catch (ThrowableProxy exc) {
			ProxyPlugin.getPlugin().getLogger().log(
				new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", exc)); //$NON-NLS-1$
		}
		return null;
	}
	/**
	 * Invoke the method with argument.  The argument will be an IDEBeanProxy 
	 * ( because we are an IDEMethodProxy ) so we can cast to it and get the actual bean
	 * itself and use this to invoke against method which is the actual
	 * java.lang.Reflect instance
	 */
	public IBeanProxy invoke(IBeanProxy subject, IBeanProxy argument) throws ThrowableProxy {
		try {
			Object result =
				((Method) getBean()).invoke(
					subject != null ? ((IIDEBeanProxy) subject).getBean() : null,
					new Object[] { argument != null ? ((IIDEBeanProxy) argument).getBean() : null });
			if (result == null) {
				return null;
			} else {
				Class returnType = ((Method) getBean()).getReturnType();
				return getBeanProxy(returnType, result);
			}
		} catch (InvocationTargetException e) {
			// This is a wrappered exception. Return the wrappered one so it looks like
			// it was the real one.
			IBeanTypeProxy exceptionTypeProxy =
				((IDEStandardBeanTypeProxyFactory) fProxyFactoryRegistry.getBeanTypeProxyFactory()).getBeanTypeProxy(
					e.getTargetException().getClass());
			throw new IDEThrowableProxy(e.getTargetException(), exceptionTypeProxy);
		} catch (Exception exc) {
			IBeanTypeProxy exceptionTypeProxy =
				((IDEStandardBeanTypeProxyFactory) fProxyFactoryRegistry.getBeanTypeProxyFactory()).getBeanTypeProxy(exc.getClass());
			throw new IDEThrowableProxy(exc, exceptionTypeProxy);
		}
	}
	/**
	 * Invoke without throwing an exception
	 */
	public IBeanProxy invokeCatchThrowableExceptions(IBeanProxy subject, IBeanProxy argument) {
		try {
			return invoke(subject, argument);
		} catch (ThrowableProxy exc) {
			ProxyPlugin.getPlugin().getLogger().log(
				new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", exc)); //$NON-NLS-1$
		}
		return null;
	}
	/**
	 * Invoke the method with arguments.  The arguments will be IDEBeanProxy objects
	 * ( because we are an IDEMethodProxy ) so we can cast to them and get the actual bean
	 * objects themselves and use these to invoke against method which is the actual
	 * java.lang.Reflect instance
	 */
	public IBeanProxy invoke(IBeanProxy subject, IBeanProxy[] arguments) throws ThrowableProxy {
		Object[] beanArguments = new Object[arguments.length];
		for (int i = 0; i < arguments.length; i++) {
			if (arguments[i] != null) {
				beanArguments[i] = ((IIDEBeanProxy) arguments[i]).getBean();
			}
		}
		try {
			Object result = ((Method) getBean()).invoke(subject != null ? ((IIDEBeanProxy) subject).getBean() : null, beanArguments);
			if (result == null) {
				return null;
			} else {
				Class returnType = ((Method) getBean()).getReturnType();
				return getBeanProxy(returnType, result);
			}
		} catch (InvocationTargetException e) {
			// This is a wrappered exception. Return the wrappered one so it looks like
			// it was the real one.
			IBeanTypeProxy exceptionTypeProxy =
				((IDEStandardBeanTypeProxyFactory) fProxyFactoryRegistry.getBeanTypeProxyFactory()).getBeanTypeProxy(
					e.getTargetException().getClass());
			throw new IDEThrowableProxy(e.getTargetException(), exceptionTypeProxy);
		} catch (Exception exc) {
			IBeanTypeProxy exceptionTypeProxy =
				((IDEStandardBeanTypeProxyFactory) fProxyFactoryRegistry.getBeanTypeProxyFactory()).getBeanTypeProxy(exc.getClass());
			throw new IDEThrowableProxy(exc, exceptionTypeProxy);
		}
	}
	/**
	 * Invoke without throwing an exception
	 */
	public IBeanProxy invokeCatchThrowableExceptions(IBeanProxy subject, IBeanProxy[] arguments) {
		try {
			return invoke(subject, arguments);
		} catch (ThrowableProxy exc) {
			ProxyPlugin.getPlugin().getLogger().log(
				new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", exc)); //$NON-NLS-1$
		}
		return null;
	}
	IBeanProxy getBeanProxy(Class returnType, Object bean) {
		return fProxyFactoryRegistry.getBeanProxy(returnType, bean);
	}
}
