001: /* JFox, the OpenSource J2EE Application Server
002: *
003: * Copyright (C) 2002 huihoo.com
004: * Distributable under GNU LGPL license
005: * See the GNU Lesser General Public License for more details.
006: */
007:
008: package org.huihoo.jfox.jmx;
009:
010: import java.lang.reflect.Modifier;
011: import java.lang.reflect.Constructor;
012: import javax.management.NotCompliantMBeanException;
013: import javax.management.ReflectionException;
014:
015: /**
016: * introspector(check and instantiate) MBean Class after MBeanLoaderSupport have load a MBean
017: * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
018: */
019:
020: public class MBeanIntrospectorSupport implements MBeanIntrospector {
021: private static MBeanIntrospector me = new MBeanIntrospectorSupport();
022:
023: private MBeanIntrospectorSupport() {
024:
025: }
026:
027: public static MBeanIntrospector getInstance() {
028: return me;
029: }
030:
031: /**
032: * testing that a MBean of a given class can be instantiated by the MBean server for MBeanServer.instantiate
033: * This method checks that:
034:
035: * The given class is a concrete class.
036: * The given class exposes at least one public constructor.
037: * If these conditions are not met, throws a NotCompliantMBeanException.
038: * @throws javax.management.ReflectionException
039: */
040: public void checkInstantiate(Class mbeanClass)
041: throws ReflectionException {
042: int m = mbeanClass.getModifiers();
043: // is a abstract class or interface
044: if (Modifier.isAbstract(m) || Modifier.isInterface(m))
045: throw new ReflectionException(
046: new NotCompliantMBeanException(mbeanClass.getName()
047: + " must have be a concrete class."));
048: Constructor[] constructors = mbeanClass.getConstructors();
049: // not one public constructor
050: if (constructors.length == 0)
051: throw new ReflectionException(
052: new NotCompliantMBeanException(mbeanClass.getName()
053: + " must have a public constructor."));
054: }
055:
056: public boolean isDynamic(Class mbeanClass) {
057: return (javax.management.DynamicMBean.class)
058: .isAssignableFrom(mbeanClass);
059: }
060:
061: /**
062: * a MBean Class must be a class and must implement a MBean Inteface or DynamicMBean interface and the interface must be public
063: * @throws NotCompliantMBeanException
064: */
065: public Class checkCompliance(Class mbeanClass)
066: throws NotCompliantMBeanException {
067: if (isDynamic(mbeanClass))
068: return javax.management.DynamicMBean.class;
069: int m = mbeanClass.getModifiers();
070: // is a abstract class or interface
071: if (Modifier.isAbstract(m) || Modifier.isInterface(m))
072: throw new NotCompliantMBeanException(mbeanClass.getName()
073: + " must have be a concrete class.");
074:
075: // if(mbeanClass.isInterface())
076: // throw new NotCompliantMBeanException(mbeanClass.getNameSpace() + " must be a class.");
077: Class interfaceClass = getMBeanInterface(mbeanClass);
078: if (interfaceClass == null)
079: throw new NotCompliantMBeanException(
080: mbeanClass.getName()
081: + " does not implement the "
082: + mbeanClass.getName()
083: + "MBean interface or the javax.managementDynamicMBean interface");
084: if (!Modifier.isPublic(interfaceClass.getModifiers()))
085: throw new NotCompliantMBeanException(interfaceClass
086: .getName()
087: + " implemented by "
088: + mbeanClass.getName()
089: + " must be public.");
090: // check OK
091: return interfaceClass;
092: }
093:
094: // get the MBeanInterface of the MBean Class ,only for Standard MBean,return null for DynamicMBean
095: public Class getMBeanInterface(Class mbeanClass) {
096: if (isDynamic(mbeanClass))
097: return javax.management.DynamicMBean.class;
098: // test all the superClass ,from the base class
099: for (Class super Class = mbeanClass; (super Class != null)
100: && (!super Class.getName().equals(
101: java.lang.Object.class.getName()));) {
102: // foreach super class ,test all fatherInterfaces of it
103: Class[] fatherInterfaces = super Class.getInterfaces();
104: for (int i = 0; i < fatherInterfaces.length; i++) {
105: Class fatherInterface = fatherInterfaces[i];
106: if (fatherInterface.getName().equals(
107: super Class.getName() + "MBean")) {
108: return fatherInterface;
109: }
110:
111: // for each fatther interface , test all it's father interface
112: Class[] grandFatherInterfaces = fatherInterface
113: .getInterfaces();
114: for (int j = 0; j < grandFatherInterfaces.length; j++) {
115: Class grandFatherInterface = grandFatherInterfaces[j];
116: if (grandFatherInterface.getName().equals(
117: super Class.getName() + "MBean")) {
118: return grandFatherInterface;
119: }
120: }
121: }
122:
123: // test the super class along the base class
124: superClass = superClass.getSuperclass();
125: }
126: return null;
127: }
128: }
|