/* MBeanServerInvocationHandler.java -- Provides a proxy for a bean.
   Copyright (C) 2007 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 javax.management;

import gnu.javax.management.Translator;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * <p>
 * Provides a proxy for a management bean.  The methods
 * of the given interface are fulfilled by redirecting the
 * calls over an {@link MBeanServerConnection} to the bean
 * specified by the supplied {@link ObjectName}.
 * </p>
 * <p>
 * The {@link java.lang.reflect.InvocationHandler} also makes
 * provision for {@link MXBean}s by providing type conversion
 * according to the rules defined for these beans.  The input
 * parameters are converted to their equivalent open type before
 * calling the method, and then the return value is converted
 * back from its open type to the appropriate Java type.  For
 * example, a method that takes an {@link Enum} as input and
 * returns a {@link java.util.List} will have the input value
 * converted from an {@link Enum} to a {@link String}, while
 * the return value will be converted from its return type
 * (an appropriately typed array) to a {@link java.util.List}.
 * </p>
 * <p>
 * The proxy has special cases for the {@link Object#equals(Object)},
 * {@link Object#hashCode()} and {@link Object#toString()} methods.
 * Unless they are specified explictly by the interface, the
 * following behaviour is provided for these methods by the proxy:
 * </p>
 * <ul>
 * <li><code>equals(Object)</code> returns true if the other object
 * is an {@link MBeanServerInvocationHandler} with the same
 * {@link MBeanServerConnection} and {@link ObjectName}.  If an
 * interface class was specified on construction for one of the
 * proxies, then the same class must have also been specified
 * for the other.</li>
 * <li><code>hashCode()</code> returns the same value for
 * equivalent proxies.</li>
 * <li><code>toString()</code> returns a textual representation
 * of the proxy.</li>
 * </ul>
 * 
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 * @since 1.5
 */
public class MBeanServerInvocationHandler
  implements InvocationHandler
{

  /**
   * The connection used to make the calls.
   */
  private MBeanServerConnection conn;

  /**
   * The name of the bean to perform operations on.
   */
  private ObjectName name;

  /**
   * True if this proxy is for an {@link MXBean}.
   */
  private boolean mxBean;

  /**
   * The interface class associated with the bean.
   */
  private Class<?> iface;

  /**
   * Constructs a new {@link MBeanServerInvocationHandler}
   * which forwards methods to the supplied bean via the
   * given {@link MBeanServerConnection}.  This constructor
   * is used in preference to
   * {@link JMX#newMBeanProxy(MBeanServerConnection, ObjectName,
   * Class<T>)} if you wish to make your own call to
   * {@link java.lang.reflect.Proxy#newInstance(ClassLoader,
   * Class[], java.lang.reflect.InvocationHandler)} with
   * a different {@link ClassLoader}.  Calling this constructor
   * is equivalent to <code>MBeanServerInvocationHandler(conn,
   * name, false)</code>.  The other constructor should be used
   * instead if the bean being proxied is an {@link MXBean}.
   *
   * @param conn the connection through which methods will
   *             be forwarded to the bean.
   * @param name the name of the bean to use to provide the
   *             actual calls.
   */
  public MBeanServerInvocationHandler(MBeanServerConnection conn,
				      ObjectName name)
  {
    this(conn, name, false);
  }

  /**
   * Constructs a new {@link MBeanServerInvocationHandler}
   * which forwards methods to the supplied bean via the
   * given {@link MBeanServerConnection}.  This constructor
   * is used in preference to
   * {@link JMX#newMBeanProxy(MBeanServerConnection, ObjectName,
   * Class<T>)} if you wish to make your own call to
   * {@link java.lang.reflect.Proxy#newInstance(ClassLoader,
   * Class[], java.lang.reflect.InvocationHandler)} with
   * a different {@link ClassLoader}.  
   *
   * @param conn the connection through which methods will
   *             be forwarded to the bean.
   * @param name the name of the bean to use to provide the
   *             actual calls.
   * @param mxBean true if the bean being proxied is an
   *               {@link MXBean}.
   * @since 1.6
   */
  public MBeanServerInvocationHandler(MBeanServerConnection conn,
				      ObjectName name, boolean mxBean)
  {
    this.conn = conn;
    this.name = name;
    this.mxBean = mxBean;
  }

  /**
   * Returns the connection through which the calls to the bean
   * will be made.
   * 
   * @return the connection being used to forward the calls to
   *         the bean.
   * @since 1.6
   */
  public MBeanServerConnection getMBeanServerConnection()
  {
    return conn;
  }

  /**
   * Returns the name of the bean to which method calls are made.
   *
   * @return the bean which provides the actual method calls.
   * @since 1.6
   */
  public ObjectName getObjectName()
  {
    return name;
  }

  /**
   * Called by the proxy class whenever a method is called.  The method
   * is emulated by retrieving an attribute from, setting an attribute on
   * or invoking a method on the server connection as required.  Translation
   * between the Java data types supplied as arguments to the open types used
   * by the bean is provided, as well as translation of the return value back
   * in to the appropriate Java type if the bean is an {@link MXBean}.
   *
   * @param proxy the proxy on which the method was called.
   * @param method the method which was called.
   * @param args the arguments supplied to the method.
   * @return the return value from the method.
   * @throws Throwable if an exception is thrown in performing the
   *                   method emulation.
   */
  public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable
  {
    String mName = method.getName();
    Class<?> proxyClass = proxy.getClass();
    if (mName.equals("toString"))
      {
	if (inInterface(mName, proxyClass))
	  return conn.invoke(name,mName,null,null);
	else
	  return proxyClass.getName() + "[name=" + name 
	    + ", conn=" + conn + "]";
      }
    if (mName.equals("hashCode"))
      {
	if (inInterface(mName, proxyClass))
	  return conn.invoke(name,mName,null,null);
	else
	  return conn.hashCode() + name.hashCode()
	    + (iface == null ? 0 : iface.hashCode());
      }
    if (mName.equals("equals"))
      {
	if (inInterface(mName, proxyClass, Object.class))
	  return conn.invoke(name,mName,new Object[]{args[0]},
			     new String[]{"java.lang.Object"});
	else
	  {
	    if (args[0].getClass() != proxy.getClass())
	      return false;
	    InvocationHandler ih = Proxy.getInvocationHandler(args[0]);
	    if (ih instanceof MBeanServerInvocationHandler)
	      {
		MBeanServerInvocationHandler h =
		  (MBeanServerInvocationHandler) ih;
		return conn.equals(h.getMBeanServerConnection())
		  && name.equals(h.getObjectName())
		  && (iface == null ? h.iface == null 
		      : iface.equals(h.iface));
	      }
	    return false;
	  }
      }
    if (NotificationEmitter.class.isAssignableFrom(proxyClass))
      {
	if (mName.equals("addNotificationListener"))
	  {
	    conn.addNotificationListener(name,
					 (NotificationListener) args[0],
					 (NotificationFilter) args[1],
					 args[2]);
	    return null;
	  }
	if (mName.equals("getNotificationInfo"))
	  return conn.getMBeanInfo(name).getNotifications();
	if (mName.equals("removeNotificationListener"))
	  {
	    if (args.length == 1)
	      conn.removeNotificationListener(name, 
					      (NotificationListener)
					      args[0]);
	    else
	      conn.removeNotificationListener(name, 
					      (NotificationListener)
					      args[0],
					      (NotificationFilter)
					      args[1], args[2]);
	    return null;
	  }
      }
    String[] sigs;
    if (args == null)
      sigs = null;
    else
      {
	sigs = new String[args.length];
	for (int a = 0; a < args.length; ++a)
	  sigs[a] = args[a].getClass().getName();
      }
    String attrib = null;
    if (mName.startsWith("get"))
      attrib = mName.substring(3);
    else if (mName.startsWith("is"))
      attrib = mName.substring(2);
    if (attrib != null)
      {
	Object val = conn.getAttribute(name, attrib);
	if (mxBean)
	  return Translator.toJava(val, method);
	else
	  return val;
      }
    else if (mName.startsWith("set"))
      {
	Object arg;
	if (mxBean)
	  arg = Translator.fromJava(args, method)[0];
	else
	  arg = args[0];
	conn.setAttribute(name, new Attribute(mName.substring(3), arg));
	return null;
      }
    if (mxBean)
      return Translator.toJava(conn.invoke(name, mName, 
					   Translator.fromJava(args,method),
					   sigs), method);
    else
      return conn.invoke(name, mName, args, sigs);
  }

  /**
   * Returns true if this is a proxy for an {@link MXBean}
   * and conversions must be applied to input parameters
   * and return types, according to the rules for such beans.
   *
   * @return true if this is a proxy for an {@link MXBean}.
   * @since 1.6
   */
  public boolean isMXBean()
  {
    return mxBean;
  }

  /**
   * <p>
   * Returns a proxy for the specified bean.  A proxy object is created
   * using <code>Proxy.newProxyInstance(iface.getClassLoader(),
   * new Class[] { iface }, handler)</code>.  The
   * {@link javax.management.NotificationEmitter} class is included as the
   * second element of the array if <code>broadcaster</code> is true.
   * <code>handler</code> refers to the invocation handler which forwards
   * calls to the connection, which is created by a call to
   * <code>new MBeanServerInvocationHandler(conn, name)</code>. 
   * </p>
   * <p>
   * <strong>Note</strong>: use of the proxy may result in
   * {@link java.io.IOException}s from the underlying
   * {@link MBeanServerConnection}.
   * As of 1.6, the use of {@link JMX#newMBeanProxy(MBeanServerConnection,
   * ObjectName,Class)} and {@link JMX#newMBeanProxy(MBeanServerConnection,
   * ObjectName,Class,boolean)} is preferred.
   * </p>
   *
   * @param conn the server connection to use to access the bean.
   * @param name the {@link javax.management.ObjectName} of the
   *             bean to provide a proxy for.
   * @param iface the interface for the bean being proxied.
   * @param broadcaster true if the proxy should implement
   *                    {@link NotificationEmitter}.
   * @return a proxy for the specified bean.
   * @see JMX#newMBeanProxy(MBeanServerConnection,ObjectName,Class)
   */
  // Suppress warnings as we know an instance of T will be returned.
  @SuppressWarnings("unchecked")
  public static <T> T newProxyInstance(MBeanServerConnection conn,
				       ObjectName name, Class<T> iface,
				       boolean broadcaster)
  {
    if (broadcaster)
      return (T) Proxy.newProxyInstance(iface.getClassLoader(),
					new Class[] { iface,
						      NotificationEmitter.class },
					new MBeanServerInvocationHandler(conn,name));
    else
      return (T) Proxy.newProxyInstance(iface.getClassLoader(),
					new Class[] { iface },
					new MBeanServerInvocationHandler(conn,name));
  }

  /**
   * Returns true if the specified method is specified
   * by one of the proxy's interfaces.
   *
   * @param name the name of the method to search for.
   * @param proxyClass the class of the proxy.
   * @param args the arguments to the method.
   * @return true if one of the interfaces specifies the
   *         given method.
   */
  private boolean inInterface(String name, Class<?> proxyClass,
			      Class<?>... args)
  {
    for (Class<?> iface : proxyClass.getInterfaces())
      {
	try
	  {
	    iface.getMethod(name, args);
	    return true;
	  }
	catch (NoSuchMethodException e)
	  {
	    /* Ignored; this interface doesn't specify
	       the method. */
	  }
      }
    return false;
  }
  
}

