/* 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;
  }

}
