001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.mx.metadata;
023:
024: import javax.management.DynamicMBean;
025: import javax.management.NotCompliantMBeanException;
026:
027: /**
028: * Holds the type of an MBean class.
029: *
030: * The introspection algorithm used is the following:
031: *
032: * 1. If MyClass is an instance of the DynamicMBean interface, then the return value of its getMBeanInfo method will
033: * list the attributes and operations of the resource. In other words, MyClass is a dynamic MBean.
034: *
035: * 2. If the MyClass MBean is an instance of a MyClassMBean interface, then only the methods listed in, or inherited by,
036: * the interface are considered among all the methods of, or inherited by, the MBean. The design patterns are then used to
037: * identify the attributes and operations from the method names in the MyClassMBean interface and its ancestors.
038: * In other words, MyClass is a standard MBean.
039: *
040: * 3. If MyClass is an instance of the DynamicMBean interface, then MyClassMBean is ignored.
041: * If MyClassMBean is not a public interface, it is not a JMX manageable resource.
042: * If the MBean is an instance of neither MyClassMBean nor DynamicMBean, the inheritance tree of MyClass is examined,
043: * looking for the nearest superclass that implements its own MBean interface.
044: *
045: * a. If there is an ancestor called SuperClass that is an instance of SuperClassMBean, the design patterns
046: * are used to derive the attributes and operations from SuperClassMBean. In this case, the MBean MyClass then
047: * has the same management interface as the MBean SuperClass. If SuperClassMBean is not a public interface,
048: * it is not a JMX manageable resource.
049: *
050: * b. When there is no superclass with its own MBean interface, MyClass is not a JMX manageable resource.
051: *
052: * @author <a href="mailto:trevor@protocool.com">Trevor Squires</a>.
053: * @author thomas.diesler@jboss.org
054: */
055: public class MBeanCapability {
056: public static final int DYNAMIC_MBEAN = 0x321;
057: public static final int STANDARD_MBEAN = 0x123;
058: public static final int NOT_AN_MBEAN = 0xc0de;
059:
060: protected int mbeanType = NOT_AN_MBEAN;
061:
062: private MBeanCapability(int type) {
063: mbeanType = type;
064: }
065:
066: public int getMBeanType() {
067: return mbeanType;
068: }
069:
070: public static MBeanCapability of(Class mbeanClass)
071: throws NotCompliantMBeanException {
072: if (null == mbeanClass) {
073: throw new IllegalArgumentException(
074: "MBean class cannot be null");
075: }
076:
077: // If MyClass is an instance of the DynamicMBean interface, MyClass is a dynamic MBean.
078: if (DynamicMBean.class.isAssignableFrom(mbeanClass)) {
079: return new MBeanCapability(DYNAMIC_MBEAN);
080: }
081:
082: // If the MyClass MBean is an instance of a MyClassMBean interface, MyClass is a standard MBean
083: Class[] interfaces = mbeanClass.getInterfaces();
084: for (int i = 0; i < interfaces.length; i++) {
085: Class anInterface = interfaces[i];
086: if (anInterface.getName().equals(
087: mbeanClass.getName() + "MBean")) {
088: return new MBeanCapability(STANDARD_MBEAN);
089: }
090: }
091:
092: // If there is an ancestor called SuperClass that is an instance of SuperClassMBean
093: Class super Class = mbeanClass.getSuperclass();
094: if (super Class != null)
095: return of(super Class);
096:
097: throw new NotCompliantMBeanException(
098: "Class does not expose a management interface: "
099: + mbeanClass.getName());
100: }
101:
102: }
|