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

patterntesting.runtime.jmx.AnnotatedStandardMBean Maven / Gradle / Ivy

package patterntesting.runtime.jmx;

import java.lang.reflect.Method;
import java.util.*;

import javax.management.*;

/**
 * The Class AnnotatedStandardMBean.
 *
 * @author ninthbit
 *
 * StandardMBeans have meaningless default values with can be overcome
 * subclassing and annotations. This classed is based on the article
 * http://weblogs.java.net/blog/emcmanus/archive/2005/07/adding_informat.html
 */
public class AnnotatedStandardMBean extends StandardMBean {

	/**
	 * Instance where the MBean interface is implemented by another object.
	 *
	 * @param  not necessary but occasionally avoids compiler warnings about generics
	 * @param impl Class which implements an MBean interface
	 * @param mbeanInterface MBean interface
	 * @throws NotCompliantMBeanException thrown if MBean is not JMX compliant
	 */
	public  AnnotatedStandardMBean(final T impl, final Class mbeanInterface)
			throws NotCompliantMBeanException {
		super(impl, mbeanInterface);
	}

	/** Instance where the MBean interface is implemented by this object.
	 * @param mbeanInterface MBean interface
	 * @throws NotCompliantMBeanException thrown if MBean is not JMX compliant*/
	protected AnnotatedStandardMBean(final Class mbeanInterface)
			throws NotCompliantMBeanException {
		super(mbeanInterface);
	}

	/**
	 * Overrides the default description with the content
	 * a @Description annotation.
	 *
	 * @param op the op
	 * @return the description
	 * @see patterntesting.runtime.jmx.Description Description
	 */
	@Override
	protected String getDescription(final MBeanOperationInfo op) {
        String descr = op.getDescription();
        Method m = methodFor(getMBeanInterface(), op);
        return getDescriptionForMethod(descr, m);
	}

	/**
	 * Gets the description.
	 *
	 * @param info the info
	 * @return the description
	 * @see javax.management.StandardMBean#getDescription(javax.management.MBeanAttributeInfo)
	 */
	@Override
	protected String getDescription(final MBeanAttributeInfo info) {
		String description = info.getDescription();
		Method m = getMethodForAttribute(info);
		return getDescriptionForMethod(description, m);
	}

	private String getDescriptionForMethod(String descr, final Method m) {
		if (m != null) {
            Description d = m.getAnnotation(Description.class);
            if (d != null) {
                descr = d.value();
            }
        }
        return descr;
	}


	private Method getMethodForAttribute(final MBeanAttributeInfo info) {
		Method m = null;
		Iterator methodNames = constructPossibleMethodNames(info.getName()).iterator();
		boolean found = false;
		while (!found && methodNames.hasNext()) {
			try {
				m = getMBeanInterface().getMethod(methodNames.next(), new Class[0]);
				found = true;
			} catch (NoSuchMethodException e) {	found = false; }
		}
		return m;
	}

	private List constructPossibleMethodNames(final String attributeName) {
		List names = new ArrayList();
        String capitalizedVarName = attributeName.substring(0, 1).toUpperCase()
                + attributeName.substring(1);
		names.add("get" + capitalizedVarName);
		names.add("is" + capitalizedVarName);
		names.add("has" + capitalizedVarName);
		names.add("are" + capitalizedVarName);
		return names;
	}

	private static Method methodFor(final Class mbeanInterface,
			final MBeanOperationInfo op) {
		final MBeanParameterInfo[] params = op.getSignature();
		final String[] paramTypes = new String[params.length];
		for (int i = 0; i < params.length; i++) {
            paramTypes[i] = params[i].getType();
        }

		return findMethod(mbeanInterface, op.getName(), paramTypes);
	}

	private static Method findMethod(final Class mbeanInterface, final String name,
			final String... paramTypes) {
		try {
			final ClassLoader loader = mbeanInterface.getClassLoader();
			final Class[] paramClasses = new Class[paramTypes.length];
			for (int i = 0; i < paramTypes.length; i++) {
                paramClasses[i] = classForName(paramTypes[i], loader);
            }
			return mbeanInterface.getMethod(name, paramClasses);
		} catch (RuntimeException e) {
			// avoid accidentally catching unexpected runtime exceptions
			throw e;
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * Class for name.
	 *
	 * @param name the name
	 * @param loader the loader
	 * @return the class
	 * @throws ClassNotFoundException the class not found exception
	 */
	static Class classForName(final String name, final ClassLoader loader)
			throws ClassNotFoundException {
		Class c = primitiveClasses.get(name);
		if (c == null) {
            c = Class.forName(name, false, loader);
        }
		return c;
	}

	private static final Map> primitiveClasses = new HashMap>();
	static {
		Class[] prims = { byte.class, short.class, int.class, long.class,
				float.class, double.class, char.class, boolean.class, };
		for (Class c : prims) {
            primitiveClasses.put(c.getName(), c);
        }
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy