/* StandardMBean.java -- A standard reflection-based management bean.
   Copyright (C) 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 javax.management;

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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Provides a dynamic management bean by using reflection on an
 * interface and an implementing class.  By default, a bean instance
 * is paired up with its interface based on specific naming
 * conventions (if the implementation is called X, the interface must
 * be XMBean).  Using this class removes the need to use a specific
 * naming system to match up the two.  Instead, an instance of this
 * bean is created either via explicit construction or subclassing,
 * and this provides access to the attributes, constructors and
 * operations of the implementation via reflection.  Various hooks are
 * provided in order to allow customization of this process.
 *
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 * @since 1.5
 */
public class StandardMBean
  implements DynamicMBean
{

  /**
   * The interface for this bean.
   */
  private Class<?> iface;

  /**
   * The implementation of the interface.
   */
  private Object impl;

  /**
   * Cached bean information.
   */
  private MBeanInfo info;

  /**
   * Constructs a new {@link StandardMBean} using the specified
   * interface and <code>this</code> as the instance.  This should
   * be used to create an instance via subclassing.
   * 
   * @param iface the interface this bean implements, or <code>null</code>
   *              if the interface should be determined using the naming
   *              convention (class X has interface XMBean).
   * @throws NotCompliantMBeanException if this class doesn't implement
   *                                    the interface or a method appears
   *                                    in the interface that doesn't comply
   *                                    with the naming conventions.
   */
  protected StandardMBean(Class<?> iface)
    throws NotCompliantMBeanException
  {
    if (iface == null)
      {
	String className = getClass().getName();
	try
	  {
	    iface = Class.forName(className + "MBean");
	  }
	catch (ClassNotFoundException e)
	  {
	    for (Class<?> nextIface : getClass().getInterfaces())
	    {
	      if (JMX.isMXBeanInterface(nextIface))
		{
		  iface = nextIface;
		  break;
		}
	    }
	    if (iface == null)  
	      throw (NotCompliantMBeanException) 
		(new NotCompliantMBeanException("An interface for the class " 
						+ className +
						" was not found.").initCause(e));
	  }
      }
    if (!(iface.isInstance(this)))
      throw new NotCompliantMBeanException("The instance, " + impl + 
					   ", is not an instance of " + iface);
    impl = this;
    this.iface = iface;
  }

  /**
   * Constructs a new {@link StandardMBean} using the specified
   * interface and the supplied instance as the implementation.
   * 
   * @param impl the implementation.
   * @param iface the interface the bean implements, or <code>null</code>
   *              if the interface should be determined using the naming
   *              convention (class X has interface XMBean).
   * @throws IllegalArgumentException if <code>impl</code> is <code>null</code>.
   * @throws NotCompliantMBeanException if <code>impl</code> doesn't implement
   *                                    the interface or a method appears
   *                                    in the interface that doesn't comply
   *                                    with the naming conventions.
   */
  public <T> StandardMBean(T impl, Class<T> iface)
    throws NotCompliantMBeanException
  {
    if (impl == null)
      throw new IllegalArgumentException("The specified implementation is null.");
    if (iface == null)
      {
	Class<?> implClass = impl.getClass();
	String className = implClass.getName();
	try
	  {
	    this.iface = Class.forName(className + "MBean", true,
				       implClass.getClassLoader());
	  }
	catch (ClassNotFoundException e)
	  {
	    for (Class<?> nextIface : implClass.getInterfaces())
	    {
	      if (JMX.isMXBeanInterface(nextIface))
		{
		  this.iface = nextIface;
		  break;
		}
	    }
	    if (this.iface == null)  
	      throw (NotCompliantMBeanException) 
		(new NotCompliantMBeanException("An interface for the class " +
						className +
						" was not found.").initCause(e));
	  }
      }
    else
      this.iface = iface;
    if (!(this.iface.isInstance(impl)))
      throw new NotCompliantMBeanException("The instance, " + impl + 
					   ", is not an instance of " + iface);
    this.impl = impl;
  }

  /**
   * Caches the {@link MBeanInfo} instance for this object.  This is a
   * customization hook, so that subclasses can choose the caching policy
   * used.  The default implementation caches the value in the instance
   * itself.  Subclasses may override this so as to not cache the data
   * at all, or so as to use a cache shared between multiple beans.
   *
   * @param info the {@link MBeanInfo} instance to cache, or <code>null</code>
   *             if there is no new value to cache.  When the value is not
   *             <code>null</code>, the cache should replace the current value
   *             with the value supplied here.
   * @see #getCachedMBeanInfo()
   */
  protected void cacheMBeanInfo(MBeanInfo info)
  {
    if (info != null)
      this.info = info;
  }

  /**
   * Obtains the value of the specified attribute of the
   * management bean.  The management bean should perform
   * a lookup for the named attribute, and return its value
   * by calling the appropriate getter method, if possible.
   *
   * @param name the name of the attribute to retrieve.
   * @return the value of the specified attribute.
   * @throws AttributeNotFoundException if the name does not
   *                                    correspond to an attribute
   *                                    of the bean.
   * @throws MBeanException if retrieving the attribute causes
   *                        the bean to throw an exception (which
   *                        becomes the cause of this exception).
   * @throws ReflectionException if an exception occurred in trying
   *                             to use the reflection interface
   *                             to lookup the attribute.  The
   *                             thrown exception is the cause of
   *                             this exception.
   * @see #setAttribute(String)
   */
  public Object getAttribute(String name)
    throws AttributeNotFoundException, MBeanException,
	   ReflectionException
  {
    Method getter;
    try 
      {
	getter = iface.getMethod("get" + name);
      }
    catch (NoSuchMethodException e)
      {
	try 
	  {
	    getter = iface.getMethod("is" + name);
	  }
	catch (NoSuchMethodException ex)
	  {
	    throw ((AttributeNotFoundException) 
		   new AttributeNotFoundException("The attribute, " + name +
						  ", was not found.").initCause(ex));
	  }
      }
    Object result;
    try
      {
	result = getter.invoke(impl);
      }
    catch (IllegalAccessException e)
      {
	throw new ReflectionException(e, "Failed to retrieve " + name);
      }
    catch (IllegalArgumentException e)
      {
	throw new ReflectionException(e, "Failed to retrieve " + name);
      }
    catch (InvocationTargetException e)
      {
	throw new MBeanException((Exception) e.getCause(),
				 "The getter of " + name +
				 " threw an exception");
      }
    return result;
  }

  /**
   * Obtains the values of each of the specified attributes
   * of the management bean.  The returned list includes
   * those attributes that were retrieved and their
   * corresponding values.
   *
   * @param names the names of the attributes to retrieve.
   * @return a list of the retrieved attributes.
   * @see #setAttributes(AttributeList)
   */
  public AttributeList getAttributes(String[] names)
  {
    AttributeList list = new AttributeList(names.length);
    for (int a = 0; a < names.length; ++a)
      {
	try
	  {
	    Object value = getAttribute(names[a]);
	    list.add(new Attribute(names[a], value));
	  }
	catch (AttributeNotFoundException e)
	  {
	    /* Ignored */
	  }
	catch (ReflectionException e)
	  {
	    /* Ignored */
	  }
	catch (MBeanException e)
	  {
	    /* Ignored */
	  }
      }
    return list;
  }

  /**
   * Returns the cached {@link MBeanInfo} instance for this object.  This is a
   * customization hook, so that subclasses can choose the caching policy
   * used.  The default implementation caches the value in the instance
   * itself, and returns this value on calls to this method.
   *
   * @return the cached {@link MBeanInfo} instance, or <code>null</code>
   *         if no value is cached.
   * @see #cacheMBeanInfo(javax.management.MBeanInfo)
   */
  protected MBeanInfo getCachedMBeanInfo()
  {
    return info;
  }

  /**
   * Returns the class name that will be used in the {@link MBeanInfo}
   * instance.  This is a customization hook, so that subclasses can
   * provide a custom class name.  By default, this returns the class
   * name from the supplied {@link MBeanInfo} instance.
   *
   * @param info the {@link MBeanInfo} instance constructed via
   *             reflection.
   * @return the class name to use in the instance.
   */
  protected String getClassName(MBeanInfo info)
  {
    return info.getClassName();
  }

  /**
   * Returns information on the constructors that will be used in
   * the {@link MBeanInfo} instance.  This is a customization hook,
   * so that subclasses can provide their own information on the
   * bean's constructors, if necessary.  By default, this method
   * returns <code>null</code> unless the implementation supplied
   * is either <code>null</code> or <code>this</code>.  This default
   * implementation prevents the use of
   * {@link MBeanServer#createMBean} in cases where the bean is
   * not created as a subclass of {@link StandardMBean}.
   *
   * @param constructors the constructor information created via
   *                     reflection.
   * @param impl the implementation, or <code>null</code> if this
   *             should be ignored.
   * @return the constructor information to use.
   */
  protected MBeanConstructorInfo[] getConstructors(MBeanConstructorInfo[]
						   constructors, Object impl)
  {
    if (impl == null || impl == this)
      return constructors;
    return null;
  }

  /**
   * Returns the description of the attribute that will be used in
   * the supplied {@link MBeanAttributeInfo} instance.  This is a
   * customization hook, so that subclasses can provide a custom
   * description.  By default, this calls
   * {@link #getDescription(MBeanFeatureInfo)} with the supplied
   * {@link MBeanAttributeInfo} instance.
   *
   * @param info the {@link MBeanAttributeInfo} instance constructed
   *             via reflection.
   * @return the description to use in the instance.
   */
  protected String getDescription(MBeanAttributeInfo info)
  {
    return getDescription((MBeanFeatureInfo) info);
  }

  /**
   * Returns the description of the constructor that will be used in
   * the supplied {@link MBeanConstructorInfo} instance.  This is a
   * customization hook, so that subclasses can provide a custom
   * description.  By default, this calls
   * {@link #getDescription(MBeanFeatureInfo)} with the supplied
   * {@link MBeanConstructorInfo} instance.
   *
   * @param info the {@link MBeanConstructorInfo} instance constructed
   *             via reflection.
   * @return the description to use in the instance.
   */
  protected String getDescription(MBeanConstructorInfo info)
  {
    return getDescription((MBeanFeatureInfo) info);
  }

  /**
   * Returns the description of the nth parameter of the constructor
   * that will be used in the supplied {@link MBeanParameterInfo}
   * instance.  This is a customization hook, so that subclasses
   * can provide a custom description.  By default, this calls
   * <code>param.getDescription()</code>.
   *
   * @param info the {@link MBeanConstructorInfo} instance constructed
   *             via reflection.
   * @param param the {@link MBeanParameterInfo} instance constructed
   *             via reflection.
   * @param n the number of the parameter, in order to link it to the
   *          information on the constructor.
   * @return the description to use in the instance.
   */
  protected String getDescription(MBeanConstructorInfo info,
				  MBeanParameterInfo param, int n)
  {
    return param.getDescription();
  }

  /**
   * Returns the description of the supplied feature that
   * will be used in the supplied {@link MBeanFeatureInfo}
   * instance.  This is a customization hook, so that subclasses
   * can provide a custom description.  By default, this calls
   * <code>info.getDescription()</code>.  This method is also called
   * by default for the more specific description methods for attributes,
   * constructors and operations.
   *
   * @param info the {@link MBeanFeatureInfo} instance constructed
   *             via reflection.
   * @return the description to use in the instance.
   */
  protected String getDescription(MBeanFeatureInfo info)
  {
    return info.getDescription();
  }

  /**
   * Returns the description of the bean that will be used in the
   * supplied {@link MBeanInfo} instance.  This is a customization
   * hook, so that subclasses can provide a custom description.  By
   * default, this calls <code>info.getDescription()</code>.
   *
   * @param info the {@link MBeanInfo} instance constructed
   *             via reflection.
   * @return the description to use in the instance.
   */
  protected String getDescription(MBeanInfo info)
  {
    return info.getDescription();
  }

  /**
   * Returns the description of the operation that will be used in
   * the supplied {@link MBeanOperationInfo} instance.  This is a
   * customization hook, so that subclasses can provide a custom
   * description.  By default, this calls
   * {@link #getDescription(MBeanFeatureInfo)} with the supplied
   * {@link MBeanOperationInfo} instance.
   *
   * @param info the {@link MBeanOperationInfo} instance constructed
   *             via reflection.
   * @return the description to use in the instance.
   */
  protected String getDescription(MBeanOperationInfo info)
  {
    return getDescription((MBeanFeatureInfo) info);
  }

  /**
   * Returns the description of the nth parameter of the operation
   * that will be used in the supplied {@link MBeanParameterInfo}
   * instance.  This is a customization hook, so that subclasses
   * can provide a custom description.  By default, this calls
   * <code>param.getDescription()</code>.
   *
   * @param info the {@link MBeanOperationInfo} instance constructed
   *             via reflection.
   * @param param the {@link MBeanParameterInfo} instance constructed
   *             via reflection.
   * @param n the number of the parameter, in order to link it to the
   *          information on the operation.
   * @return the description to use in the instance.
   */
  protected String getDescription(MBeanOperationInfo info,
				  MBeanParameterInfo param, int n)
  {
    return param.getDescription();
  }

  /**
   * Returns the impact of the operation that will be used in the
   * supplied {@link MBeanOperationInfo} instance.  This is a
   * customization hook, so that subclasses can provide a custom
   * impact flag.  By default, this returns
   * <code>info.getImpact()</code>.
   *
   * @param info the {@link MBeanOperationInfo} instance constructed
   *             via reflection.
   * @return the impact flag to use in the instance.
   */
  protected int getImpact(MBeanOperationInfo info)
  {
    return info.getImpact();
  }

  /**
   * Returns the instance that implements this bean.
   *
   * @return the implementation.
   */
  public Object getImplementation()
  {
    return impl;
  }

  /**
   * Returns the class of the instance that implements this bean.
   *
   * @return the implementation class.
   */
  public Class<?> getImplementationClass()
  {
    return impl.getClass();
  }

  /**
   * <p>
   * Returns an information object which lists the attributes
   * and actions associated with the management bean.  This
   * implementation proceeds as follows:
   * </p>
   * <ol>
   * <li>{@link #getCachedMBeanInfo()} is called to obtain
   * the cached instance.  If this returns a non-null value,
   * this value is returned.</li>
   * <li>If there is no cached value, then the method proceeds
   * to create one. During this process, the customization hooks
   * detailed in this class are called to allow the values used
   * to be overrided:
   * <ul>
   * <li>For each attribute, 
   * {@link #getDescription(MBeanAttributeInfo)} is called.</li>
   * <li>For each constructor,
   * {@link #getDescription(MBeanConstructorInfo)} is called,
   * along with {@link #getDescription(MBeanConstructorInfo,
   * MBeanParameterInfo, int)} and
   * {@link #getParameterName(MBeanConstructorInfo,
   * MBeanParameterInfo, int)} for each parameter.</li>
   * <li>The constructors may be replaced as a whole by
   * a call to
   * {@link #getConstructors(MBeanConstructorInfo[], Object)}.</li>
   * <li>For each operation,
   * {@link #getDescription(MBeanOperationInfo)} and
   * {@link #getImpact(MBeanOperationInfo)} are called,
   * along with {@link #getDescription(MBeanOperationInfo,
   * MBeanParameterInfo, int)} and
   * {@link #getParameterName(MBeanOperationInfo,
   * MBeanParameterInfo, int)} for each parameter.</li>
   * <li>{@link #getClassName(MBeanInfo)} and
   * {@link #getDescription(MBeanInfo)} are called to customise
   * the basic information about the class.</li>
   * </ul>
   * </li>
   * <li>Finally, {@link #cacheMBeanInfo(MBeanInfo)} is called
   * with the created instance before it is returned.</li>
   * </ol>
   *
   * @return a description of the management bean, including
   *         all exposed attributes and actions.
   */
  public MBeanInfo getMBeanInfo()
  {
    MBeanInfo info = getCachedMBeanInfo();
    if (info != null)
      return info;
    Method[] methods = iface.getMethods();
    Map<String,Method[]> attributes = new HashMap<String,Method[]>();
    List<MBeanOperationInfo> operations = new ArrayList<MBeanOperationInfo>();
    for (int a = 0; a < methods.length; ++a)
      {
	String name = methods[a].getName();
	if (((name.startsWith("get") &&
	      methods[a].getReturnType() != Void.TYPE) ||
	     (name.startsWith("is") &&
	      methods[a].getReturnType() == Boolean.TYPE)) &&
	    methods[a].getParameterTypes().length == 0)
	  {
	    Method[] amethods;
	    String attrib;
	    if (name.startsWith("is"))
	      attrib = name.substring(2);
	    else
	      attrib = name.substring(3);
	    if (attributes.containsKey(attrib))
	      amethods = (Method[]) attributes.get(attrib);
	    else
	      {
		amethods = new Method[2];
		attributes.put(attrib, amethods);
	      }
	    amethods[0] = methods[a];
	  }
	else if (name.startsWith("set") &&
		 methods[a].getReturnType() == Void.TYPE &&
		 methods[a].getParameterTypes().length == 1)
	  {
	    Method[] amethods;
	    String attrib = name.substring(3);
	    if (attributes.containsKey(attrib))
	      amethods = (Method[]) attributes.get(attrib);
	    else
	      {
		amethods = new Method[2];
		attributes.put(attrib, amethods);
	      }
	    amethods[1] = methods[a];
	  }
	else
	  operations.add(new MBeanOperationInfo(methods[a].getName(),
						methods[a]));
      }
    List<MBeanAttributeInfo> attribs = new ArrayList<MBeanAttributeInfo>(attributes.size());
    for (Map.Entry<String,Method[]> entry : attributes.entrySet())
      {
	Method[] amethods = entry.getValue();
	try
	  {
	    attribs.add(new MBeanAttributeInfo(entry.getKey(),
					       entry.getKey(),
					       amethods[0], amethods[1]));
	  }
	catch (IntrospectionException e)
	  {
	    /* Shouldn't happen; both shouldn't be null */
	    throw new IllegalStateException("The two methods passed to " +
					    "the MBeanAttributeInfo " +
					    "constructor for " + entry +
					    "were null.", e);
	  }
      }
    MBeanAttributeInfo[] ainfo = new MBeanAttributeInfo[attribs.size()];
    for (int a = 0; a < ainfo.length; ++a)
      {
	MBeanAttributeInfo oldInfo = (MBeanAttributeInfo) attribs.get(a);
	String desc = getDescription(oldInfo);
	ainfo[a] = new MBeanAttributeInfo(oldInfo.getName(),
					  oldInfo.getType(), desc,
					  oldInfo.isReadable(),
					  oldInfo.isWritable(),
					  oldInfo.isIs());
      }
    Constructor<?>[] cons = impl.getClass().getConstructors();
    MBeanConstructorInfo[] cinfo = new MBeanConstructorInfo[cons.length];
    for (int a = 0; a < cinfo.length; ++a)
      {
	MBeanConstructorInfo oldInfo = new MBeanConstructorInfo(cons[a].getName(),
								cons[a]);
	String desc = getDescription(oldInfo);
	MBeanParameterInfo[] params = oldInfo.getSignature();
	MBeanParameterInfo[] pinfo = new MBeanParameterInfo[params.length];
	for (int b = 0; b < pinfo.length; ++b)
	  {
	    String pdesc = getDescription(oldInfo, params[b], b);
	    String pname = getParameterName(oldInfo, params[b], b);
	    pinfo[b] = new MBeanParameterInfo(pname, params[b].getType(),
					      pdesc);
	  }
	cinfo[a] = new MBeanConstructorInfo(oldInfo.getName(), desc,
					    pinfo);
      }
    cinfo = getConstructors(cinfo, impl);
    MBeanOperationInfo[] oinfo = new MBeanOperationInfo[operations.size()];
    for (int a = 0; a < oinfo.length; ++a)
      {
	MBeanOperationInfo oldInfo = (MBeanOperationInfo) operations.get(a);
	String desc = getDescription(oldInfo);
	int impact = getImpact(oldInfo);
	MBeanParameterInfo[] params = oldInfo.getSignature();
	MBeanParameterInfo[] pinfo = new MBeanParameterInfo[params.length];
	for (int b = 0; b < pinfo.length; ++b)
	  {
	    String pdesc = getDescription(oldInfo, params[b], b);
	    String pname = getParameterName(oldInfo, params[b], b);
	    pinfo[b] = new MBeanParameterInfo(pname, params[b].getType(),
					      pdesc);
	  }
	oinfo[a] = new MBeanOperationInfo(oldInfo.getName(), desc, pinfo,
					  oldInfo.getReturnType(), impact);
      }
    info = new MBeanInfo(impl.getClass().getName(), impl.getClass().getName(),
			 ainfo, cinfo, oinfo, null);
    String cname = getClassName(info);
    String desc = getDescription(info);
    MBeanNotificationInfo[] ninfo = null;
    if (impl instanceof NotificationBroadcaster)
      ninfo = ((NotificationBroadcaster) impl).getNotificationInfo();
    info = new MBeanInfo(cname, desc, ainfo, cinfo, oinfo, ninfo);
    cacheMBeanInfo(info);
    return info;
  }

  /**
   * Returns the interface for this management bean.
   *
   * @return the management interface.
   */
  public final Class<?> getMBeanInterface()
  {
    return iface;
  }

  /**
   * Returns the name of the nth parameter of the constructor
   * that will be used in the supplied {@link MBeanParameterInfo}
   * instance.  This is a customization hook, so that subclasses
   * can provide a custom name.  By default, this calls
   * <code>param.getName()</code>.
   *
   * @param info the {@link MBeanConstructorInfo} instance constructed
   *             via reflection.
   * @param param the {@link MBeanParameterInfo} instance constructed
   *             via reflection.
   * @param n the number of the parameter, in order to link it to the
   *          information on the constructor.
   * @return the name to use in the instance.
   */
  protected String getParameterName(MBeanConstructorInfo info,
				    MBeanParameterInfo param, int n)
  {
    return param.getName();
  }

  /**
   * Returns the name of the nth parameter of the operation
   * that will be used in the supplied {@link MBeanParameterInfo}
   * instance.  This is a customization hook, so that subclasses
   * can provide a custom name.  By default, this calls
   * <code>param.getName()</code>.
   *
   * @param info the {@link MBeanOperationInfo} instance constructed
   *             via reflection.
   * @param param the {@link MBeanParameterInfo} instance constructed
   *             via reflection.
   * @param n the number of the parameter, in order to link it to the
   *          information on the operation.
   * @return the name to use in the instance.
   */
  protected String getParameterName(MBeanOperationInfo info,
				    MBeanParameterInfo param, int n)
  {
    return param.getName();
  }

  /**
   * Invokes the specified action on the management bean using
   * the supplied parameters.  The signature of the action is
   * specified by a {@link String} array, which lists the classes
   * corresponding to each parameter.  The class loader used to
   * load these classes is the same as that used for loading the
   * management bean itself.
   * 
   * @param name the name of the action to invoke.
   * @param params the parameters used to call the action.
   * @param signature the signature of the action.
   * @return the return value of the action.
   * @throws MBeanException if the action throws an exception.  The
   *                        thrown exception is the cause of this
   *                        exception.
   * @throws ReflectionException if an exception occurred in trying
   *                             to use the reflection interface
   *                             to invoke the action.  The
   *                             thrown exception is the cause of
   *                             this exception.
   */
  public Object invoke(String name, Object[] params, String[] signature)
    throws MBeanException, ReflectionException
  {
    if (name.startsWith("get") || name.startsWith("is") ||
	name.startsWith("set"))
      throw new ReflectionException(new NoSuchMethodException(),
				    "Invocation of an attribute " +
				    "method is disallowed.");
    ClassLoader loader = getClass().getClassLoader();
    Class<?>[] sigTypes;
    if (signature != null)
      {
	sigTypes = new Class<?>[signature.length];
	for (int a = 0; a < signature.length; ++a)
	  try 
	    {
	      sigTypes[a] = Class.forName(signature[a], true, loader);
	    }
	  catch (ClassNotFoundException e)
	    {
	      throw new ReflectionException(e, "The class, " + signature[a] + 
					    ", in the method signature " +
					    "could not be loaded.");
	    }
      }
    else
      sigTypes = null;
    Method method;
    try
      {
	method = iface.getMethod(name, sigTypes);
      }
    catch (NoSuchMethodException e)
      {
	throw new ReflectionException(e, "The method, " + name +
				      ", could not be found.");
      }
    Object result;
    try
      {
	result = method.invoke(impl, params);
      }
    catch (IllegalAccessException e)
      {
	throw new ReflectionException(e, "Failed to call " + name);
      }
    catch (IllegalArgumentException e)
      {
	throw new ReflectionException(e, "Failed to call " + name);
      }
    catch (InvocationTargetException e)
      {
	throw new MBeanException((Exception) e.getCause(), "The method "
				 + name + " threw an exception");
      }
    return result;
  }

  /**
   * Sets the value of the specified attribute of the
   * management bean.  The management bean should perform
   * a lookup for the named attribute, and sets its value
   * using the associated setter method, if possible.
   *
   * @param attribute the attribute to set.
   * @throws AttributeNotFoundException if the attribute does not
   *                                    correspond to an attribute
   *                                    of the bean.
   * @throws InvalidAttributeValueException if the value is invalid
   *                                        for this particular
   *                                        attribute of the bean.
   * @throws MBeanException if setting the attribute causes
   *                        the bean to throw an exception (which
   *                        becomes the cause of this exception).
   * @throws ReflectionException if an exception occurred in trying
   *                             to use the reflection interface
   *                             to lookup the attribute.  The
   *                             thrown exception is the cause of
   *                             this exception.
   * @see #getAttribute(String)
   */
  public void setAttribute(Attribute attribute)
    throws AttributeNotFoundException, InvalidAttributeValueException,
	   MBeanException, ReflectionException
  {
    String name = attribute.getName();
    String attName = name.substring(0, 1).toUpperCase() + name.substring(1);
    Object val = attribute.getValue();   
    try
      {
	getMutator(attName, val.getClass()).invoke(impl, new Object[] { val });
      }
    catch (IllegalAccessException e)
      {
	throw new ReflectionException(e, "Failed to set " + name);
      }
    catch (IllegalArgumentException e)
      {
	throw ((InvalidAttributeValueException)
	       new InvalidAttributeValueException(attribute.getValue() +
						  " is an invalid value for " +
						  name).initCause(e));
      }
    catch (InvocationTargetException e)
      {
	throw new MBeanException(e, "The getter of " + name +
				 " threw an exception");
      }
  }

  /**
   * Sets the value of each of the specified attributes
   * to that supplied by the {@link Attribute} object.
   * The returned list contains the attributes that were
   * set and their new values.
   *
   * @param attributes the attributes to set.
   * @return a list of the changed attributes.
   * @see #getAttributes(AttributeList)
   */
  public AttributeList setAttributes(AttributeList attributes)
  {
    AttributeList list = new AttributeList(attributes.size());
    Iterator<Object> it = attributes.iterator();
    while (it.hasNext())
      {
	try
	  {
	    Attribute attrib = (Attribute) it.next();
	    setAttribute(attrib);
	    list.add(attrib);
	  }
	catch (AttributeNotFoundException e)
	  {
	    /* Ignored */
	  }
	catch (InvalidAttributeValueException e)
	  {
	    /* Ignored */
	  }
	catch (ReflectionException e)
	  {
	    /* Ignored */
	  }
	catch (MBeanException e)
	  {
	    /* Ignored */
	  }
      }
    return list;
  }

  /**
   * Replaces the implementation of the interface used by this
   * instance with the one specified.  The new implementation
   * must be non-null and implement the interface specified on
   * construction of this instance.
   *
   * @throws IllegalArgumentException if <code>impl</code> is <code>null</code>.
   * @throws NotCompliantMBeanException if <code>impl</code> doesn't implement
   *                                    the interface or a method appears
   *                                    in the interface that doesn't comply
   *                                    with the naming conventions.
   */
  public void setImplementation(Object impl)
    throws NotCompliantMBeanException
  {
    if (impl == null)
      throw new IllegalArgumentException("The specified implementation is null.");
    if (!(iface.isInstance(impl)))
      throw new NotCompliantMBeanException("The instance, " + impl + 
					   ", is not an instance of " + iface);
    this.impl = impl;
  }

  /**
   * Returns the mutator method for a particular attribute name
   * with a parameter type matching that of the given value.
   *
   * @param name the name of the attribute.
   * @param type the type of the parameter.
   * @return the appropriate mutator method.
   * @throws AttributeNotFoundException if a method can't be found.
   */
  private Method getMutator(String name, Class<?> type)
    throws AttributeNotFoundException
  {
    String mutator = "set" + name;
    Exception ex = null;
    try 
      {
	return iface.getMethod(mutator, type);
      }
    catch (NoSuchMethodException e)
      {
	/* Ignored; we'll try harder instead */
	ex = e;
      }
    /* Special cases */
    if (type == Boolean.class)
      try
	{
	  return iface.getMethod(mutator, Boolean.TYPE);
	}
      catch (NoSuchMethodException e)
	{
	  throw ((AttributeNotFoundException) 
		 new AttributeNotFoundException("The attribute, " + name +
						", was not found.").initCause(e));
	}
    if (type == Byte.class)
      try
	{
	  return iface.getMethod(mutator, Byte.TYPE);
	}
      catch (NoSuchMethodException e)
	{
	  throw ((AttributeNotFoundException) 
		 new AttributeNotFoundException("The attribute, " + name +
						", was not found.").initCause(e));
	}
    if (type == Character.class)
      try
	{
	  return iface.getMethod(mutator, Character.TYPE);
	}
      catch (NoSuchMethodException e)
	{
	  throw ((AttributeNotFoundException) 
		 new AttributeNotFoundException("The attribute, " + name +
						", was not found.").initCause(e));
	}
    if (type == Double.class)
      try
	{
	  return iface.getMethod(mutator, Double.TYPE);
	}
      catch (NoSuchMethodException e)
	{
	  throw ((AttributeNotFoundException) 
		 new AttributeNotFoundException("The attribute, " + name +
						", was not found.").initCause(e));
	}
    if (type == Float.class)
      try
	{
	  return iface.getMethod(mutator, Float.TYPE);
	}
      catch (NoSuchMethodException e)
	{
	  throw ((AttributeNotFoundException) 
		 new AttributeNotFoundException("The attribute, " + name +
						", was not found.").initCause(e));
	}
    if (type == Integer.class)
      try
	{
	  return iface.getMethod(mutator, Integer.TYPE);
	}
      catch (NoSuchMethodException e)
	{
	  throw ((AttributeNotFoundException) 
		 new AttributeNotFoundException("The attribute, " + name +
						", was not found.").initCause(e));
	}
    if (type == Long.class)
      try
	{
	  return iface.getMethod(mutator, Long.TYPE);
	}
      catch (NoSuchMethodException e)
	{
	  throw ((AttributeNotFoundException) 
		 new AttributeNotFoundException("The attribute, " + name +
						", was not found.").initCause(e));
	}
    if (type == Short.class)
      try
	{
	  return iface.getMethod(mutator, Short.TYPE);
	}
      catch (NoSuchMethodException e)
	{
	  throw ((AttributeNotFoundException) 
		 new AttributeNotFoundException("The attribute, " + name +
						", was not found.").initCause(e));
	}
    /* Superclasses and interfaces */
    for (Class<?> i : type.getInterfaces())
      try
	{
	  return getMutator(name, i);
	}
      catch (AttributeNotFoundException e)
	{
	  ex = e;
	}
    Class<?> sclass = type.getSuperclass();
    if (sclass != null && sclass != Object.class)
      try
	{
	  return getMutator(name, sclass);
	}
      catch (AttributeNotFoundException e)
	{
	  ex = e;
	}
    /* If we get this far, give up */
    throw ((AttributeNotFoundException) 
	   new AttributeNotFoundException("The attribute, " + name +
					  ", was not found.").initCause(ex)); 
  }

}
