All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jetty.jmx.ObjectMBean Maven / Gradle / Ivy

There is a newer version: 1.0-rc5
Show newest version
// ========================================================================
// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at 
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses. 
// ========================================================================

package org.eclipse.jetty.jmx;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;

import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
import javax.management.DynamicMBean;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.modelmbean.ModelMBean;

import org.eclipse.jetty.util.LazyList;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;

/* ------------------------------------------------------------ */
/** ObjectMBean.
 * A dynamic MBean that can wrap an arbitary Object instance.
 * the attributes and methods exposed by this bean are controlled by
 * the merge of property bundles discovered by names related to all
 * superclasses and all superinterfaces.
 *
 * Attributes and methods exported may be "Object" and must exist on the
 * wrapped object, or "MBean" and must exist on a subclass of OBjectMBean
 * or "MObject" which exists on the wrapped object, but whose values are
 * converted to MBean object names.
 *
 */
public class ObjectMBean implements DynamicMBean
{
    private static Class[] OBJ_ARG = new Class[]{Object.class};

    protected Object _managed;
    private MBeanInfo _info;
    private Map _getters=new HashMap();
    private Map _setters=new HashMap();
    private Map _methods=new HashMap();
    private Set _convert=new HashSet();
    private ClassLoader _loader;
    private MBeanContainer _mbeanContainer;

    private static String OBJECT_NAME_CLASS = ObjectName.class.getName();
    private static String OBJECT_NAME_ARRAY_CLASS = ObjectName[].class.getName();

    /* ------------------------------------------------------------ */
    /**
     * Create MBean for Object. Attempts to create an MBean for the object by searching the package
     * and class name space. For example an object of the type
     *
     * 
     * class com.acme.MyClass extends com.acme.util.BaseClass implements com.acme.Iface
     * 
* * Then this method would look for the following classes: *
    *
  • com.acme.jmx.MyClassMBean *
  • com.acme.util.jmx.BaseClassMBean *
  • org.eclipse.jetty.jmx.ObjectMBean *
* * @param o The object * @return A new instance of an MBean for the object or null. */ public static Object mbeanFor(Object o) { try { Class oClass = o.getClass(); Object mbean = null; while (mbean == null && oClass != null) { String pName = oClass.getPackage().getName(); String cName = oClass.getName().substring(pName.length() + 1); String mName = pName + ".jmx." + cName + "MBean"; try { Class mClass = (Object.class.equals(oClass))?oClass=ObjectMBean.class:Loader.loadClass(oClass,mName,true); if (Log.isDebugEnabled()) Log.debug("mbeanFor " + o + " mClass=" + mClass); try { Constructor constructor = mClass.getConstructor(OBJ_ARG); mbean=constructor.newInstance(new Object[]{o}); } catch(Exception e) { Log.ignore(e); if (ModelMBean.class.isAssignableFrom(mClass)) { mbean=mClass.newInstance(); ((ModelMBean)mbean).setManagedResource(o, "objectReference"); } } if (Log.isDebugEnabled()) Log.debug("mbeanFor " + o + " is " + mbean); return mbean; } catch (ClassNotFoundException e) { if (e.toString().endsWith("MBean")) Log.ignore(e); else Log.warn(e); } catch (Error e) { Log.warn(e); mbean = null; } catch (Exception e) { Log.warn(e); mbean = null; } oClass = oClass.getSuperclass(); } } catch (Exception e) { Log.ignore(e); } return null; } public ObjectMBean(Object managedObject) { _managed = managedObject; _loader = Thread.currentThread().getContextClassLoader(); } public Object getManagedObject() { return _managed; } public ObjectName getObjectName() { return null; } public String getObjectNameBasis() { return null; } protected void setMBeanContainer(MBeanContainer container) { this._mbeanContainer = container; } public MBeanContainer getMBeanContainer () { return this._mbeanContainer; } public MBeanInfo getMBeanInfo() { try { if (_info==null) { // Start with blank lazy lists attributes etc. String desc=null; Object attributes=null; Object constructors=null; Object operations=null; Object notifications=null; // Find list of classes that can influence the mbean Class o_class=_managed.getClass(); Object influences = findInfluences(null, _managed.getClass()); // Set to record defined items Set defined=new HashSet(); // For each influence for (int i=0;i0) { // define an operation if (!defined.contains(key) && key.indexOf('[')<0) { defined.add(key); operations=LazyList.add(operations,defineOperation(key, value, bundle)); } } else { // define an attribute if (!defined.contains(key)) { defined.add(key); MBeanAttributeInfo info=defineAttribute(key, value); if (info!=null) attributes=LazyList.add(attributes,info); } } } } catch(MissingResourceException e) { Log.ignore(e); } } _info = new MBeanInfo(o_class.getName(), desc, (MBeanAttributeInfo[])LazyList.toArray(attributes, MBeanAttributeInfo.class), (MBeanConstructorInfo[])LazyList.toArray(constructors, MBeanConstructorInfo.class), (MBeanOperationInfo[])LazyList.toArray(operations, MBeanOperationInfo.class), (MBeanNotificationInfo[])LazyList.toArray(notifications, MBeanNotificationInfo.class)); } } catch(RuntimeException e) { Log.warn(e); throw e; } return _info; } /* ------------------------------------------------------------ */ public Object getAttribute(String name) throws AttributeNotFoundException, MBeanException, ReflectionException { Method getter = (Method) _getters.get(name); if (getter == null) throw new AttributeNotFoundException(name); try { Object o = _managed; if (getter.getDeclaringClass().isInstance(this)) o = this; // mbean method // get the attribute Object r=getter.invoke(o, (java.lang.Object[]) null); // convert to ObjectName if need be. if (r!=null && _convert.contains(name)) { if (r.getClass().isArray()) { ObjectName[] on = new ObjectName[Array.getLength(r)]; for (int i=0;i 0 ? "," : "") + signature[i]; methodKey += ")"; ClassLoader old_loader=Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(_loader); Method method = (Method) _methods.get(methodKey); if (method == null) throw new NoSuchMethodException(methodKey); Object o = _managed; if (method.getDeclaringClass().isInstance(this)) o = this; return method.invoke(o, params); } catch (NoSuchMethodException e) { Log.warn(Log.EXCEPTION, e); throw new ReflectionException(e); } catch (IllegalAccessException e) { Log.warn(Log.EXCEPTION, e); throw new MBeanException(e); } catch (InvocationTargetException e) { Log.warn(Log.EXCEPTION, e); throw new ReflectionException(new Exception(e.getCause())); } finally { Thread.currentThread().setContextClassLoader(old_loader); } } private static Object findInfluences(Object influences, Class aClass) { if (aClass!=null) { // This class is an influence influences=LazyList.add(influences,aClass); // So are the super classes influences=findInfluences(influences,aClass.getSuperclass()); // So are the interfaces Class[] ifs = aClass.getInterfaces(); for (int i=0;ifs!=null && i *
  • "Object" The field/method is on the managed object. *
  • "MBean" The field/method is on the mbean proxy object *
  • "MObject" The field/method is on the managed object and value should be converted to MBean reference *
  • "MMBean" The field/method is on the mbean proxy object and value should be converted to MBean reference * * the access is either "RW" or "RO". */ public MBeanAttributeInfo defineAttribute(String name, String metaData) { String description = ""; boolean writable = true; boolean onMBean = false; boolean convert = false; if (metaData!= null) { String[] tokens = metaData.split(":", 3); for (int t=0;t0?",":"(")+args[i]; } signature+=(i>0?")":"()"); // Build param infos for (i = 0; i < args.length; i++) { String param_desc = bundle.getString(signature + "[" + i + "]"); parts=param_desc.split(" *: *",2); if (Log.isDebugEnabled()) Log.debug(parts[0]+": "+parts[1]); pInfo[i] = new MBeanParameterInfo(parts[0].trim(), args[i], parts[1].trim()); } // build the operation info Method method = oClass.getMethod(method_name, types); Class returnClass = method.getReturnType(); _methods.put(signature, method); if (convert) _convert.add(signature); return new MBeanOperationInfo(method_name, description, pInfo, returnClass.isPrimitive() ? TypeUtil.toName(returnClass) : (returnClass.getName()), impact); } catch (Exception e) { Log.warn("Operation '"+signature+"'", e); throw new IllegalArgumentException(e.toString()); } } }




  • © 2015 - 2024 Weber Informatics LLC | Privacy Policy