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 + -
显示快捷键?