donaldp     2002/09/13 04:29:13

  Added:       baxter/src/java/org/apache/excalibur/baxter
                        MBeanInvocationHandler.java
  Log:
  Add an invocation handler for MBeans. This handler will allow you to proxy 
MBeans as long as they implement all methods in an interface (or set of 
interfaces)
  
  Revision  Changes    Path
  1.1                  
jakarta-avalon-excalibur/baxter/src/java/org/apache/excalibur/baxter/MBeanInvocationHandler.java
  
  Index: MBeanInvocationHandler.java
  ===================================================================
  /*
 * Copyright (C) The Apache Software Foundation. All rights reserved.
 *
 * This software is published under the terms of the Apache Software License
 * version 1.1, a copy of which has been included  with this distribution in
 * the LICENSE.txt file.
 */
package org.apache.excalibur.baxter;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.ReflectionException;

/**
 * An [EMAIL PROTECTED] InvocationHandler} for MBeans.
 * Allows you to invoke MBean as if they were normal objects if
 * they implement all the methods in an interface.
 *
 * @author <a href="mailto:peter at apache.org">Peter Donald</a>
 * @version CVS $Revision: 1.1 $ $Date: 2002/09/13 11:29:13 $
 */
public class MBeanInvocationHandler
    implements InvocationHandler
{
    /**
     * Map of methods onto parameter type arrays.
     */
    private final Map m_methodMap = new HashMap();

    /**
     * The MBeanServer to call methods on.
     */
    private final MBeanServer m_mBeanServer;

    /**
     * The name of object we are to invoke.
     */
    private final ObjectName m_objectName;

    /**
     * Create a Proxy for MBean that implements specified
     * interfaces. It is expected that the MBean as registered
     * will have all of those methods implemented.
     *
     * @param mBeanServer the MBeanServer
     * @param objectName the name of object
     * @param services the service interfaces to proxy
     * @return the proxied MBean
     */
    public static Object createProxy( final MBeanServer mBeanServer,
                                      final ObjectName objectName,
                                      final Class[] services )
    {
        final ClassLoader classLoader =
            MBeanInvocationHandler.class.getClassLoader();
        final MBeanInvocationHandler handler =
            new MBeanInvocationHandler( mBeanServer, objectName );
        return Proxy.newProxyInstance( classLoader, services, handler );
    }

    /**
     * Create InvocationHandler for specified
     * ObjectName on specified MBeanServer.
     *
     * @param mBeanServer the MBeanServer
     * @param objectName the name of object
     */
    public MBeanInvocationHandler( final MBeanServer mBeanServer,
                                   final ObjectName objectName )
    {
        if( null == mBeanServer )
        {
            throw new NullPointerException( "mBeanServer" );
        }
        if( null == objectName )
        {
            throw new NullPointerException( "objectName" );
        }

        m_mBeanServer = mBeanServer;
        m_objectName = objectName;
    }

    /**
     * Return the MBeanServer the InvocationHandler calls methods using.
     *
     * @return the MBeanServer the InvocationHandler calls methods using.
     */
    protected MBeanServer getMBeanServer()
    {
        return m_mBeanServer;
    }

    /**
     * Return the ObjectName designating object to call methods on.
     *
     * @return the ObjectName designating object to call methods on.
     */
    protected ObjectName getObjectName()
    {
        return m_objectName;
    }

    /**
     * Invoke a method on a MBean.
     */
    public Object invoke( final Object proxy,
                          final Method method,
                          final Object[] args )
        throws Throwable
    {
        final String[] paramTypes = getParamTypes( method );
        try
        {
            return getMBeanServer().invoke( getObjectName(),
                                            method.getName(),
                                            args,
                                            paramTypes );
        }
        catch( InstanceNotFoundException e )
        {
            throw new IllegalStateException( e.toString() );
        }
        catch( MBeanException e )
        {
            throw e.getTargetException();
        }
        catch( ReflectionException e )
        {
            throw new IllegalStateException( e.toString() );
        }
    }

    /**
     * Get a list of param types for method.
     */
    private synchronized String[] getParamTypes( final Method method )
    {
        String[] paramTypes = (String[])m_methodMap.get( method );
        if( null == paramTypes )
        {
            paramTypes = calcParamTypes( method );
            m_methodMap.put( method, paramTypes );
        }
        return paramTypes;
    }

    /**
     * Create a list of strings that name types
     * of a methods parameters. This is derived from
     * method object.
     */
    private String[] calcParamTypes( final Method method )
    {
        final Class[] parameterClasses = method.getParameterTypes();
        final String[] paramTypes = new String[ parameterClasses.length ];
        for( int i = 0; i < paramTypes.length; i++ )
        {
            paramTypes[ i ] = parameterClasses[ i ].getName();

        }
        return paramTypes;
    }
}
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to