FileDocCategorySizeDatePackage
Introspector.javaAPI DocJava SE 6 API17818Tue Jun 10 00:22:02 BST 2008com.sun.jmx.mbeanserver

Introspector

public class Introspector extends Object
This class contains the methods for performing all the tests needed to verify that a class represents a JMX compliant MBean.
since
1.5

Fields Summary
private static final String
attributeDescription
private static final String
operationDescription
private static final String
constructorDescription
private static final String
mbeanInfoDescription
Constructors Summary
private Introspector()

    

     /*
     * ------------------------------------------
     *  PRIVATE CONSTRUCTORS
     * ------------------------------------------
     */

    // private constructor defined to "hide" the default public constructor
      

	// ------------------------------ 
	// ------------------------------
	
    
Methods Summary
private static java.lang.ObjectannotationToField(java.lang.Object x)

        // An annotation element cannot have a null value but never mind
        if (x == null)
            return null;
        if (x instanceof Number || x instanceof String ||
                x instanceof Character || x instanceof Boolean ||
                x instanceof String[])
            return x;
        // Remaining possibilities: array of primitive (e.g. int[]),
        // enum, class, array of enum or class.
        Class<?> c = x.getClass();
        if (c.isArray()) {
            if (c.getComponentType().isPrimitive())
                return x;
            Object[] xx = (Object[]) x;
            String[] ss = new String[xx.length];
            for (int i = 0; i < xx.length; i++)
                ss[i] = (String) annotationToField(xx[i]);
            return ss;
        }
        if (x instanceof Class)
            return ((Class<?>) x).getName();
        if (x instanceof Enum)
            return ((Enum) x).name();
        // The only other possibility is that the value is another
        // annotation, or that the language has evolved since this code
        // was written.  We don't allow for either of those currently.
        throw new IllegalArgumentException("Illegal type for annotation " +
                "element: " + x.getClass().getName());
    
public static voidcheckCompliance(java.lang.Class mbeanClass)

        // Is DynamicMBean?
        //
        if (DynamicMBean.class.isAssignableFrom(mbeanClass))
            return;
        // Is Standard MBean?
        //
        final Exception mbeanException;
        try {
            getStandardMBeanInterface(mbeanClass);
            return;
        } catch (NotCompliantMBeanException e) {
            mbeanException = e;
        }
        // Is MXBean?
        //
        final Exception mxbeanException;
        try {
            getMXBeanInterface(mbeanClass);
            return;
        } catch (NotCompliantMBeanException e) {
            mxbeanException = e;
        }
        final String msg =
            "MBean class " + mbeanClass.getName() + " does not implement " +
            "DynamicMBean, neither follows the Standard MBean conventions (" +
            mbeanException.toString() + ") nor the MXBean conventions (" +
            mxbeanException.toString() + ")";
        throw new NotCompliantMBeanException(msg);
    
public static javax.management.DescriptordescriptorForAnnotations(java.lang.annotation.Annotation[] annots)

        if (annots.length == 0)
            return ImmutableDescriptor.EMPTY_DESCRIPTOR;
        Map<String, Object> descriptorMap = new HashMap<String, Object>();
        for (Annotation a : annots) {
            Class<? extends Annotation> c = a.annotationType();
            Method[] elements = c.getMethods();
            for (Method element : elements) {
                DescriptorKey key = element.getAnnotation(DescriptorKey.class);
                if (key != null) {
                    String name = key.value();
                    Object value;
                    try {
                        value = element.invoke(a);
                    } catch (RuntimeException e) { 
                        // we don't expect this - except for possibly
                        // security exceptions? 
                        // RuntimeExceptions shouldn't be "UndeclaredThrowable".
                        // anyway...
                        //
                        throw e;
                    } catch (Exception e) {
                        // we don't expect this
                        throw new UndeclaredThrowableException(e);
                    }
                    value = annotationToField(value);
                    Object oldValue = descriptorMap.put(name, value);
                    if (oldValue != null && !equals(oldValue, value)) {
                        final String msg =
                            "Inconsistent values for descriptor field " + name +
                            " from annotations: " + value + " :: " + oldValue;
                        throw new IllegalArgumentException(msg);
                    }
                }
            }
        }
        
        if (descriptorMap.isEmpty())
            return ImmutableDescriptor.EMPTY_DESCRIPTOR;
        else
            return new ImmutableDescriptor(descriptorMap);
    
public static javax.management.DescriptordescriptorForElement(java.lang.reflect.AnnotatedElement elmt)

        if (elmt == null)
            return ImmutableDescriptor.EMPTY_DESCRIPTOR;
        final Annotation[] annots = elmt.getAnnotations();
        return descriptorForAnnotations(annots);
    
private static booleanequals(java.lang.Object x, java.lang.Object y)

        return Arrays.deepEquals(new Object[] {x}, new Object[] {y});
    
private static java.lang.ClassfindMBeanInterface(java.lang.Class aClass, java.lang.String aName)
Try to find the MBean interface corresponding to the class aName - i.e. aNameMBean, from within aClass and its superclasses.

	Class current = aClass;
	while (current != null) {
	    final Class[] interfaces = current.getInterfaces();   
	    final int len = interfaces.length;
	    for (int i=0;i<len;i++)  {	     
		final Class inter = 
		    implementsMBean(interfaces[i], aName);
		if (inter != null) return inter;
	    }
	    current = current.getSuperclass();
	}
	return null;     
    
public static java.lang.ClassgetMBeanInterface(java.lang.Class baseClass)
Get the MBean interface implemented by a JMX Standard MBean class. This method is only called by the legacy code in "com.sun.management.jmx".

param
baseClass The class to be tested.
return
The MBean interface implemented by the MBean. Return null if the MBean is a DynamicMBean, or if no MBean interface is found.

        // Check if the given class implements the MBean interface
        // or the Dynamic MBean interface
        if (isDynamic(baseClass)) return null;
        try {
            return getStandardMBeanInterface(baseClass);
        } catch (NotCompliantMBeanException e) {
            return null;
        }
    
public static java.lang.ClassgetMXBeanInterface(java.lang.Class baseClass)
Get the MXBean interface implemented by a JMX MXBean class.

param
baseClass The class to be tested.
return
The MXBean interface implemented by the MXBean.
throws
NotCompliantMBeanException The specified class is not a JMX compliant MXBean.

        try {
            return MXBeanSupport.findMXBeanInterface(baseClass);
        } catch (Exception e) {
            throw throwException(baseClass,e);
        }
    
public static java.lang.ClassgetStandardMBeanInterface(java.lang.Class baseClass)
Get the MBean interface implemented by a JMX Standard MBean class.

param
baseClass The class to be tested.
return
The MBean interface implemented by the Standard MBean.
throws
NotCompliantMBeanException The specified class is not a JMX compliant Standard MBean.

        Class current = baseClass;
        Class mbeanInterface = null;
        while (current != null) {
            mbeanInterface =
                findMBeanInterface(current, current.getName());
            if (mbeanInterface != null) break;
            current = current.getSuperclass();
        }
        if (mbeanInterface != null) {
            return mbeanInterface;
        } else {
            final String msg =
                "Class " + baseClass.getName() +
                " is not a JMX compliant Standard MBean";
            throw new NotCompliantMBeanException(msg);
        }
    
private static java.lang.ClassimplementsMBean(java.lang.Class c, java.lang.String clName)
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

        String clMBeanName = clName + "MBean";
	if (c.getName().equals(clMBeanName)) {
	    return c;
	}   
	Class current = c;
	Class[] interfaces = c.getInterfaces();
	for (int i = 0;i < interfaces.length; i++) {
            if (interfaces[i].getName().equals(clMBeanName))
                return interfaces[i];
	}
	
	return null;
    
public static final booleanisDynamic(java.lang.Class c)
Tell whether a MBean of the given class is a Dynamic MBean. This method does nothing more than returning
javax.management.DynamicMBean.class.isAssignableFrom(c)
This method does not check for any JMX MBean compliance:
  • If true is returned, then instances of c are DynamicMBean.
  • If false is returned, then no further assumption can be made on instances of c. In particular, instances of c may, or may not be JMX standard MBeans.

param
c The class of the MBean under examination.
return
true if instances of c are Dynamic MBeans, false otherwise.
since.unbundled
JMX RI 1.2

	// Check if the MBean implements the DynamicMBean interface
	return javax.management.DynamicMBean.class.isAssignableFrom(c);
    
public static javax.management.DynamicMBeanmakeDynamicMBean(java.lang.Object mbean)

        if (mbean instanceof DynamicMBean)
            return (DynamicMBean) mbean;
        final Class mbeanClass = mbean.getClass();
        Class c = null;
        try {
            c = getStandardMBeanInterface(mbeanClass);
        } catch (NotCompliantMBeanException e) {
            // Ignore exception - we need to check whether 
            // mbean is an MXBean first.
        }
        if (c != null) return new StandardMBeanSupport(mbean, c);

        try {
            c = getMXBeanInterface(mbeanClass);
        } catch (NotCompliantMBeanException e) {
            // Ignore exception - we cannot decide whether mbean was supposed
            // to be an MBean or an MXBean. We will call checkCompliance() 
            // to generate the appropriate exception.
        }
        if (c != null) return new MXBeanSupport(mbean, c);
        checkCompliance(mbeanClass);
        throw new NotCompliantMBeanException("Not compliant"); // not reached
    
public static javax.management.MBeanInfotestCompliance(java.lang.Class baseClass)
Basic method for testing if a given class is a JMX compliant MBean.

param
baseClass The class to be tested
return
null if the MBean is a DynamicMBean, the computed {@link javax.management.MBeanInfo} otherwise.
exception
NotCompliantMBeanException The specified class is not a JMX compliant MBean


	// ------------------------------ 
	// ------------------------------
	
	// Check if the MBean implements the MBean or the Dynamic 
	// MBean interface
	if (isDynamic(baseClass)) 
	    return null;
	
	return testCompliance(baseClass, null);
    
public static synchronized javax.management.MBeanInfotestCompliance(java.lang.Class baseClass, java.lang.Class mbeanInterface)
Basic method for testing if a given class is a JMX compliant Standard MBean. This method is only called by the legacy code in com.sun.management.jmx.

param
baseClass The class to be tested.
param
mbeanInterface the MBean interface that the class implements, or null if the interface must be determined by introspection.
return
the computed {@link javax.management.MBeanInfo}.
exception
NotCompliantMBeanException The specified class is not a JMX compliant Standard MBean

        if (mbeanInterface == null)
            mbeanInterface = getStandardMBeanInterface(baseClass);
        MBeanIntrospector introspector = StandardMBeanIntrospector.getInstance();
        PerInterface<?> perInterface = introspector.getPerInterface(mbeanInterface);
        return introspector.getClassMBeanInfo(baseClass, perInterface);
    
public static voidtestComplianceMXBeanInterface(java.lang.Class interfaceClass)

	MXBeanIntrospector.getInstance().getAnalyzer(interfaceClass);
    
public static voidtestCreation(java.lang.Class c)
Basic method for testing that a MBean of a given class can be instantiated by the MBean server.

This method checks that:

  • The given class is a concrete class.
  • The given class exposes at least one public constructor.
If these conditions are not met, throws a NotCompliantMBeanException.

param
c The class of the MBean we want to create.
exception
NotCompliantMBeanException if the MBean class makes it impossible to instantiate the MBean from within the MBeanServer.
since.unbundled
JMX RI 1.2

	// Check if the class is a concrete class
	final int mods = c.getModifiers(); 
	if (Modifier.isAbstract(mods) || Modifier.isInterface(mods)) {
	    throw new NotCompliantMBeanException("MBean class must be concrete");
	}

	// Check if the MBean has a public constructor 
	final Constructor[] consList = c.getConstructors();     
	if (consList.length == 0) {
	    throw new NotCompliantMBeanException("MBean class must have public constructor");
	}
    
static javax.management.NotCompliantMBeanExceptionthrowException(java.lang.Class notCompliant, java.lang.Throwable cause)
Throws a NotCompliantMBeanException or a SecurityException.

param
notCompliant the class which was under examination
param
cause the raeson why NotCompliantMBeanException should be thrown.
return
nothing - this method always throw an exception. The return type makes it possible to write
 throw throwException(clazz,cause); 
throws
SecurityException - if cause is a SecurityException
throws
NotCompliantMBeanException otherwise.

        if (cause instanceof SecurityException) 
            throw (SecurityException) cause;
        if (cause instanceof NotCompliantMBeanException)
            throw (NotCompliantMBeanException)cause;
        final String classname = 
                (notCompliant==null)?"null class":notCompliant.getName();
        final String reason = 
                (cause==null)?"Not compliant":cause.getMessage();
        final NotCompliantMBeanException res = 
                new NotCompliantMBeanException(classname+": "+reason);
        res.initCause(cause);
        throw res;