All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.mx.metadata.StandardMetaData Maven / Gradle / Ivy

There is a newer version: 6.0.0.M1
Show newest version
/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.mx.metadata;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.management.IntrospectionException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationBroadcaster;

/**
 * This metadata builder implementation builds a MBean info based on the
 * naming rules of the Standard MBeans. The MBean server uses this builder
 * to generate the metadata for Standard MBeans.  

* * In cooperation with the * {@link MBeanInfoConversion#toModelMBeanInfo MBeanInfoConversion} class you * can use this builder as a migration tool from Standard to Model MBeans, or * for cases where you want the management interface be based on a compile-time * type safe interface. It is also possible to subclass this builder * implementation to extend it to support more sophisticated introspection rules * such as adding descriptors to management interface elements. * * @author Juha Lindfors. * @author Trevor Squires. * @author Thomas Diesler. * @author Dimitris Andreadis. */ public class StandardMetaData extends AbstractBuilder { // Attributes ---------------------------------------------------- /** * The MBean object instance. * Can be null. */ private Object mbeanInstance = null; /** * The class of the MBean instance. */ private Class mbeanClass = null; /** * The interface used as a basis for constructing the MBean metadata. */ private Class mbeanInterface = null; // Static -------------------------------------------------------- /** * Locates an interface for a class that matches the Standard MBean naming * convention. * * @param mbeanClass the class to investigate * * @return the Standard MBean interface class or null if not found */ public static Class findStandardInterface(Class mbeanClass) { Class concrete = mbeanClass; Class stdInterface = null; while (null != concrete) { stdInterface = findStandardInterface(concrete, concrete.getInterfaces()); if (null != stdInterface) { return stdInterface; } concrete = concrete.getSuperclass(); } return null; } private static Class findStandardInterface(Class concrete, Class[] interfaces) { String stdName = concrete.getName() + "MBean"; Class retval = null; // look to see if this class implements MBean std interface for (int i = 0; i < interfaces.length; ++i) { if (interfaces[i].getName().equals(stdName)) { retval = interfaces[i]; break; } } return retval; } // Constructors -------------------------------------------------- /** * Initializes the Standard metadata builder. The JMX metadata is based * on the class of the given resource instance. * * @param mbeanInstance MBean instance */ public StandardMetaData(Object mbeanInstance) throws NotCompliantMBeanException { this(mbeanInstance.getClass()); this.mbeanInstance = mbeanInstance; } /** * Initializes the Standard metadata builder. The JMX metadata is based * on the given class. * * @param mbeanClass resource class that implements an interface * adhering to the Standard MBean naming conventions */ public StandardMetaData(Class mbeanClass) throws NotCompliantMBeanException { this.mbeanClass = mbeanClass; this.mbeanInterface = StandardMetaData.findStandardInterface(mbeanClass); if (this.mbeanInterface == null) throw new NotCompliantMBeanException("Cannot obtain management interface for: " + mbeanClass); } /** * Initializes the Standard metadata builder. The JMX metadata is based * on the passed mbean interface. * * @param mbInstance MBean instance * @param mbInterface the management interface */ public StandardMetaData(Object mbInstance, Class mbInterface) throws NotCompliantMBeanException { this.mbeanInstance = mbInstance; this.mbeanClass = mbInstance.getClass(); this.mbeanInterface = mbInterface; // search for it if (this.mbeanInterface == null) this.mbeanInterface = StandardMetaData.findStandardInterface(mbeanClass); if (this.mbeanInterface == null) throw new NotCompliantMBeanException("Cannot obtain management interface for: " + mbeanClass); if (this.mbeanInterface.isInterface() == false) throw new NotCompliantMBeanException("Management interface is not an interface: " + mbeanInterface); } /** * Retrieve the management interface */ public Class getMBeanInterface() { return mbeanInterface; } // MetaDataBuilder implementation -------------------------------- public MBeanInfo build() throws NotCompliantMBeanException { try { // First check the mbean instance implements the interface if (mbeanInterface == null) throw new NotCompliantMBeanException("The mbean does not implement a management interface"); if (mbeanInstance != null && mbeanInterface.isInstance(mbeanInstance) == false) throw new NotCompliantMBeanException("The mbean does not implement its management interface " + mbeanInterface.getName()); // First build the constructors Constructor[] constructors = mbeanClass.getConstructors(); MBeanConstructorInfo[] constructorInfo = new MBeanConstructorInfo[constructors.length]; for (int i = 0; i < constructors.length; ++i) { constructorInfo[i] = new MBeanConstructorInfo("MBean Constructor.", constructors[i]); } // Next we have to figure out how the methods in the mbean class map // to attributes and operations Method[] methods = mbeanInterface.getMethods(); HashMap getters = new HashMap(); HashMap setters = new HashMap(); HashMap operInfo = new HashMap(); List attrInfo = new ArrayList(); for (int i = 0; i < methods.length; ++i) { String methodName = methods[i].getName(); Class[] signature = methods[i].getParameterTypes(); Class returnType = methods[i].getReturnType(); if (methodName.startsWith("set") && methodName.length() > 3 && signature.length == 1 && returnType == Void.TYPE) { String key = methodName.substring(3, methodName.length()); Method setter = (Method) setters.get(key); if (setter != null && setter.getParameterTypes()[0].equals(signature[0]) == false) { throw new IntrospectionException("overloaded type for attribute set: " + key); } setters.put(key, methods[i]); } else if (methodName.startsWith("get") && methodName.length() > 3 && signature.length == 0 && returnType != Void.TYPE) { String key = methodName.substring(3, methodName.length()); Method getter = (Method) getters.get(key); if (getter != null && getter.getName().startsWith("is")) { throw new IntrospectionException("mixed use of get/is for attribute " + key); } getters.put(key, methods[i]); } else if (methodName.startsWith("is") && methodName.length() > 2 && signature.length == 0 && isBooleanReturn(returnType)) { String key = methodName.substring(2, methodName.length()); Method getter = (Method) getters.get(key); if (getter != null && getter.getName().startsWith("get")) { throw new IntrospectionException("mixed use of get/is for attribute " + key); } getters.put(key, methods[i]); } else { MBeanOperationInfo info = new MBeanOperationInfo("MBean Operation.", methods[i]); operInfo.put(getSignatureString(methods[i]), info); } } Object[] keys = getters.keySet().toArray(); for (int i = 0; i < keys.length; ++i) { String attrName = (String) keys[i]; Method getter = (Method) getters.remove(attrName); Method setter = (Method) setters.remove(attrName); MBeanAttributeInfo info = new MBeanAttributeInfo(attrName, "MBean Attribute.", getter, setter); attrInfo.add(info); } Iterator it = setters.keySet().iterator(); while (it.hasNext()) { String attrName = (String) it.next(); Method setter = (Method) setters.get(attrName); MBeanAttributeInfo info = new MBeanAttributeInfo(attrName, "MBean Attribute.", null, setter); attrInfo.add(info); } // save away the attribute and operation info objects MBeanAttributeInfo[] attributeInfo = (MBeanAttributeInfo[]) attrInfo.toArray(new MBeanAttributeInfo[0]); MBeanOperationInfo[] operationInfo = (MBeanOperationInfo[]) operInfo.values().toArray(new MBeanOperationInfo[0]); // if the builder was initialized with the resource instance, check if // it is a notification broadcaster, and add the appropriate notifications // to the interface. MBeanNotificationInfo[] notifications = null; if (mbeanInstance instanceof NotificationBroadcaster) { notifications = ((NotificationBroadcaster) mbeanInstance).getNotificationInfo(); } else { notifications = new MBeanNotificationInfo[0]; } return new MBeanInfo(mbeanClass.getName(), "Management Bean.", attributeInfo, constructorInfo, operationInfo, notifications); } catch (IntrospectionException e) { throw new NotCompliantMBeanException(e.getMessage()); } } /** * JMX standard specifies that only "boolean isX()" style methods * represent attributes. "Boolean isX()" methods map to operations. */ private boolean isBooleanReturn(Class returnType) { return returnType == Boolean.TYPE; } protected String getSignatureString(Method method) { String name = method.getName(); Class[] signature = method.getParameterTypes(); StringBuffer buffer = new StringBuffer(512); buffer.append(name); buffer.append("("); if (signature != null) { for (int i = 0; i < signature.length; i++) { buffer.append(signature[i].getName()); if (i < signature.length-1) buffer.append(","); } } buffer.append(")"); return buffer.toString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy