📄 mbeanintrospector.java
字号:
* Invoke the given setter on the given target with the given argument * and cookie. Wrap exceptions appropriately. */ /* If the value is of the wrong type for the method we are about to * invoke, we are supposed to throw an InvalidAttributeValueException. * Rather than making the check always, we invoke the method, then * if it throws an exception we check the type to see if that was * what caused the exception. The assumption is that an exception * from an invalid type will arise before any user method is ever * called (either in reflection or in OpenConverter). */ final void invokeSetter(String name, M setter, Object target, Object arg, Object cookie) throws MBeanException, ReflectionException, InvalidAttributeValueException { try { invokeM2(setter, target, new Object[] {arg}, cookie); } catch (IllegalAccessException e) { throw new ReflectionException(e, e.toString()); } catch (RuntimeException e) { maybeInvalidParameter(name, setter, arg, cookie); throw e; } catch (InvocationTargetException e) { maybeInvalidParameter(name, setter, arg, cookie); unwrapInvocationTargetException(e); } } private void maybeInvalidParameter(String name, M setter, Object arg, Object cookie) throws InvalidAttributeValueException { if (!validParameter(setter, arg, 0, cookie)) { final String msg = "Invalid value for attribute " + name + ": " + arg; throw new InvalidAttributeValueException(msg); } } static boolean isValidParameter(Method m, Object value, int paramNo) { Class<?> c = m.getParameterTypes()[paramNo]; try { // Following is expensive but we only call this method to determine // if an exception is due to an incompatible parameter type. // Plain old c.isInstance doesn't work for primitive types. Object a = Array.newInstance(c, 1); Array.set(a, 0, value); return true; } catch (IllegalArgumentException e) { return false; } } private static void unwrapInvocationTargetException(InvocationTargetException e) throws MBeanException { Throwable t = e.getCause(); if (t instanceof RuntimeException) throw (RuntimeException) t; else if (t instanceof Error) throw (Error) t; else throw new MBeanException((Exception) t, (t == null ? null : t.toString())); } /** A visitor that constructs the per-interface MBeanInfo. */ private class MBeanInfoMaker implements MBeanAnalyzer.MBeanVisitor<M> { public void visitAttribute(String attributeName, M getter, M setter) { MBeanAttributeInfo mbai = getMBeanAttributeInfo(attributeName, getter, setter); attrs.add(mbai); } public void visitOperation(String operationName, M operation) { MBeanOperationInfo mboi = getMBeanOperationInfo(operationName, operation); ops.add(mboi); } /** Make an MBeanInfo based on the attributes and operations * found in the interface. */ MBeanInfo makeMBeanInfo(Class<?> mbeanInterface, String description) { final MBeanAttributeInfo[] attrArray = attrs.toArray(new MBeanAttributeInfo[0]); final MBeanOperationInfo[] opArray = ops.toArray(new MBeanOperationInfo[0]); final String interfaceClassName = "interfaceClassName=" + mbeanInterface.getName(); final Descriptor interfDescriptor = new ImmutableDescriptor(interfaceClassName); final Descriptor mbeanDescriptor = getBasicMBeanDescriptor(); final Descriptor annotatedDescriptor = Introspector.descriptorForElement(mbeanInterface); final Descriptor descriptor = DescriptorCache.getInstance().union(interfDescriptor, mbeanDescriptor, annotatedDescriptor); return new MBeanInfo(mbeanInterface.getName(), description, attrArray, null, opArray, null, descriptor); } private final List<MBeanAttributeInfo> attrs = newList(); private final List<MBeanOperationInfo> ops = newList(); } /* * Looking up the MBeanInfo for a given base class (implementation class) * is complicated by the fact that we may use the same base class with * several different explicit MBean interfaces via the * javax.management.StandardMBean class. It is further complicated * by the fact that we have to be careful not to retain a strong reference * to any Class object for fear we would prevent a ClassLoader from being * garbage-collected. So we have a first lookup from the base class * to a map for each interface that base class might specify giving * the MBeanInfo constructed for that base class and interface. */ static class MBeanInfoMap extends WeakHashMap<Class<?>, WeakHashMap<Class<?>, MBeanInfo>> { } /** * Return the MBeanInfo for the given resource, based on the given * per-interface data. */ final MBeanInfo getMBeanInfo(Object resource, PerInterface<M> perInterface) { MBeanInfo mbi = getClassMBeanInfo(resource.getClass(), perInterface); MBeanNotificationInfo[] notifs = findNotifications(resource); if (notifs == null || notifs.length == 0) return mbi; else { return new MBeanInfo(mbi.getClassName(), mbi.getDescription(), mbi.getAttributes(), mbi.getConstructors(), mbi.getOperations(), notifs, mbi.getDescriptor()); } } /** * Return the basic MBeanInfo for resources of the given class and * per-interface data. This MBeanInfo might not be the final MBeanInfo * for instances of the class, because if the class is a * NotificationBroadcaster then each instance gets to decide what * MBeanNotificationInfo[] to put in its own MBeanInfo. */ final MBeanInfo getClassMBeanInfo(Class<?> resourceClass, PerInterface<M> perInterface) { MBeanInfoMap map = getMBeanInfoMap(); synchronized (map) { WeakHashMap<Class<?>, MBeanInfo> intfMap = map.get(resourceClass); if (intfMap == null) { intfMap = new WeakHashMap<Class<?>, MBeanInfo>(); map.put(resourceClass, intfMap); } Class<?> intfClass = perInterface.getMBeanInterface(); MBeanInfo mbi = intfMap.get(intfClass); if (mbi == null) { MBeanInfo imbi = perInterface.getMBeanInfo(); Descriptor descriptor = ImmutableDescriptor.union(imbi.getDescriptor(), getMBeanDescriptor(resourceClass)); mbi = new MBeanInfo(resourceClass.getName(), imbi.getDescription(), imbi.getAttributes(), findConstructors(resourceClass), imbi.getOperations(), (MBeanNotificationInfo[]) null, descriptor); intfMap.put(intfClass, mbi); } return mbi; } } static MBeanNotificationInfo[] findNotifications(Object moi) { if (!(moi instanceof NotificationBroadcaster)) return null; MBeanNotificationInfo[] mbn = ((NotificationBroadcaster) moi).getNotificationInfo(); if (mbn == null) return null; MBeanNotificationInfo[] result = new MBeanNotificationInfo[mbn.length]; for (int i = 0; i < mbn.length; i++) { MBeanNotificationInfo ni = mbn[i]; if (ni.getClass() != MBeanNotificationInfo.class) ni = (MBeanNotificationInfo) ni.clone(); result[i] = ni; } return result; } private static MBeanConstructorInfo[] findConstructors(Class<?> c) { Constructor[] cons = c.getConstructors(); MBeanConstructorInfo[] mbc = new MBeanConstructorInfo[cons.length]; for (int i = 0; i < cons.length; i++) { final String descr = "Public constructor of the MBean"; mbc[i] = new MBeanConstructorInfo(descr, cons[i]); } return mbc; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -