📄 introspector.java
字号:
} current = current.getSuperclass(); } return null; } /** * Discovers the getters, setters, operations of the class * * @param baseClass The XX base class. * @param beanClass The XXMBean interface implemented by the tested class. * * @exception NotCompliantMBeanException The tested class is not a * JMX compliant MBean */ private static MBeanInfo introspect(Class baseClass, Class beanClass) throws NotCompliantMBeanException { // ------------------------------ // ------------------------------ List/*<MBeanAttributeInfo>*/ attributes = new ArrayList/*<MBeanAttributeInfo>*/(); List/*<MBeanOperationInfo>*/ operations = new ArrayList/*<MBeanOperationInfo>*/(); Method methodList[] = beanClass.getMethods(); // Now analyze each method. for (int i = 0; i < methodList.length; i++) { Method method = methodList[i]; String name = method.getName(); Class argTypes[] = method.getParameterTypes(); Class resultType = method.getReturnType(); int argCount = argTypes.length; try { final MBeanAttributeInfo attr; if (name.startsWith("get") && !name.equals("get") && argCount == 0 && !resultType.equals(void.class)) { // if the method is "T getX()" it is a getter attr = new MBeanAttributeInfo(name.substring(3), attributeDescription, method, null); } else if (name.startsWith("set") && !name.equals("set") && argCount == 1 && resultType.equals(void.class)) { // if the method is "void setX(T x)" it is a setter attr = new MBeanAttributeInfo(name.substring(3), attributeDescription, null, method); } else if (name.startsWith("is") && !name.equals("is") && argCount == 0 && resultType.equals(boolean.class)) { // if the method is "boolean isX()" it is a getter attr = new MBeanAttributeInfo(name.substring(2), attributeDescription, method, null); } else { // in all other cases it is an operation attr = null; } if (attr != null) { if (testConsistency(attributes, attr)) attributes.add(attr); } else { final MBeanOperationInfo oper = new MBeanOperationInfo(operationDescription, method); operations.add(oper); } } catch (IntrospectionException e) { // Should not happen (MBeanAttributeInfo constructor) error("introspect", e); } } return constructResult(baseClass, attributes, operations); } /** * Checks if the types and the signatures of * getters/setters/operations are conform to the MBean design * patterns. * * Error cases: * - It exposes a method void Y getXX() AND a method void setXX(Z) * (parameter type mismatch) * - It exposes a method void setXX(Y) AND a method void setXX(Z) * (parameter type mismatch) * - It exposes a boolean isXX() method AND a YY getXX() or a void setXX(Y). * Returns false if the attribute is already in attributes List */ private static boolean testConsistency(List/*<MBeanAttributeInfo>*/attributes, MBeanAttributeInfo attr) throws NotCompliantMBeanException { for (Iterator it = attributes.iterator(); it.hasNext(); ) { MBeanAttributeInfo mb = (MBeanAttributeInfo) it.next(); if (mb.getName().equals(attr.getName())) { if ((attr.isReadable() && mb.isReadable()) && (attr.isIs() != mb.isIs())) { final String msg = "Conflicting getters for attribute " + mb.getName(); throw new NotCompliantMBeanException(msg); } if (!mb.getType().equals(attr.getType())) { if (mb.isWritable() && attr.isWritable()) { final String msg = "Type mismatch between parameters of set" + mb.getName() + " methods"; throw new NotCompliantMBeanException(msg); } else { final String msg = "Type mismatch between parameters of get or is" + mb.getName() + ", set" + mb.getName() + " methods"; throw new NotCompliantMBeanException(msg); } } if (attr.isReadable() && mb.isReadable()) { return false; } if (attr.isWritable() && mb.isWritable()) { return false; } } } return true; } /** * Discovers the constructors of the MBean */ static MBeanConstructorInfo[] getConstructors(Class baseClass) { Constructor[] consList = baseClass.getConstructors(); List constructors = new ArrayList(); // Now analyze each Constructor. for (int i = 0; i < consList.length; i++) { Constructor constructor = consList[i]; MBeanConstructorInfo mc = null; try { mc = new MBeanConstructorInfo(constructorDescription, constructor); } catch (Exception ex) { mc = null; } if (mc != null) { constructors.add(mc); } } // Allocate and populate the result array. MBeanConstructorInfo[] resultConstructors = new MBeanConstructorInfo[constructors.size()]; constructors.toArray(resultConstructors); return resultConstructors; } /** * Constructs the MBeanInfo of the MBean. */ private static MBeanInfo constructResult(Class baseClass, List/*<MBeanAttributeInfo>*/ attributes, List/*<MBeanOperationInfo>*/ operations) { final int len = attributes.size(); final MBeanAttributeInfo[] attrlist = new MBeanAttributeInfo[len]; attributes.toArray(attrlist); final ArrayList mergedAttributes = new ArrayList(); for (int i=0;i<len;i++) { final MBeanAttributeInfo bi = attrlist[i]; // bi can be null if it has already been eliminated // by the loop below at an earlier iteration // (cf. attrlist[j]=null;) In this case, just skip it. // if (bi == null) continue; // Placeholder for the final attribute info we're going to // keep. // MBeanAttributeInfo att = bi; // The loop below will try to find whether bi is also present // elsewhere further down the list. // If it is not, att will be left unchanged. // Otherwise, the found attribute info will be merged with // att and `removed' from the array by setting them to `null' // for (int j=i+1;j<len;j++) { MBeanAttributeInfo mi = attrlist[j]; // mi can be null if it has already been eliminated // by this loop at an earlier iteration. // (cf. attrlist[j]=null;) In this case, just skip it. // if (mi == null) continue; if ((mi.getName().compareTo(bi.getName()) == 0)) { // mi and bi have the same name, which means that // that the attribute has been inserted twice in // the list, which means that it is a read-write // attribute. // So we're going to replace att with a new // attribute info with read-write mode. // We also set attrlist[j] to null in order to avoid // duplicates (attrlist[j] and attrlist[i] are now // merged into att). // attrlist[j]=null; att = new MBeanAttributeInfo(bi.getName(), bi.getType(), attributeDescription, true, true, bi.isIs()); // I think we could break, but it is probably // safer not to... // // break; } } // Now all attributes info which had the same name than bi // have been merged together in att. // Simply add att to the merged list. // mergedAttributes.add(att); } final MBeanAttributeInfo[] resultAttributes = new MBeanAttributeInfo[mergedAttributes.size()]; mergedAttributes.toArray(resultAttributes); final MBeanOperationInfo[] resultOperations = new MBeanOperationInfo[operations.size()]; operations.toArray(resultOperations); final MBeanConstructorInfo[] resultConstructors = getConstructors(baseClass); final MBeanInfo resultMBeanInfo = new MBeanInfo(baseClass.getName(), mbeanInfoDescription, resultAttributes, resultConstructors, resultOperations, null); return resultMBeanInfo; } /** * Returns the XXMBean interface or null if no such interface exists * * @param c The interface to be tested * @param clName The name of the class implementing this interface */ static Class implementsMBean(Class c, String clName) { if (c.getName().compareTo(clName + "MBean") == 0) { return c; } Class current = c; Class[] interfaces = c.getInterfaces(); for (int i = 0;i < interfaces.length; i++) { try { if (interfaces[i].getName().compareTo(clName + "MBean") == 0) { return interfaces[i]; } } catch (Exception e) { return null; } } return null; } private static void error(String method,Throwable t) { com.sun.jmx.trace.Trace.send(com.sun.jmx.trace.Trace.LEVEL_ERROR, com.sun.jmx.trace.Trace.INFO_MBEANSERVER, "Introspector", method, t); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -