introspectionmbean.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 840 行 · 第 1/2 页

JAVA
840
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source 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 of the License, or * (at your option) any later version. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.jmx;import javax.management.*;import javax.management.openmbean.ArrayType;import javax.management.openmbean.OpenType;import javax.management.openmbean.SimpleType;import java.lang.annotation.Annotation;import java.lang.ref.SoftReference;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.Comparator;import java.util.HashMap;import java.util.WeakHashMap;import java.util.logging.Level;import java.util.logging.Logger;import com.caucho.util.L10N;/** * Resin implementation of StandardMBean. */public class IntrospectionMBean implements DynamicMBean {  private static final L10N L = new L10N(IntrospectionMBean.class);  private static final Logger log    = Logger.getLogger(IntrospectionMBean.class.getName());  private static final Class[] NULL_ARG = new Class[0];  private static final Class _descriptionAnn;  private static final Class _nameAnn;  private static final WeakHashMap<Class,SoftReference<MBeanInfo>> _cachedInfo    = new WeakHashMap<Class,SoftReference<MBeanInfo>>();  private final Object _impl;  private final Class _mbeanInterface;  private final boolean _isLowercaseAttributeNames;  private final MBeanInfo _mbeanInfo;  private final HashMap<String,OpenModelMethod> _attrGetMap    = new HashMap<String,OpenModelMethod>();  /**   * Makes a DynamicMBean.   */  public IntrospectionMBean(Object impl, Class mbeanInterface)    throws NotCompliantMBeanException  {    this(impl, mbeanInterface, false);  }  /**   * Makes a DynamicMBean.   *   * @param isLowercaseAttributeNames true if attributes should have first   * letter lowercased   */  public IntrospectionMBean(Object impl,                            Class mbeanInterface,                            boolean isLowercaseAttributeNames)    throws NotCompliantMBeanException  {    if (impl == null)      throw new NullPointerException();    _mbeanInterface = mbeanInterface;    _isLowercaseAttributeNames = isLowercaseAttributeNames;    _mbeanInfo = introspect(impl, mbeanInterface, isLowercaseAttributeNames);    _impl = impl;  }  /**   * Returns the implementation.   */  public Object getImplementation()  {    return _impl;  }  /**   * Returns an attribute value.   */  public Object getAttribute(String attribute)    throws AttributeNotFoundException, MBeanException, ReflectionException  {    try {      OpenModelMethod method = getGetMethod(attribute);      if (method != null)        return method.invoke(_impl, (Object []) null);      else        throw new AttributeNotFoundException(L.l("'{0}' is an unknown attribute in '{1}'",						 attribute,						 _mbeanInterface.getName()));    } catch (IllegalAccessException e) {      throw new MBeanException(e);    } catch (InvocationTargetException e) {      if (e.getCause() instanceof Exception)        throw new ReflectionException((Exception) e.getCause());      else        throw (Error) e.getCause();    } catch (Throwable e) {      throw new RuntimeException(e);    }  }  /**   * Sets an attribute value.   */  public void setAttribute(Attribute attribute)    throws AttributeNotFoundException, InvalidAttributeValueException,           MBeanException, ReflectionException  {    try {      Method method = getSetMethod(attribute.getName(), attribute.getValue());      if (method != null)        method.invoke(_impl, new Object[] { attribute.getValue() });      else        throw new AttributeNotFoundException(attribute.getName());    } catch (IllegalAccessException e) {      throw new MBeanException(e);    } catch (InvocationTargetException e) {      throw new MBeanException(e);    } catch (Throwable e) {      throw new RuntimeException(e.toString());    }  }  /**   * Returns matching attribute values.   */  public AttributeList getAttributes(String []attributes)  {    AttributeList list = new AttributeList();    for (int i = 0; i < attributes.length; i++) {      try {        OpenModelMethod method = getGetMethod(attributes[i]);        if (method != null) {          Object value = method.invoke(_impl, (Object []) null);          list.add(new Attribute(attributes[i], value));        }      } catch (Throwable e) {        log.log(Level.WARNING, e.toString(), e);      }    }    return list;  }  /**   * Sets attribute values.   */  public AttributeList setAttributes(AttributeList attributes)  {    AttributeList list = new AttributeList();    for (int i = 0; i < attributes.size(); i++) {      try {        Attribute attr = (Attribute) attributes.get(i);        Method method = getSetMethod(attr.getName(), attr.getValue());        if (method != null) {          method.invoke(_impl, new Object[] { attr.getValue() });          list.add(new Attribute(attr.getName(), attr.getValue()));        }      } catch (Throwable e) {        log.log(Level.WARNING, e.toString(), e);      }    }    return list;  }  /**   * Returns the set method matching the name.   */  private OpenModelMethod getGetMethod(String name)  {    OpenModelMethod method = _attrGetMap.get(name);    if (method != null)      return method;    method = createGetMethod(name);    if (method != null)      _attrGetMap.put(name, method);    return method;  }  /**   * Returns the get or is method matching the name.   */  private OpenModelMethod createGetMethod(String name)  {    String methodName;    if (_isLowercaseAttributeNames)  {      StringBuilder builder = new StringBuilder(name);      builder.setCharAt(0, Character.toUpperCase(builder.charAt(0)));      methodName = builder.toString();    }    else      methodName = name;    String getName = "get" + methodName;    String isName = "is" + methodName;    Method []methods = _mbeanInterface.getMethods();    for (int i = 0; i < methods.length; i++) {      if (! methods[i].getName().equals(getName) &&          ! methods[i].getName().equals(isName))        continue;      Class []args = methods[i].getParameterTypes();      if (args.length == 0 &&	  ! methods[i].getReturnType().equals(void.class)) {	Class retType = methods[i].getReturnType();	        return new OpenModelMethod(methods[i], createUnmarshall(retType));      }    }    return null;  }  /**v   * Returns the open mbean unmarshaller for the given return type.   */  private Unmarshall createUnmarshall(Class cl)  {    Unmarshall mbean = getMBeanObjectName(cl);    if (mbean != null)      return mbean;    if (cl.isArray()) {      Class componentType = cl.getComponentType();            mbean = getMBeanObjectName(componentType);      if (mbean != null)	return new UnmarshallArray(ObjectName.class, mbean);    }    return Unmarshall.IDENTITY;  }  private Unmarshall getMBeanObjectName(Class cl)  {    try {      Method method = cl.getMethod("getObjectName");      if (method != null	  && ObjectName.class.equals(method.getReturnType()))	return new UnmarshallMBean(method);    } catch (NoSuchMethodException e) {    } catch (Exception e) {      log.log(Level.FINER, e.toString(), e);    }    return null;  }  /**   * Returns the set method matching the name.   */  private Method getSetMethod(String name, Object value)  {    String methodName;    if (_isLowercaseAttributeNames)  {      StringBuilder builder = new StringBuilder(name);      builder.setCharAt(0, Character.toUpperCase(builder.charAt(0)));      methodName = builder.toString();    }    else      methodName = name;    String setName = "set" + methodName;    Method []methods = _mbeanInterface.getMethods();    for (int i = 0; i < methods.length; i++) {      if (! methods[i].getName().equals(setName))        continue;      Class []args = methods[i].getParameterTypes();      if (args.length != 1)        continue;      /*      if (value != null && ! args[0].isAssignableFrom(value.getClass()))	continue;      */      return methods[i];    }    return null;  }  /**   * Invokes a method on the bean.   */  public Object invoke(String actionName,                       Object []params,                       String []signature)    throws MBeanException, ReflectionException  {    try {      Method []methods = _mbeanInterface.getMethods();      int length = 0;      if (signature != null)        length = signature.length;      if (params != null)        length = params.length;      for (int i = 0; i < methods.length; i++) {        if (! methods[i].getName().equals(actionName))          continue;        Class []args = methods[i].getParameterTypes();        if (args.length != length)          continue;        boolean isMatch = true;        for (int j = length - 1; j >= 0; j--) {          if (signature != null && ! args[j].getName().equals(signature[j]))            isMatch = false;        }        if (isMatch) {          return methods[i].invoke(_impl, params);	}      }      if (actionName.equals("hashCode")	  && (signature == null || signature.length == 0))        return _impl.hashCode();      else if (actionName.equals("toString")	       && (signature == null || signature.length == 0))        return _impl.toString();      else        return null;    } catch (IllegalAccessException e) {      throw new MBeanException(e);    } catch (InvocationTargetException e) {      if (e.getCause() instanceof Exception)        throw new ReflectionException((Exception) e.getCause());      else        throw (Error) e.getCause();    }  }  /**   * Returns the introspection information for the MBean.   */  public MBeanInfo getMBeanInfo()  {    return _mbeanInfo;  }  static MBeanInfo introspect(Object obj, Class cl,                              boolean isLowercaseAttributeNames)    throws NotCompliantMBeanException  {    try {      SoftReference<MBeanInfo> infoRef = _cachedInfo.get(cl);      MBeanInfo info = null;      if (infoRef != null && (info = infoRef.get()) != null)        return info;      String className = cl.getName();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?