103928aee4356845252ac6b662d5c72c29903813eJake Slack//
203928aee4356845252ac6b662d5c72c29903813eJake Slack//  ========================================================================
303928aee4356845252ac6b662d5c72c29903813eJake Slack//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
403928aee4356845252ac6b662d5c72c29903813eJake Slack//  ------------------------------------------------------------------------
503928aee4356845252ac6b662d5c72c29903813eJake Slack//  All rights reserved. This program and the accompanying materials
603928aee4356845252ac6b662d5c72c29903813eJake Slack//  are made available under the terms of the Eclipse Public License v1.0
703928aee4356845252ac6b662d5c72c29903813eJake Slack//  and Apache License v2.0 which accompanies this distribution.
803928aee4356845252ac6b662d5c72c29903813eJake Slack//
903928aee4356845252ac6b662d5c72c29903813eJake Slack//      The Eclipse Public License is available at
1003928aee4356845252ac6b662d5c72c29903813eJake Slack//      http://www.eclipse.org/legal/epl-v10.html
1103928aee4356845252ac6b662d5c72c29903813eJake Slack//
1203928aee4356845252ac6b662d5c72c29903813eJake Slack//      The Apache License v2.0 is available at
1303928aee4356845252ac6b662d5c72c29903813eJake Slack//      http://www.opensource.org/licenses/apache2.0.php
1403928aee4356845252ac6b662d5c72c29903813eJake Slack//
1503928aee4356845252ac6b662d5c72c29903813eJake Slack//  You may elect to redistribute this code under either of these licenses.
1603928aee4356845252ac6b662d5c72c29903813eJake Slack//  ========================================================================
1703928aee4356845252ac6b662d5c72c29903813eJake Slack//
1803928aee4356845252ac6b662d5c72c29903813eJake Slack
1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.jmx;
2003928aee4356845252ac6b662d5c72c29903813eJake Slack
2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.lang.reflect.Array;
2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.lang.reflect.Constructor;
2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.lang.reflect.InvocationTargetException;
2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.lang.reflect.Method;
2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.lang.reflect.Modifier;
2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Collection;
2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Enumeration;
2803928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.HashMap;
2903928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.HashSet;
3003928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Iterator;
3103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Locale;
3203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Map;
3303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.MissingResourceException;
3403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.ResourceBundle;
3503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Set;
3603928aee4356845252ac6b662d5c72c29903813eJake Slack
3703928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.Attribute;
3803928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.AttributeList;
3903928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.AttributeNotFoundException;
4003928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.DynamicMBean;
4103928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.InvalidAttributeValueException;
4203928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.MBeanAttributeInfo;
4303928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.MBeanConstructorInfo;
4403928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.MBeanException;
4503928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.MBeanInfo;
4603928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.MBeanNotificationInfo;
4703928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.MBeanOperationInfo;
4803928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.MBeanParameterInfo;
4903928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.ObjectName;
5003928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.ReflectionException;
5103928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.management.modelmbean.ModelMBean;
5203928aee4356845252ac6b662d5c72c29903813eJake Slack
5303928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.LazyList;
5403928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.Loader;
5503928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.TypeUtil;
5603928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Log;
5703928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Logger;
5803928aee4356845252ac6b662d5c72c29903813eJake Slack
5903928aee4356845252ac6b662d5c72c29903813eJake Slack/* ------------------------------------------------------------ */
6003928aee4356845252ac6b662d5c72c29903813eJake Slack/** ObjectMBean.
6103928aee4356845252ac6b662d5c72c29903813eJake Slack * A dynamic MBean that can wrap an arbitary Object instance.
6203928aee4356845252ac6b662d5c72c29903813eJake Slack * the attributes and methods exposed by this bean are controlled by
6303928aee4356845252ac6b662d5c72c29903813eJake Slack * the merge of property bundles discovered by names related to all
6403928aee4356845252ac6b662d5c72c29903813eJake Slack * superclasses and all superinterfaces.
6503928aee4356845252ac6b662d5c72c29903813eJake Slack *
6603928aee4356845252ac6b662d5c72c29903813eJake Slack * Attributes and methods exported may be "Object" and must exist on the
6703928aee4356845252ac6b662d5c72c29903813eJake Slack * wrapped object, or "MBean" and must exist on a subclass of OBjectMBean
6803928aee4356845252ac6b662d5c72c29903813eJake Slack * or "MObject" which exists on the wrapped object, but whose values are
6903928aee4356845252ac6b662d5c72c29903813eJake Slack * converted to MBean object names.
7003928aee4356845252ac6b662d5c72c29903813eJake Slack *
7103928aee4356845252ac6b662d5c72c29903813eJake Slack */
7203928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class ObjectMBean implements DynamicMBean
7303928aee4356845252ac6b662d5c72c29903813eJake Slack{
7403928aee4356845252ac6b662d5c72c29903813eJake Slack    private static final Logger LOG = Log.getLogger(ObjectMBean.class);
7503928aee4356845252ac6b662d5c72c29903813eJake Slack
7603928aee4356845252ac6b662d5c72c29903813eJake Slack    private static Class[] OBJ_ARG = new Class[]{Object.class};
7703928aee4356845252ac6b662d5c72c29903813eJake Slack
7803928aee4356845252ac6b662d5c72c29903813eJake Slack    protected Object _managed;
7903928aee4356845252ac6b662d5c72c29903813eJake Slack    private MBeanInfo _info;
8003928aee4356845252ac6b662d5c72c29903813eJake Slack    private Map _getters=new HashMap();
8103928aee4356845252ac6b662d5c72c29903813eJake Slack    private Map _setters=new HashMap();
8203928aee4356845252ac6b662d5c72c29903813eJake Slack    private Map _methods=new HashMap();
8303928aee4356845252ac6b662d5c72c29903813eJake Slack    private Set _convert=new HashSet();
8403928aee4356845252ac6b662d5c72c29903813eJake Slack    private ClassLoader _loader;
8503928aee4356845252ac6b662d5c72c29903813eJake Slack    private MBeanContainer _mbeanContainer;
8603928aee4356845252ac6b662d5c72c29903813eJake Slack
8703928aee4356845252ac6b662d5c72c29903813eJake Slack    private static String OBJECT_NAME_CLASS = ObjectName.class.getName();
8803928aee4356845252ac6b662d5c72c29903813eJake Slack    private static String OBJECT_NAME_ARRAY_CLASS = ObjectName[].class.getName();
8903928aee4356845252ac6b662d5c72c29903813eJake Slack
9003928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
9103928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
9203928aee4356845252ac6b662d5c72c29903813eJake Slack     * Create MBean for Object. Attempts to create an MBean for the object by searching the package
9303928aee4356845252ac6b662d5c72c29903813eJake Slack     * and class name space. For example an object of the type
9403928aee4356845252ac6b662d5c72c29903813eJake Slack     *
9503928aee4356845252ac6b662d5c72c29903813eJake Slack     * <PRE>
9603928aee4356845252ac6b662d5c72c29903813eJake Slack     * class com.acme.MyClass extends com.acme.util.BaseClass implements com.acme.Iface
9703928aee4356845252ac6b662d5c72c29903813eJake Slack     * </PRE>
9803928aee4356845252ac6b662d5c72c29903813eJake Slack     *
9903928aee4356845252ac6b662d5c72c29903813eJake Slack     * Then this method would look for the following classes:
10003928aee4356845252ac6b662d5c72c29903813eJake Slack     * <UL>
10103928aee4356845252ac6b662d5c72c29903813eJake Slack     * <LI>com.acme.jmx.MyClassMBean
10203928aee4356845252ac6b662d5c72c29903813eJake Slack     * <LI>com.acme.util.jmx.BaseClassMBean
10303928aee4356845252ac6b662d5c72c29903813eJake Slack     * <LI>org.eclipse.jetty.jmx.ObjectMBean
10403928aee4356845252ac6b662d5c72c29903813eJake Slack     * </UL>
10503928aee4356845252ac6b662d5c72c29903813eJake Slack     *
10603928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param o The object
10703928aee4356845252ac6b662d5c72c29903813eJake Slack     * @return A new instance of an MBean for the object or null.
10803928aee4356845252ac6b662d5c72c29903813eJake Slack     */
10903928aee4356845252ac6b662d5c72c29903813eJake Slack    public static Object mbeanFor(Object o)
11003928aee4356845252ac6b662d5c72c29903813eJake Slack    {
11103928aee4356845252ac6b662d5c72c29903813eJake Slack        try
11203928aee4356845252ac6b662d5c72c29903813eJake Slack        {
11303928aee4356845252ac6b662d5c72c29903813eJake Slack            Class oClass = o.getClass();
11403928aee4356845252ac6b662d5c72c29903813eJake Slack            Object mbean = null;
11503928aee4356845252ac6b662d5c72c29903813eJake Slack
11603928aee4356845252ac6b662d5c72c29903813eJake Slack            while (mbean == null && oClass != null)
11703928aee4356845252ac6b662d5c72c29903813eJake Slack            {
11803928aee4356845252ac6b662d5c72c29903813eJake Slack                String pName = oClass.getPackage().getName();
11903928aee4356845252ac6b662d5c72c29903813eJake Slack                String cName = oClass.getName().substring(pName.length() + 1);
12003928aee4356845252ac6b662d5c72c29903813eJake Slack                String mName = pName + ".jmx." + cName + "MBean";
12103928aee4356845252ac6b662d5c72c29903813eJake Slack
12203928aee4356845252ac6b662d5c72c29903813eJake Slack
12303928aee4356845252ac6b662d5c72c29903813eJake Slack                try
12403928aee4356845252ac6b662d5c72c29903813eJake Slack                {
12503928aee4356845252ac6b662d5c72c29903813eJake Slack                    Class mClass = (Object.class.equals(oClass))?oClass=ObjectMBean.class:Loader.loadClass(oClass,mName,true);
12603928aee4356845252ac6b662d5c72c29903813eJake Slack                    if (LOG.isDebugEnabled())
12703928aee4356845252ac6b662d5c72c29903813eJake Slack                        LOG.debug("mbeanFor " + o + " mClass=" + mClass);
12803928aee4356845252ac6b662d5c72c29903813eJake Slack
12903928aee4356845252ac6b662d5c72c29903813eJake Slack                    try
13003928aee4356845252ac6b662d5c72c29903813eJake Slack                    {
13103928aee4356845252ac6b662d5c72c29903813eJake Slack                        Constructor constructor = mClass.getConstructor(OBJ_ARG);
13203928aee4356845252ac6b662d5c72c29903813eJake Slack                        mbean=constructor.newInstance(new Object[]{o});
13303928aee4356845252ac6b662d5c72c29903813eJake Slack                    }
13403928aee4356845252ac6b662d5c72c29903813eJake Slack                    catch(Exception e)
13503928aee4356845252ac6b662d5c72c29903813eJake Slack                    {
13603928aee4356845252ac6b662d5c72c29903813eJake Slack                        LOG.ignore(e);
13703928aee4356845252ac6b662d5c72c29903813eJake Slack                        if (ModelMBean.class.isAssignableFrom(mClass))
13803928aee4356845252ac6b662d5c72c29903813eJake Slack                        {
13903928aee4356845252ac6b662d5c72c29903813eJake Slack                            mbean=mClass.newInstance();
14003928aee4356845252ac6b662d5c72c29903813eJake Slack                            ((ModelMBean)mbean).setManagedResource(o, "objectReference");
14103928aee4356845252ac6b662d5c72c29903813eJake Slack                        }
14203928aee4356845252ac6b662d5c72c29903813eJake Slack                    }
14303928aee4356845252ac6b662d5c72c29903813eJake Slack
14403928aee4356845252ac6b662d5c72c29903813eJake Slack                    if (LOG.isDebugEnabled())
14503928aee4356845252ac6b662d5c72c29903813eJake Slack                        LOG.debug("mbeanFor " + o + " is " + mbean);
14603928aee4356845252ac6b662d5c72c29903813eJake Slack                    return mbean;
14703928aee4356845252ac6b662d5c72c29903813eJake Slack                }
14803928aee4356845252ac6b662d5c72c29903813eJake Slack                catch (ClassNotFoundException e)
14903928aee4356845252ac6b662d5c72c29903813eJake Slack                {
15003928aee4356845252ac6b662d5c72c29903813eJake Slack                    // The code below was modified to fix bugs 332200 and JETTY-1416
15103928aee4356845252ac6b662d5c72c29903813eJake Slack                    // The issue was caused by additional information added to the
15203928aee4356845252ac6b662d5c72c29903813eJake Slack                    // message after the class name when running in Apache Felix,
15303928aee4356845252ac6b662d5c72c29903813eJake Slack                    // as well as before the class name when running in JBoss.
15403928aee4356845252ac6b662d5c72c29903813eJake Slack                    if (e.getMessage().contains(mName))
15503928aee4356845252ac6b662d5c72c29903813eJake Slack                        LOG.ignore(e);
15603928aee4356845252ac6b662d5c72c29903813eJake Slack                    else
15703928aee4356845252ac6b662d5c72c29903813eJake Slack                        LOG.warn(e);
15803928aee4356845252ac6b662d5c72c29903813eJake Slack                }
15903928aee4356845252ac6b662d5c72c29903813eJake Slack                catch (Error e)
16003928aee4356845252ac6b662d5c72c29903813eJake Slack                {
16103928aee4356845252ac6b662d5c72c29903813eJake Slack                    LOG.warn(e);
16203928aee4356845252ac6b662d5c72c29903813eJake Slack                    mbean = null;
16303928aee4356845252ac6b662d5c72c29903813eJake Slack                }
16403928aee4356845252ac6b662d5c72c29903813eJake Slack                catch (Exception e)
16503928aee4356845252ac6b662d5c72c29903813eJake Slack                {
16603928aee4356845252ac6b662d5c72c29903813eJake Slack                    LOG.warn(e);
16703928aee4356845252ac6b662d5c72c29903813eJake Slack                    mbean = null;
16803928aee4356845252ac6b662d5c72c29903813eJake Slack                }
16903928aee4356845252ac6b662d5c72c29903813eJake Slack
17003928aee4356845252ac6b662d5c72c29903813eJake Slack                oClass = oClass.getSuperclass();
17103928aee4356845252ac6b662d5c72c29903813eJake Slack            }
17203928aee4356845252ac6b662d5c72c29903813eJake Slack        }
17303928aee4356845252ac6b662d5c72c29903813eJake Slack        catch (Exception e)
17403928aee4356845252ac6b662d5c72c29903813eJake Slack        {
17503928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.ignore(e);
17603928aee4356845252ac6b662d5c72c29903813eJake Slack        }
17703928aee4356845252ac6b662d5c72c29903813eJake Slack        return null;
17803928aee4356845252ac6b662d5c72c29903813eJake Slack    }
17903928aee4356845252ac6b662d5c72c29903813eJake Slack
18003928aee4356845252ac6b662d5c72c29903813eJake Slack
18103928aee4356845252ac6b662d5c72c29903813eJake Slack    public ObjectMBean(Object managedObject)
18203928aee4356845252ac6b662d5c72c29903813eJake Slack    {
18303928aee4356845252ac6b662d5c72c29903813eJake Slack        _managed = managedObject;
18403928aee4356845252ac6b662d5c72c29903813eJake Slack        _loader = Thread.currentThread().getContextClassLoader();
18503928aee4356845252ac6b662d5c72c29903813eJake Slack    }
18603928aee4356845252ac6b662d5c72c29903813eJake Slack
18703928aee4356845252ac6b662d5c72c29903813eJake Slack    public Object getManagedObject()
18803928aee4356845252ac6b662d5c72c29903813eJake Slack    {
18903928aee4356845252ac6b662d5c72c29903813eJake Slack        return _managed;
19003928aee4356845252ac6b662d5c72c29903813eJake Slack    }
19103928aee4356845252ac6b662d5c72c29903813eJake Slack
19203928aee4356845252ac6b662d5c72c29903813eJake Slack    public ObjectName getObjectName()
19303928aee4356845252ac6b662d5c72c29903813eJake Slack    {
19403928aee4356845252ac6b662d5c72c29903813eJake Slack        return null;
19503928aee4356845252ac6b662d5c72c29903813eJake Slack    }
19603928aee4356845252ac6b662d5c72c29903813eJake Slack
19703928aee4356845252ac6b662d5c72c29903813eJake Slack    public String getObjectContextBasis()
19803928aee4356845252ac6b662d5c72c29903813eJake Slack    {
19903928aee4356845252ac6b662d5c72c29903813eJake Slack        return null;
20003928aee4356845252ac6b662d5c72c29903813eJake Slack    }
20103928aee4356845252ac6b662d5c72c29903813eJake Slack
20203928aee4356845252ac6b662d5c72c29903813eJake Slack    public String getObjectNameBasis()
20303928aee4356845252ac6b662d5c72c29903813eJake Slack    {
20403928aee4356845252ac6b662d5c72c29903813eJake Slack        return null;
20503928aee4356845252ac6b662d5c72c29903813eJake Slack    }
20603928aee4356845252ac6b662d5c72c29903813eJake Slack
20703928aee4356845252ac6b662d5c72c29903813eJake Slack    protected void setMBeanContainer(MBeanContainer container)
20803928aee4356845252ac6b662d5c72c29903813eJake Slack    {
20903928aee4356845252ac6b662d5c72c29903813eJake Slack       this._mbeanContainer = container;
21003928aee4356845252ac6b662d5c72c29903813eJake Slack    }
21103928aee4356845252ac6b662d5c72c29903813eJake Slack
21203928aee4356845252ac6b662d5c72c29903813eJake Slack    public MBeanContainer getMBeanContainer ()
21303928aee4356845252ac6b662d5c72c29903813eJake Slack    {
21403928aee4356845252ac6b662d5c72c29903813eJake Slack        return this._mbeanContainer;
21503928aee4356845252ac6b662d5c72c29903813eJake Slack    }
21603928aee4356845252ac6b662d5c72c29903813eJake Slack
21703928aee4356845252ac6b662d5c72c29903813eJake Slack
21803928aee4356845252ac6b662d5c72c29903813eJake Slack    public MBeanInfo getMBeanInfo()
21903928aee4356845252ac6b662d5c72c29903813eJake Slack    {
22003928aee4356845252ac6b662d5c72c29903813eJake Slack        try
22103928aee4356845252ac6b662d5c72c29903813eJake Slack        {
22203928aee4356845252ac6b662d5c72c29903813eJake Slack            if (_info==null)
22303928aee4356845252ac6b662d5c72c29903813eJake Slack            {
22403928aee4356845252ac6b662d5c72c29903813eJake Slack                // Start with blank lazy lists attributes etc.
22503928aee4356845252ac6b662d5c72c29903813eJake Slack                String desc=null;
22603928aee4356845252ac6b662d5c72c29903813eJake Slack                Object attributes=null;
22703928aee4356845252ac6b662d5c72c29903813eJake Slack                Object constructors=null;
22803928aee4356845252ac6b662d5c72c29903813eJake Slack                Object operations=null;
22903928aee4356845252ac6b662d5c72c29903813eJake Slack                Object notifications=null;
23003928aee4356845252ac6b662d5c72c29903813eJake Slack
23103928aee4356845252ac6b662d5c72c29903813eJake Slack                // Find list of classes that can influence the mbean
23203928aee4356845252ac6b662d5c72c29903813eJake Slack                Class o_class=_managed.getClass();
23303928aee4356845252ac6b662d5c72c29903813eJake Slack                Object influences = findInfluences(null, _managed.getClass());
23403928aee4356845252ac6b662d5c72c29903813eJake Slack
23503928aee4356845252ac6b662d5c72c29903813eJake Slack                // Set to record defined items
23603928aee4356845252ac6b662d5c72c29903813eJake Slack                Set defined=new HashSet();
23703928aee4356845252ac6b662d5c72c29903813eJake Slack
23803928aee4356845252ac6b662d5c72c29903813eJake Slack                // For each influence
23903928aee4356845252ac6b662d5c72c29903813eJake Slack                for (int i=0;i<LazyList.size(influences);i++)
24003928aee4356845252ac6b662d5c72c29903813eJake Slack                {
24103928aee4356845252ac6b662d5c72c29903813eJake Slack                    Class oClass = (Class)LazyList.get(influences, i);
24203928aee4356845252ac6b662d5c72c29903813eJake Slack
24303928aee4356845252ac6b662d5c72c29903813eJake Slack                    // look for a bundle defining methods
24403928aee4356845252ac6b662d5c72c29903813eJake Slack                    if (Object.class.equals(oClass))
24503928aee4356845252ac6b662d5c72c29903813eJake Slack                        oClass=ObjectMBean.class;
24603928aee4356845252ac6b662d5c72c29903813eJake Slack                    String pName = oClass.getPackage().getName();
24703928aee4356845252ac6b662d5c72c29903813eJake Slack                    String cName = oClass.getName().substring(pName.length() + 1);
24803928aee4356845252ac6b662d5c72c29903813eJake Slack                    String rName = pName.replace('.', '/') + "/jmx/" + cName+"-mbean";
24903928aee4356845252ac6b662d5c72c29903813eJake Slack
25003928aee4356845252ac6b662d5c72c29903813eJake Slack                    try
25103928aee4356845252ac6b662d5c72c29903813eJake Slack                    {
25203928aee4356845252ac6b662d5c72c29903813eJake Slack                        LOG.debug(rName);
25303928aee4356845252ac6b662d5c72c29903813eJake Slack                        ResourceBundle bundle = Loader.getResourceBundle(o_class, rName,true,Locale.getDefault());
25403928aee4356845252ac6b662d5c72c29903813eJake Slack
25503928aee4356845252ac6b662d5c72c29903813eJake Slack
25603928aee4356845252ac6b662d5c72c29903813eJake Slack                        // Extract meta data from bundle
25703928aee4356845252ac6b662d5c72c29903813eJake Slack                        Enumeration e = bundle.getKeys();
25803928aee4356845252ac6b662d5c72c29903813eJake Slack                        while (e.hasMoreElements())
25903928aee4356845252ac6b662d5c72c29903813eJake Slack                        {
26003928aee4356845252ac6b662d5c72c29903813eJake Slack                            String key = (String)e.nextElement();
26103928aee4356845252ac6b662d5c72c29903813eJake Slack                            String value = bundle.getString(key);
26203928aee4356845252ac6b662d5c72c29903813eJake Slack
26303928aee4356845252ac6b662d5c72c29903813eJake Slack                            // Determin if key is for mbean , attribute or for operation
26403928aee4356845252ac6b662d5c72c29903813eJake Slack                            if (key.equals(cName))
26503928aee4356845252ac6b662d5c72c29903813eJake Slack                            {
26603928aee4356845252ac6b662d5c72c29903813eJake Slack                                // set the mbean description
26703928aee4356845252ac6b662d5c72c29903813eJake Slack                                if (desc==null)
26803928aee4356845252ac6b662d5c72c29903813eJake Slack                                    desc=value;
26903928aee4356845252ac6b662d5c72c29903813eJake Slack                            }
27003928aee4356845252ac6b662d5c72c29903813eJake Slack                            else if (key.indexOf('(')>0)
27103928aee4356845252ac6b662d5c72c29903813eJake Slack                            {
27203928aee4356845252ac6b662d5c72c29903813eJake Slack                                // define an operation
27303928aee4356845252ac6b662d5c72c29903813eJake Slack                                if (!defined.contains(key) && key.indexOf('[')<0)
27403928aee4356845252ac6b662d5c72c29903813eJake Slack                                {
27503928aee4356845252ac6b662d5c72c29903813eJake Slack                                    defined.add(key);
27603928aee4356845252ac6b662d5c72c29903813eJake Slack                                    operations=LazyList.add(operations,defineOperation(key, value, bundle));
27703928aee4356845252ac6b662d5c72c29903813eJake Slack                                }
27803928aee4356845252ac6b662d5c72c29903813eJake Slack                            }
27903928aee4356845252ac6b662d5c72c29903813eJake Slack                            else
28003928aee4356845252ac6b662d5c72c29903813eJake Slack                            {
28103928aee4356845252ac6b662d5c72c29903813eJake Slack                                // define an attribute
28203928aee4356845252ac6b662d5c72c29903813eJake Slack                                if (!defined.contains(key))
28303928aee4356845252ac6b662d5c72c29903813eJake Slack                                {
28403928aee4356845252ac6b662d5c72c29903813eJake Slack                                    defined.add(key);
28503928aee4356845252ac6b662d5c72c29903813eJake Slack                                    MBeanAttributeInfo info=defineAttribute(key, value);
28603928aee4356845252ac6b662d5c72c29903813eJake Slack                                    if (info!=null)
28703928aee4356845252ac6b662d5c72c29903813eJake Slack                                        attributes=LazyList.add(attributes,info);
28803928aee4356845252ac6b662d5c72c29903813eJake Slack                                }
28903928aee4356845252ac6b662d5c72c29903813eJake Slack                            }
29003928aee4356845252ac6b662d5c72c29903813eJake Slack                        }
29103928aee4356845252ac6b662d5c72c29903813eJake Slack                    }
29203928aee4356845252ac6b662d5c72c29903813eJake Slack                    catch(MissingResourceException e)
29303928aee4356845252ac6b662d5c72c29903813eJake Slack                    {
29403928aee4356845252ac6b662d5c72c29903813eJake Slack                        LOG.ignore(e);
29503928aee4356845252ac6b662d5c72c29903813eJake Slack                    }
29603928aee4356845252ac6b662d5c72c29903813eJake Slack                }
29703928aee4356845252ac6b662d5c72c29903813eJake Slack
29803928aee4356845252ac6b662d5c72c29903813eJake Slack                _info = new MBeanInfo(o_class.getName(),
29903928aee4356845252ac6b662d5c72c29903813eJake Slack                                desc,
30003928aee4356845252ac6b662d5c72c29903813eJake Slack                                (MBeanAttributeInfo[])LazyList.toArray(attributes, MBeanAttributeInfo.class),
30103928aee4356845252ac6b662d5c72c29903813eJake Slack                                (MBeanConstructorInfo[])LazyList.toArray(constructors, MBeanConstructorInfo.class),
30203928aee4356845252ac6b662d5c72c29903813eJake Slack                                (MBeanOperationInfo[])LazyList.toArray(operations, MBeanOperationInfo.class),
30303928aee4356845252ac6b662d5c72c29903813eJake Slack                                (MBeanNotificationInfo[])LazyList.toArray(notifications, MBeanNotificationInfo.class));
30403928aee4356845252ac6b662d5c72c29903813eJake Slack            }
30503928aee4356845252ac6b662d5c72c29903813eJake Slack        }
30603928aee4356845252ac6b662d5c72c29903813eJake Slack        catch(RuntimeException e)
30703928aee4356845252ac6b662d5c72c29903813eJake Slack        {
30803928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.warn(e);
30903928aee4356845252ac6b662d5c72c29903813eJake Slack            throw e;
31003928aee4356845252ac6b662d5c72c29903813eJake Slack        }
31103928aee4356845252ac6b662d5c72c29903813eJake Slack        return _info;
31203928aee4356845252ac6b662d5c72c29903813eJake Slack    }
31303928aee4356845252ac6b662d5c72c29903813eJake Slack
31403928aee4356845252ac6b662d5c72c29903813eJake Slack
31503928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
31603928aee4356845252ac6b662d5c72c29903813eJake Slack    public Object getAttribute(String name) throws AttributeNotFoundException, MBeanException, ReflectionException
31703928aee4356845252ac6b662d5c72c29903813eJake Slack    {
31803928aee4356845252ac6b662d5c72c29903813eJake Slack        Method getter = (Method) _getters.get(name);
31903928aee4356845252ac6b662d5c72c29903813eJake Slack        if (getter == null)
32003928aee4356845252ac6b662d5c72c29903813eJake Slack            throw new AttributeNotFoundException(name);
32103928aee4356845252ac6b662d5c72c29903813eJake Slack        try
32203928aee4356845252ac6b662d5c72c29903813eJake Slack        {
32303928aee4356845252ac6b662d5c72c29903813eJake Slack            Object o = _managed;
32403928aee4356845252ac6b662d5c72c29903813eJake Slack            if (getter.getDeclaringClass().isInstance(this))
32503928aee4356845252ac6b662d5c72c29903813eJake Slack                o = this; // mbean method
32603928aee4356845252ac6b662d5c72c29903813eJake Slack
32703928aee4356845252ac6b662d5c72c29903813eJake Slack            // get the attribute
32803928aee4356845252ac6b662d5c72c29903813eJake Slack            Object r=getter.invoke(o, (java.lang.Object[]) null);
32903928aee4356845252ac6b662d5c72c29903813eJake Slack
33003928aee4356845252ac6b662d5c72c29903813eJake Slack            // convert to ObjectName if need be.
33103928aee4356845252ac6b662d5c72c29903813eJake Slack            if (r!=null && _convert.contains(name))
33203928aee4356845252ac6b662d5c72c29903813eJake Slack            {
33303928aee4356845252ac6b662d5c72c29903813eJake Slack                if (r.getClass().isArray())
33403928aee4356845252ac6b662d5c72c29903813eJake Slack                {
33503928aee4356845252ac6b662d5c72c29903813eJake Slack                    ObjectName[] on = new ObjectName[Array.getLength(r)];
33603928aee4356845252ac6b662d5c72c29903813eJake Slack                    for (int i=0;i<on.length;i++)
33703928aee4356845252ac6b662d5c72c29903813eJake Slack                        on[i]=_mbeanContainer.findMBean(Array.get(r, i));
33803928aee4356845252ac6b662d5c72c29903813eJake Slack                    r=on;
33903928aee4356845252ac6b662d5c72c29903813eJake Slack                }
34003928aee4356845252ac6b662d5c72c29903813eJake Slack                else if (r instanceof Collection<?>)
34103928aee4356845252ac6b662d5c72c29903813eJake Slack                {
34203928aee4356845252ac6b662d5c72c29903813eJake Slack                    Collection<Object> c = (Collection<Object>)r;
34303928aee4356845252ac6b662d5c72c29903813eJake Slack                    ObjectName[] on = new ObjectName[c.size()];
34403928aee4356845252ac6b662d5c72c29903813eJake Slack                    int i=0;
34503928aee4356845252ac6b662d5c72c29903813eJake Slack                    for (Object obj :c)
34603928aee4356845252ac6b662d5c72c29903813eJake Slack                        on[i++]=_mbeanContainer.findMBean(obj);
34703928aee4356845252ac6b662d5c72c29903813eJake Slack                    r=on;
34803928aee4356845252ac6b662d5c72c29903813eJake Slack                }
34903928aee4356845252ac6b662d5c72c29903813eJake Slack                else
35003928aee4356845252ac6b662d5c72c29903813eJake Slack                {
35103928aee4356845252ac6b662d5c72c29903813eJake Slack                    ObjectName mbean = _mbeanContainer.findMBean(r);
35203928aee4356845252ac6b662d5c72c29903813eJake Slack                    if (mbean==null)
35303928aee4356845252ac6b662d5c72c29903813eJake Slack                        return null;
35403928aee4356845252ac6b662d5c72c29903813eJake Slack                    r=mbean;
35503928aee4356845252ac6b662d5c72c29903813eJake Slack                }
35603928aee4356845252ac6b662d5c72c29903813eJake Slack            }
35703928aee4356845252ac6b662d5c72c29903813eJake Slack            return r;
35803928aee4356845252ac6b662d5c72c29903813eJake Slack        }
35903928aee4356845252ac6b662d5c72c29903813eJake Slack        catch (IllegalAccessException e)
36003928aee4356845252ac6b662d5c72c29903813eJake Slack        {
36103928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.warn(Log.EXCEPTION, e);
36203928aee4356845252ac6b662d5c72c29903813eJake Slack            throw new AttributeNotFoundException(e.toString());
36303928aee4356845252ac6b662d5c72c29903813eJake Slack        }
36403928aee4356845252ac6b662d5c72c29903813eJake Slack        catch (InvocationTargetException e)
36503928aee4356845252ac6b662d5c72c29903813eJake Slack        {
36603928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.warn(Log.EXCEPTION, e);
36703928aee4356845252ac6b662d5c72c29903813eJake Slack            throw new ReflectionException(new Exception(e.getCause()));
36803928aee4356845252ac6b662d5c72c29903813eJake Slack        }
36903928aee4356845252ac6b662d5c72c29903813eJake Slack    }
37003928aee4356845252ac6b662d5c72c29903813eJake Slack
37103928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
37203928aee4356845252ac6b662d5c72c29903813eJake Slack    public AttributeList getAttributes(String[] names)
37303928aee4356845252ac6b662d5c72c29903813eJake Slack    {
37403928aee4356845252ac6b662d5c72c29903813eJake Slack        AttributeList results = new AttributeList(names.length);
37503928aee4356845252ac6b662d5c72c29903813eJake Slack        for (int i = 0; i < names.length; i++)
37603928aee4356845252ac6b662d5c72c29903813eJake Slack        {
37703928aee4356845252ac6b662d5c72c29903813eJake Slack            try
37803928aee4356845252ac6b662d5c72c29903813eJake Slack            {
37903928aee4356845252ac6b662d5c72c29903813eJake Slack                results.add(new Attribute(names[i], getAttribute(names[i])));
38003928aee4356845252ac6b662d5c72c29903813eJake Slack            }
38103928aee4356845252ac6b662d5c72c29903813eJake Slack            catch (Exception e)
38203928aee4356845252ac6b662d5c72c29903813eJake Slack            {
38303928aee4356845252ac6b662d5c72c29903813eJake Slack                LOG.warn(Log.EXCEPTION, e);
38403928aee4356845252ac6b662d5c72c29903813eJake Slack            }
38503928aee4356845252ac6b662d5c72c29903813eJake Slack        }
38603928aee4356845252ac6b662d5c72c29903813eJake Slack        return results;
38703928aee4356845252ac6b662d5c72c29903813eJake Slack    }
38803928aee4356845252ac6b662d5c72c29903813eJake Slack
38903928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
39003928aee4356845252ac6b662d5c72c29903813eJake Slack    public void setAttribute(Attribute attr) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException
39103928aee4356845252ac6b662d5c72c29903813eJake Slack    {
39203928aee4356845252ac6b662d5c72c29903813eJake Slack        if (attr == null)
39303928aee4356845252ac6b662d5c72c29903813eJake Slack            return;
39403928aee4356845252ac6b662d5c72c29903813eJake Slack
39503928aee4356845252ac6b662d5c72c29903813eJake Slack        if (LOG.isDebugEnabled())
39603928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.debug("setAttribute " + _managed + ":" +attr.getName() + "=" + attr.getValue());
39703928aee4356845252ac6b662d5c72c29903813eJake Slack        Method setter = (Method) _setters.get(attr.getName());
39803928aee4356845252ac6b662d5c72c29903813eJake Slack        if (setter == null)
39903928aee4356845252ac6b662d5c72c29903813eJake Slack            throw new AttributeNotFoundException(attr.getName());
40003928aee4356845252ac6b662d5c72c29903813eJake Slack        try
40103928aee4356845252ac6b662d5c72c29903813eJake Slack        {
40203928aee4356845252ac6b662d5c72c29903813eJake Slack            Object o = _managed;
40303928aee4356845252ac6b662d5c72c29903813eJake Slack            if (setter.getDeclaringClass().isInstance(this))
40403928aee4356845252ac6b662d5c72c29903813eJake Slack                o = this;
40503928aee4356845252ac6b662d5c72c29903813eJake Slack
40603928aee4356845252ac6b662d5c72c29903813eJake Slack            // get the value
40703928aee4356845252ac6b662d5c72c29903813eJake Slack            Object value = attr.getValue();
40803928aee4356845252ac6b662d5c72c29903813eJake Slack
40903928aee4356845252ac6b662d5c72c29903813eJake Slack            // convert from ObjectName if need be
41003928aee4356845252ac6b662d5c72c29903813eJake Slack            if (value!=null && _convert.contains(attr.getName()))
41103928aee4356845252ac6b662d5c72c29903813eJake Slack            {
41203928aee4356845252ac6b662d5c72c29903813eJake Slack                if (value.getClass().isArray())
41303928aee4356845252ac6b662d5c72c29903813eJake Slack                {
41403928aee4356845252ac6b662d5c72c29903813eJake Slack                    Class t=setter.getParameterTypes()[0].getComponentType();
41503928aee4356845252ac6b662d5c72c29903813eJake Slack                    Object na = Array.newInstance(t,Array.getLength(value));
41603928aee4356845252ac6b662d5c72c29903813eJake Slack                    for (int i=Array.getLength(value);i-->0;)
41703928aee4356845252ac6b662d5c72c29903813eJake Slack                        Array.set(na, i, _mbeanContainer.findBean((ObjectName)Array.get(value, i)));
41803928aee4356845252ac6b662d5c72c29903813eJake Slack                    value=na;
41903928aee4356845252ac6b662d5c72c29903813eJake Slack                }
42003928aee4356845252ac6b662d5c72c29903813eJake Slack                else
42103928aee4356845252ac6b662d5c72c29903813eJake Slack                    value=_mbeanContainer.findBean((ObjectName)value);
42203928aee4356845252ac6b662d5c72c29903813eJake Slack            }
42303928aee4356845252ac6b662d5c72c29903813eJake Slack
42403928aee4356845252ac6b662d5c72c29903813eJake Slack            // do the setting
42503928aee4356845252ac6b662d5c72c29903813eJake Slack            setter.invoke(o, new Object[]{ value });
42603928aee4356845252ac6b662d5c72c29903813eJake Slack        }
42703928aee4356845252ac6b662d5c72c29903813eJake Slack        catch (IllegalAccessException e)
42803928aee4356845252ac6b662d5c72c29903813eJake Slack        {
42903928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.warn(Log.EXCEPTION, e);
43003928aee4356845252ac6b662d5c72c29903813eJake Slack            throw new AttributeNotFoundException(e.toString());
43103928aee4356845252ac6b662d5c72c29903813eJake Slack        }
43203928aee4356845252ac6b662d5c72c29903813eJake Slack        catch (InvocationTargetException e)
43303928aee4356845252ac6b662d5c72c29903813eJake Slack        {
43403928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.warn(Log.EXCEPTION, e);
43503928aee4356845252ac6b662d5c72c29903813eJake Slack            throw new ReflectionException(new Exception(e.getCause()));
43603928aee4356845252ac6b662d5c72c29903813eJake Slack        }
43703928aee4356845252ac6b662d5c72c29903813eJake Slack    }
43803928aee4356845252ac6b662d5c72c29903813eJake Slack
43903928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
44003928aee4356845252ac6b662d5c72c29903813eJake Slack    public AttributeList setAttributes(AttributeList attrs)
44103928aee4356845252ac6b662d5c72c29903813eJake Slack    {
44203928aee4356845252ac6b662d5c72c29903813eJake Slack        LOG.debug("setAttributes");
44303928aee4356845252ac6b662d5c72c29903813eJake Slack
44403928aee4356845252ac6b662d5c72c29903813eJake Slack        AttributeList results = new AttributeList(attrs.size());
44503928aee4356845252ac6b662d5c72c29903813eJake Slack        Iterator iter = attrs.iterator();
44603928aee4356845252ac6b662d5c72c29903813eJake Slack        while (iter.hasNext())
44703928aee4356845252ac6b662d5c72c29903813eJake Slack        {
44803928aee4356845252ac6b662d5c72c29903813eJake Slack            try
44903928aee4356845252ac6b662d5c72c29903813eJake Slack            {
45003928aee4356845252ac6b662d5c72c29903813eJake Slack                Attribute attr = (Attribute) iter.next();
45103928aee4356845252ac6b662d5c72c29903813eJake Slack                setAttribute(attr);
45203928aee4356845252ac6b662d5c72c29903813eJake Slack                results.add(new Attribute(attr.getName(), getAttribute(attr.getName())));
45303928aee4356845252ac6b662d5c72c29903813eJake Slack            }
45403928aee4356845252ac6b662d5c72c29903813eJake Slack            catch (Exception e)
45503928aee4356845252ac6b662d5c72c29903813eJake Slack            {
45603928aee4356845252ac6b662d5c72c29903813eJake Slack                LOG.warn(Log.EXCEPTION, e);
45703928aee4356845252ac6b662d5c72c29903813eJake Slack            }
45803928aee4356845252ac6b662d5c72c29903813eJake Slack        }
45903928aee4356845252ac6b662d5c72c29903813eJake Slack        return results;
46003928aee4356845252ac6b662d5c72c29903813eJake Slack    }
46103928aee4356845252ac6b662d5c72c29903813eJake Slack
46203928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
46303928aee4356845252ac6b662d5c72c29903813eJake Slack    public Object invoke(String name, Object[] params, String[] signature) throws MBeanException, ReflectionException
46403928aee4356845252ac6b662d5c72c29903813eJake Slack    {
46503928aee4356845252ac6b662d5c72c29903813eJake Slack        if (LOG.isDebugEnabled())
46603928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.debug("invoke " + name);
46703928aee4356845252ac6b662d5c72c29903813eJake Slack
46803928aee4356845252ac6b662d5c72c29903813eJake Slack        String methodKey = name + "(";
46903928aee4356845252ac6b662d5c72c29903813eJake Slack        if (signature != null)
47003928aee4356845252ac6b662d5c72c29903813eJake Slack            for (int i = 0; i < signature.length; i++)
47103928aee4356845252ac6b662d5c72c29903813eJake Slack                methodKey += (i > 0 ? "," : "") + signature[i];
47203928aee4356845252ac6b662d5c72c29903813eJake Slack        methodKey += ")";
47303928aee4356845252ac6b662d5c72c29903813eJake Slack
47403928aee4356845252ac6b662d5c72c29903813eJake Slack        ClassLoader old_loader=Thread.currentThread().getContextClassLoader();
47503928aee4356845252ac6b662d5c72c29903813eJake Slack        try
47603928aee4356845252ac6b662d5c72c29903813eJake Slack        {
47703928aee4356845252ac6b662d5c72c29903813eJake Slack            Thread.currentThread().setContextClassLoader(_loader);
47803928aee4356845252ac6b662d5c72c29903813eJake Slack            Method method = (Method) _methods.get(methodKey);
47903928aee4356845252ac6b662d5c72c29903813eJake Slack            if (method == null)
48003928aee4356845252ac6b662d5c72c29903813eJake Slack                throw new NoSuchMethodException(methodKey);
48103928aee4356845252ac6b662d5c72c29903813eJake Slack
48203928aee4356845252ac6b662d5c72c29903813eJake Slack            Object o = _managed;
48303928aee4356845252ac6b662d5c72c29903813eJake Slack            if (method.getDeclaringClass().isInstance(this))
48403928aee4356845252ac6b662d5c72c29903813eJake Slack                o = this;
48503928aee4356845252ac6b662d5c72c29903813eJake Slack            return method.invoke(o, params);
48603928aee4356845252ac6b662d5c72c29903813eJake Slack        }
48703928aee4356845252ac6b662d5c72c29903813eJake Slack        catch (NoSuchMethodException e)
48803928aee4356845252ac6b662d5c72c29903813eJake Slack        {
48903928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.warn(Log.EXCEPTION, e);
49003928aee4356845252ac6b662d5c72c29903813eJake Slack            throw new ReflectionException(e);
49103928aee4356845252ac6b662d5c72c29903813eJake Slack        }
49203928aee4356845252ac6b662d5c72c29903813eJake Slack        catch (IllegalAccessException e)
49303928aee4356845252ac6b662d5c72c29903813eJake Slack        {
49403928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.warn(Log.EXCEPTION, e);
49503928aee4356845252ac6b662d5c72c29903813eJake Slack            throw new MBeanException(e);
49603928aee4356845252ac6b662d5c72c29903813eJake Slack        }
49703928aee4356845252ac6b662d5c72c29903813eJake Slack        catch (InvocationTargetException e)
49803928aee4356845252ac6b662d5c72c29903813eJake Slack        {
49903928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.warn(Log.EXCEPTION, e);
50003928aee4356845252ac6b662d5c72c29903813eJake Slack            throw new ReflectionException(new Exception(e.getCause()));
50103928aee4356845252ac6b662d5c72c29903813eJake Slack        }
50203928aee4356845252ac6b662d5c72c29903813eJake Slack        finally
50303928aee4356845252ac6b662d5c72c29903813eJake Slack        {
50403928aee4356845252ac6b662d5c72c29903813eJake Slack            Thread.currentThread().setContextClassLoader(old_loader);
50503928aee4356845252ac6b662d5c72c29903813eJake Slack        }
50603928aee4356845252ac6b662d5c72c29903813eJake Slack    }
50703928aee4356845252ac6b662d5c72c29903813eJake Slack
50803928aee4356845252ac6b662d5c72c29903813eJake Slack    private static Object findInfluences(Object influences, Class aClass)
50903928aee4356845252ac6b662d5c72c29903813eJake Slack    {
51003928aee4356845252ac6b662d5c72c29903813eJake Slack        if (aClass!=null)
51103928aee4356845252ac6b662d5c72c29903813eJake Slack        {
51203928aee4356845252ac6b662d5c72c29903813eJake Slack            // This class is an influence
51303928aee4356845252ac6b662d5c72c29903813eJake Slack            influences=LazyList.add(influences,aClass);
51403928aee4356845252ac6b662d5c72c29903813eJake Slack
51503928aee4356845252ac6b662d5c72c29903813eJake Slack            // So are the super classes
51603928aee4356845252ac6b662d5c72c29903813eJake Slack            influences=findInfluences(influences,aClass.getSuperclass());
51703928aee4356845252ac6b662d5c72c29903813eJake Slack
51803928aee4356845252ac6b662d5c72c29903813eJake Slack            // So are the interfaces
51903928aee4356845252ac6b662d5c72c29903813eJake Slack            Class[] ifs = aClass.getInterfaces();
52003928aee4356845252ac6b662d5c72c29903813eJake Slack            for (int i=0;ifs!=null && i<ifs.length;i++)
52103928aee4356845252ac6b662d5c72c29903813eJake Slack                influences=findInfluences(influences,ifs[i]);
52203928aee4356845252ac6b662d5c72c29903813eJake Slack        }
52303928aee4356845252ac6b662d5c72c29903813eJake Slack        return influences;
52403928aee4356845252ac6b662d5c72c29903813eJake Slack    }
52503928aee4356845252ac6b662d5c72c29903813eJake Slack
52603928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
52703928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
52803928aee4356845252ac6b662d5c72c29903813eJake Slack     * Define an attribute on the managed object. The meta data is defined by looking for standard
52903928aee4356845252ac6b662d5c72c29903813eJake Slack     * getter and setter methods. Descriptions are obtained with a call to findDescription with the
53003928aee4356845252ac6b662d5c72c29903813eJake Slack     * attribute name.
53103928aee4356845252ac6b662d5c72c29903813eJake Slack     *
53203928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param name
53303928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param metaData "description" or "access:description" or "type:access:description"  where type is
53403928aee4356845252ac6b662d5c72c29903813eJake Slack     * one of: <ul>
53503928aee4356845252ac6b662d5c72c29903813eJake Slack     * <li>"Object" The field/method is on the managed object.
53603928aee4356845252ac6b662d5c72c29903813eJake Slack     * <li>"MBean" The field/method is on the mbean proxy object
53703928aee4356845252ac6b662d5c72c29903813eJake Slack     * <li>"MObject" The field/method is on the managed object and value should be converted to MBean reference
53803928aee4356845252ac6b662d5c72c29903813eJake Slack     * <li>"MMBean" The field/method is on the mbean proxy object and value should be converted to MBean reference
53903928aee4356845252ac6b662d5c72c29903813eJake Slack     * </ul>
54003928aee4356845252ac6b662d5c72c29903813eJake Slack     * the access is either "RW" or "RO".
54103928aee4356845252ac6b662d5c72c29903813eJake Slack     */
54203928aee4356845252ac6b662d5c72c29903813eJake Slack    public MBeanAttributeInfo defineAttribute(String name, String metaData)
54303928aee4356845252ac6b662d5c72c29903813eJake Slack    {
54403928aee4356845252ac6b662d5c72c29903813eJake Slack        String description = "";
54503928aee4356845252ac6b662d5c72c29903813eJake Slack        boolean writable = true;
54603928aee4356845252ac6b662d5c72c29903813eJake Slack        boolean onMBean = false;
54703928aee4356845252ac6b662d5c72c29903813eJake Slack        boolean convert = false;
54803928aee4356845252ac6b662d5c72c29903813eJake Slack
54903928aee4356845252ac6b662d5c72c29903813eJake Slack        if (metaData!= null)
55003928aee4356845252ac6b662d5c72c29903813eJake Slack        {
55103928aee4356845252ac6b662d5c72c29903813eJake Slack            String[] tokens = metaData.split(":", 3);
55203928aee4356845252ac6b662d5c72c29903813eJake Slack            for (int t=0;t<tokens.length-1;t++)
55303928aee4356845252ac6b662d5c72c29903813eJake Slack            {
55403928aee4356845252ac6b662d5c72c29903813eJake Slack                tokens[t]=tokens[t].trim();
55503928aee4356845252ac6b662d5c72c29903813eJake Slack                if ("RO".equals(tokens[t]))
55603928aee4356845252ac6b662d5c72c29903813eJake Slack                    writable=false;
55703928aee4356845252ac6b662d5c72c29903813eJake Slack                else
55803928aee4356845252ac6b662d5c72c29903813eJake Slack                {
55903928aee4356845252ac6b662d5c72c29903813eJake Slack                    onMBean=("MMBean".equalsIgnoreCase(tokens[t]) || "MBean".equalsIgnoreCase(tokens[t]));
56003928aee4356845252ac6b662d5c72c29903813eJake Slack                    convert=("MMBean".equalsIgnoreCase(tokens[t]) || "MObject".equalsIgnoreCase(tokens[t]));
56103928aee4356845252ac6b662d5c72c29903813eJake Slack                }
56203928aee4356845252ac6b662d5c72c29903813eJake Slack            }
56303928aee4356845252ac6b662d5c72c29903813eJake Slack            description=tokens[tokens.length-1];
56403928aee4356845252ac6b662d5c72c29903813eJake Slack        }
56503928aee4356845252ac6b662d5c72c29903813eJake Slack
56603928aee4356845252ac6b662d5c72c29903813eJake Slack
56703928aee4356845252ac6b662d5c72c29903813eJake Slack        String uName = name.substring(0, 1).toUpperCase(Locale.ENGLISH) + name.substring(1);
56803928aee4356845252ac6b662d5c72c29903813eJake Slack        Class oClass = onMBean ? this.getClass() : _managed.getClass();
56903928aee4356845252ac6b662d5c72c29903813eJake Slack
57003928aee4356845252ac6b662d5c72c29903813eJake Slack        if (LOG.isDebugEnabled())
57103928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.debug("defineAttribute "+name+" "+onMBean+":"+writable+":"+oClass+":"+description);
57203928aee4356845252ac6b662d5c72c29903813eJake Slack
57303928aee4356845252ac6b662d5c72c29903813eJake Slack        Class type = null;
57403928aee4356845252ac6b662d5c72c29903813eJake Slack        Method getter = null;
57503928aee4356845252ac6b662d5c72c29903813eJake Slack        Method setter = null;
57603928aee4356845252ac6b662d5c72c29903813eJake Slack        Method[] methods = oClass.getMethods();
57703928aee4356845252ac6b662d5c72c29903813eJake Slack        for (int m = 0; m < methods.length; m++)
57803928aee4356845252ac6b662d5c72c29903813eJake Slack        {
57903928aee4356845252ac6b662d5c72c29903813eJake Slack            if ((methods[m].getModifiers() & Modifier.PUBLIC) == 0)
58003928aee4356845252ac6b662d5c72c29903813eJake Slack                continue;
58103928aee4356845252ac6b662d5c72c29903813eJake Slack
58203928aee4356845252ac6b662d5c72c29903813eJake Slack            // Look for a getter
58303928aee4356845252ac6b662d5c72c29903813eJake Slack            if (methods[m].getName().equals("get" + uName) && methods[m].getParameterTypes().length == 0)
58403928aee4356845252ac6b662d5c72c29903813eJake Slack            {
58503928aee4356845252ac6b662d5c72c29903813eJake Slack                if (getter != null)
58603928aee4356845252ac6b662d5c72c29903813eJake Slack                {
58703928aee4356845252ac6b662d5c72c29903813eJake Slack		    LOG.warn("Multiple mbean getters for attr " + name+ " in "+oClass);
58803928aee4356845252ac6b662d5c72c29903813eJake Slack		    continue;
58903928aee4356845252ac6b662d5c72c29903813eJake Slack		}
59003928aee4356845252ac6b662d5c72c29903813eJake Slack                getter = methods[m];
59103928aee4356845252ac6b662d5c72c29903813eJake Slack                if (type != null && !type.equals(methods[m].getReturnType()))
59203928aee4356845252ac6b662d5c72c29903813eJake Slack                {
59303928aee4356845252ac6b662d5c72c29903813eJake Slack		    LOG.warn("Type conflict for mbean attr " + name+ " in "+oClass);
59403928aee4356845252ac6b662d5c72c29903813eJake Slack		    continue;
59503928aee4356845252ac6b662d5c72c29903813eJake Slack		}
59603928aee4356845252ac6b662d5c72c29903813eJake Slack                type = methods[m].getReturnType();
59703928aee4356845252ac6b662d5c72c29903813eJake Slack            }
59803928aee4356845252ac6b662d5c72c29903813eJake Slack
59903928aee4356845252ac6b662d5c72c29903813eJake Slack            // Look for an is getter
60003928aee4356845252ac6b662d5c72c29903813eJake Slack            if (methods[m].getName().equals("is" + uName) && methods[m].getParameterTypes().length == 0)
60103928aee4356845252ac6b662d5c72c29903813eJake Slack            {
60203928aee4356845252ac6b662d5c72c29903813eJake Slack                if (getter != null)
60303928aee4356845252ac6b662d5c72c29903813eJake Slack                {
60403928aee4356845252ac6b662d5c72c29903813eJake Slack		    LOG.warn("Multiple mbean getters for attr " + name+ " in "+oClass);
60503928aee4356845252ac6b662d5c72c29903813eJake Slack		    continue;
60603928aee4356845252ac6b662d5c72c29903813eJake Slack		}
60703928aee4356845252ac6b662d5c72c29903813eJake Slack                getter = methods[m];
60803928aee4356845252ac6b662d5c72c29903813eJake Slack                if (type != null && !type.equals(methods[m].getReturnType()))
60903928aee4356845252ac6b662d5c72c29903813eJake Slack                {
61003928aee4356845252ac6b662d5c72c29903813eJake Slack		    LOG.warn("Type conflict for mbean attr " + name+ " in "+oClass);
61103928aee4356845252ac6b662d5c72c29903813eJake Slack		    continue;
61203928aee4356845252ac6b662d5c72c29903813eJake Slack		}
61303928aee4356845252ac6b662d5c72c29903813eJake Slack                type = methods[m].getReturnType();
61403928aee4356845252ac6b662d5c72c29903813eJake Slack            }
61503928aee4356845252ac6b662d5c72c29903813eJake Slack
61603928aee4356845252ac6b662d5c72c29903813eJake Slack            // look for a setter
61703928aee4356845252ac6b662d5c72c29903813eJake Slack            if (writable && methods[m].getName().equals("set" + uName) && methods[m].getParameterTypes().length == 1)
61803928aee4356845252ac6b662d5c72c29903813eJake Slack            {
61903928aee4356845252ac6b662d5c72c29903813eJake Slack                if (setter != null)
62003928aee4356845252ac6b662d5c72c29903813eJake Slack                {
62103928aee4356845252ac6b662d5c72c29903813eJake Slack		    LOG.warn("Multiple setters for mbean attr " + name+ " in "+oClass);
62203928aee4356845252ac6b662d5c72c29903813eJake Slack		    continue;
62303928aee4356845252ac6b662d5c72c29903813eJake Slack		}
62403928aee4356845252ac6b662d5c72c29903813eJake Slack                setter = methods[m];
62503928aee4356845252ac6b662d5c72c29903813eJake Slack                if (type != null && !type.equals(methods[m].getParameterTypes()[0]))
62603928aee4356845252ac6b662d5c72c29903813eJake Slack                {
62703928aee4356845252ac6b662d5c72c29903813eJake Slack		    LOG.warn("Type conflict for mbean attr " + name+ " in "+oClass);
62803928aee4356845252ac6b662d5c72c29903813eJake Slack		    continue;
62903928aee4356845252ac6b662d5c72c29903813eJake Slack		}
63003928aee4356845252ac6b662d5c72c29903813eJake Slack                type = methods[m].getParameterTypes()[0];
63103928aee4356845252ac6b662d5c72c29903813eJake Slack            }
63203928aee4356845252ac6b662d5c72c29903813eJake Slack        }
63303928aee4356845252ac6b662d5c72c29903813eJake Slack
63403928aee4356845252ac6b662d5c72c29903813eJake Slack        if (convert)
63503928aee4356845252ac6b662d5c72c29903813eJake Slack        {
63603928aee4356845252ac6b662d5c72c29903813eJake Slack            if (type==null)
63703928aee4356845252ac6b662d5c72c29903813eJake Slack            {
63803928aee4356845252ac6b662d5c72c29903813eJake Slack	        LOG.warn("No mbean type for " + name+" on "+_managed.getClass());
63903928aee4356845252ac6b662d5c72c29903813eJake Slack		return null;
64003928aee4356845252ac6b662d5c72c29903813eJake Slack	    }
64103928aee4356845252ac6b662d5c72c29903813eJake Slack
64203928aee4356845252ac6b662d5c72c29903813eJake Slack            if (type.isPrimitive() && !type.isArray())
64303928aee4356845252ac6b662d5c72c29903813eJake Slack            {
64403928aee4356845252ac6b662d5c72c29903813eJake Slack	        LOG.warn("Cannot convert mbean primative " + name);
64503928aee4356845252ac6b662d5c72c29903813eJake Slack		return null;
64603928aee4356845252ac6b662d5c72c29903813eJake Slack	    }
64703928aee4356845252ac6b662d5c72c29903813eJake Slack        }
64803928aee4356845252ac6b662d5c72c29903813eJake Slack
64903928aee4356845252ac6b662d5c72c29903813eJake Slack        if (getter == null && setter == null)
65003928aee4356845252ac6b662d5c72c29903813eJake Slack        {
65103928aee4356845252ac6b662d5c72c29903813eJake Slack	    LOG.warn("No mbean getter or setters found for " + name+ " in "+oClass);
65203928aee4356845252ac6b662d5c72c29903813eJake Slack	    return null;
65303928aee4356845252ac6b662d5c72c29903813eJake Slack	}
65403928aee4356845252ac6b662d5c72c29903813eJake Slack
65503928aee4356845252ac6b662d5c72c29903813eJake Slack        try
65603928aee4356845252ac6b662d5c72c29903813eJake Slack        {
65703928aee4356845252ac6b662d5c72c29903813eJake Slack            // Remember the methods
65803928aee4356845252ac6b662d5c72c29903813eJake Slack            _getters.put(name, getter);
65903928aee4356845252ac6b662d5c72c29903813eJake Slack            _setters.put(name, setter);
66003928aee4356845252ac6b662d5c72c29903813eJake Slack
66103928aee4356845252ac6b662d5c72c29903813eJake Slack            MBeanAttributeInfo info=null;
66203928aee4356845252ac6b662d5c72c29903813eJake Slack            if (convert)
66303928aee4356845252ac6b662d5c72c29903813eJake Slack            {
66403928aee4356845252ac6b662d5c72c29903813eJake Slack                _convert.add(name);
66503928aee4356845252ac6b662d5c72c29903813eJake Slack                if (type.isArray())
66603928aee4356845252ac6b662d5c72c29903813eJake Slack                    info= new MBeanAttributeInfo(name,OBJECT_NAME_ARRAY_CLASS,description,getter!=null,setter!=null,getter!=null&&getter.getName().startsWith("is"));
66703928aee4356845252ac6b662d5c72c29903813eJake Slack
66803928aee4356845252ac6b662d5c72c29903813eJake Slack                else
66903928aee4356845252ac6b662d5c72c29903813eJake Slack                    info= new MBeanAttributeInfo(name,OBJECT_NAME_CLASS,description,getter!=null,setter!=null,getter!=null&&getter.getName().startsWith("is"));
67003928aee4356845252ac6b662d5c72c29903813eJake Slack            }
67103928aee4356845252ac6b662d5c72c29903813eJake Slack            else
67203928aee4356845252ac6b662d5c72c29903813eJake Slack                info= new MBeanAttributeInfo(name,description,getter,setter);
67303928aee4356845252ac6b662d5c72c29903813eJake Slack
67403928aee4356845252ac6b662d5c72c29903813eJake Slack            return info;
67503928aee4356845252ac6b662d5c72c29903813eJake Slack        }
67603928aee4356845252ac6b662d5c72c29903813eJake Slack        catch (Exception e)
67703928aee4356845252ac6b662d5c72c29903813eJake Slack        {
67803928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.warn(name+": "+metaData, e);
67903928aee4356845252ac6b662d5c72c29903813eJake Slack            throw new IllegalArgumentException(e.toString());
68003928aee4356845252ac6b662d5c72c29903813eJake Slack        }
68103928aee4356845252ac6b662d5c72c29903813eJake Slack    }
68203928aee4356845252ac6b662d5c72c29903813eJake Slack
68303928aee4356845252ac6b662d5c72c29903813eJake Slack
68403928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
68503928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
68603928aee4356845252ac6b662d5c72c29903813eJake Slack     * Define an operation on the managed object. Defines an operation with parameters. Refection is
68703928aee4356845252ac6b662d5c72c29903813eJake Slack     * used to determine find the method and it's return type. The description of the method is
68803928aee4356845252ac6b662d5c72c29903813eJake Slack     * found with a call to findDescription on "name(signature)". The name and description of each
68903928aee4356845252ac6b662d5c72c29903813eJake Slack     * parameter is found with a call to findDescription with "name(signature)[n]", the returned
69003928aee4356845252ac6b662d5c72c29903813eJake Slack     * description is for the last parameter of the partial signature and is assumed to start with
69103928aee4356845252ac6b662d5c72c29903813eJake Slack     * the parameter name, followed by a colon.
69203928aee4356845252ac6b662d5c72c29903813eJake Slack     *
69303928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param metaData "description" or "impact:description" or "type:impact:description", type is
69403928aee4356845252ac6b662d5c72c29903813eJake Slack     * the "Object","MBean", "MMBean" or "MObject" to indicate the method is on the object, the MBean or on the
69503928aee4356845252ac6b662d5c72c29903813eJake Slack     * object but converted to an MBean reference, and impact is either "ACTION","INFO","ACTION_INFO" or "UNKNOWN".
69603928aee4356845252ac6b662d5c72c29903813eJake Slack     */
69703928aee4356845252ac6b662d5c72c29903813eJake Slack    private MBeanOperationInfo defineOperation(String signature, String metaData, ResourceBundle bundle)
69803928aee4356845252ac6b662d5c72c29903813eJake Slack    {
69903928aee4356845252ac6b662d5c72c29903813eJake Slack        String[] tokens=metaData.split(":",3);
70003928aee4356845252ac6b662d5c72c29903813eJake Slack        int i=tokens.length-1;
70103928aee4356845252ac6b662d5c72c29903813eJake Slack        String description=tokens[i--];
70203928aee4356845252ac6b662d5c72c29903813eJake Slack        String impact_name = i<0?"UNKNOWN":tokens[i--].trim();
70303928aee4356845252ac6b662d5c72c29903813eJake Slack        if (i==0)
70403928aee4356845252ac6b662d5c72c29903813eJake Slack            tokens[0]=tokens[0].trim();
70503928aee4356845252ac6b662d5c72c29903813eJake Slack        boolean onMBean= i==0 && ("MBean".equalsIgnoreCase(tokens[0])||"MMBean".equalsIgnoreCase(tokens[0]));
70603928aee4356845252ac6b662d5c72c29903813eJake Slack        boolean convert= i==0 && ("MObject".equalsIgnoreCase(tokens[0])||"MMBean".equalsIgnoreCase(tokens[0]));
70703928aee4356845252ac6b662d5c72c29903813eJake Slack
70803928aee4356845252ac6b662d5c72c29903813eJake Slack        if (LOG.isDebugEnabled())
70903928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.debug("defineOperation "+signature+" "+onMBean+":"+impact_name+":"+description);
71003928aee4356845252ac6b662d5c72c29903813eJake Slack
71103928aee4356845252ac6b662d5c72c29903813eJake Slack        Class oClass = onMBean ? this.getClass() : _managed.getClass();
71203928aee4356845252ac6b662d5c72c29903813eJake Slack
71303928aee4356845252ac6b662d5c72c29903813eJake Slack        try
71403928aee4356845252ac6b662d5c72c29903813eJake Slack        {
71503928aee4356845252ac6b662d5c72c29903813eJake Slack            // Resolve the impact
71603928aee4356845252ac6b662d5c72c29903813eJake Slack            int impact=MBeanOperationInfo.UNKNOWN;
71703928aee4356845252ac6b662d5c72c29903813eJake Slack            if (impact_name==null || impact_name.equals("UNKNOWN"))
71803928aee4356845252ac6b662d5c72c29903813eJake Slack                impact=MBeanOperationInfo.UNKNOWN;
71903928aee4356845252ac6b662d5c72c29903813eJake Slack            else if (impact_name.equals("ACTION"))
72003928aee4356845252ac6b662d5c72c29903813eJake Slack                impact=MBeanOperationInfo.ACTION;
72103928aee4356845252ac6b662d5c72c29903813eJake Slack            else if (impact_name.equals("INFO"))
72203928aee4356845252ac6b662d5c72c29903813eJake Slack                impact=MBeanOperationInfo.INFO;
72303928aee4356845252ac6b662d5c72c29903813eJake Slack            else if (impact_name.equals("ACTION_INFO"))
72403928aee4356845252ac6b662d5c72c29903813eJake Slack                impact=MBeanOperationInfo.ACTION_INFO;
72503928aee4356845252ac6b662d5c72c29903813eJake Slack            else
72603928aee4356845252ac6b662d5c72c29903813eJake Slack                LOG.warn("Unknown impact '"+impact_name+"' for "+signature);
72703928aee4356845252ac6b662d5c72c29903813eJake Slack
72803928aee4356845252ac6b662d5c72c29903813eJake Slack
72903928aee4356845252ac6b662d5c72c29903813eJake Slack            // split the signature
73003928aee4356845252ac6b662d5c72c29903813eJake Slack            String[] parts=signature.split("[\\(\\)]");
73103928aee4356845252ac6b662d5c72c29903813eJake Slack            String method_name=parts[0];
73203928aee4356845252ac6b662d5c72c29903813eJake Slack            String arguments=parts.length==2?parts[1]:null;
73303928aee4356845252ac6b662d5c72c29903813eJake Slack            String[] args=arguments==null?new String[0]:arguments.split(" *, *");
73403928aee4356845252ac6b662d5c72c29903813eJake Slack
73503928aee4356845252ac6b662d5c72c29903813eJake Slack            // Check types and normalize signature.
73603928aee4356845252ac6b662d5c72c29903813eJake Slack            Class[] types = new Class[args.length];
73703928aee4356845252ac6b662d5c72c29903813eJake Slack            MBeanParameterInfo[] pInfo = new MBeanParameterInfo[args.length];
73803928aee4356845252ac6b662d5c72c29903813eJake Slack            signature=method_name;
73903928aee4356845252ac6b662d5c72c29903813eJake Slack            for (i = 0; i < args.length; i++)
74003928aee4356845252ac6b662d5c72c29903813eJake Slack            {
74103928aee4356845252ac6b662d5c72c29903813eJake Slack                Class type = TypeUtil.fromName(args[i]);
74203928aee4356845252ac6b662d5c72c29903813eJake Slack                if (type == null)
74303928aee4356845252ac6b662d5c72c29903813eJake Slack                    type = Thread.currentThread().getContextClassLoader().loadClass(args[i]);
74403928aee4356845252ac6b662d5c72c29903813eJake Slack                types[i] = type;
74503928aee4356845252ac6b662d5c72c29903813eJake Slack                args[i] = type.isPrimitive() ? TypeUtil.toName(type) : args[i];
74603928aee4356845252ac6b662d5c72c29903813eJake Slack                signature+=(i>0?",":"(")+args[i];
74703928aee4356845252ac6b662d5c72c29903813eJake Slack            }
74803928aee4356845252ac6b662d5c72c29903813eJake Slack            signature+=(i>0?")":"()");
74903928aee4356845252ac6b662d5c72c29903813eJake Slack
75003928aee4356845252ac6b662d5c72c29903813eJake Slack            // Build param infos
75103928aee4356845252ac6b662d5c72c29903813eJake Slack            for (i = 0; i < args.length; i++)
75203928aee4356845252ac6b662d5c72c29903813eJake Slack            {
75303928aee4356845252ac6b662d5c72c29903813eJake Slack                String param_desc = bundle.getString(signature + "[" + i + "]");
75403928aee4356845252ac6b662d5c72c29903813eJake Slack                parts=param_desc.split(" *: *",2);
75503928aee4356845252ac6b662d5c72c29903813eJake Slack                if (LOG.isDebugEnabled())
75603928aee4356845252ac6b662d5c72c29903813eJake Slack                    LOG.debug(parts[0]+": "+parts[1]);
75703928aee4356845252ac6b662d5c72c29903813eJake Slack                pInfo[i] = new MBeanParameterInfo(parts[0].trim(), args[i], parts[1].trim());
75803928aee4356845252ac6b662d5c72c29903813eJake Slack            }
75903928aee4356845252ac6b662d5c72c29903813eJake Slack
76003928aee4356845252ac6b662d5c72c29903813eJake Slack            // build the operation info
76103928aee4356845252ac6b662d5c72c29903813eJake Slack            Method method = oClass.getMethod(method_name, types);
76203928aee4356845252ac6b662d5c72c29903813eJake Slack            Class returnClass = method.getReturnType();
76303928aee4356845252ac6b662d5c72c29903813eJake Slack            _methods.put(signature, method);
76403928aee4356845252ac6b662d5c72c29903813eJake Slack            if (convert)
76503928aee4356845252ac6b662d5c72c29903813eJake Slack                _convert.add(signature);
76603928aee4356845252ac6b662d5c72c29903813eJake Slack
76703928aee4356845252ac6b662d5c72c29903813eJake Slack            return new MBeanOperationInfo(method_name, description, pInfo, returnClass.isPrimitive() ? TypeUtil.toName(returnClass) : (returnClass.getName()), impact);
76803928aee4356845252ac6b662d5c72c29903813eJake Slack        }
76903928aee4356845252ac6b662d5c72c29903813eJake Slack        catch (Exception e)
77003928aee4356845252ac6b662d5c72c29903813eJake Slack        {
77103928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.warn("Operation '"+signature+"'", e);
77203928aee4356845252ac6b662d5c72c29903813eJake Slack            throw new IllegalArgumentException(e.toString());
77303928aee4356845252ac6b662d5c72c29903813eJake Slack        }
77403928aee4356845252ac6b662d5c72c29903813eJake Slack
77503928aee4356845252ac6b662d5c72c29903813eJake Slack    }
77603928aee4356845252ac6b662d5c72c29903813eJake Slack
77703928aee4356845252ac6b662d5c72c29903813eJake Slack}
778