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

com.adobe.granite.jmx.annotation.AnnotatedStandardMBean Maven / Gradle / Ivy

/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2011 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/
package com.adobe.granite.jmx.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.NotCompliantMBeanException;
import javax.management.StandardMBean;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.adobe.granite.jmx.internal.Utils;

/**
 * The extension of {@link StandardMBean} that will automatically provide JMX
 * metadata through annotations.
 * 
 * @see MBeanInfo
 * @see Description
 * @see Name
 * @see Impact
 */
public class AnnotatedStandardMBean extends StandardMBean {
    private static final Logger log = LoggerFactory.getLogger(AnnotatedStandardMBean.class);

    /**
     * Make a DynamicMBean out of the object implementation, using the specified
     * mbeanInterface class.
     * 
     * @param implementation The implementation of this MBean.
     * @param mbeanInterface The Management Interface exported by this MBean's
     * implementation. If null, then this object will use standard JMX design pattern to
     * determine the management interface associated with the given implementation.
     * @param  Allows the compiler to check that implementation does indeed implement
     * the class described by mbeanInterface. The compiler can only check this if
     * mbeanInterface is a class literal such as MyMBean.class.
     * @throws javax.management.NotCompliantMBeanException if the mbeanInterface does not
     * follow JMX design patterns for Management Interfaces, or if the given
     * implementation does not implement the specified interface.
     * 
     * @see StandardMBean#StandardMBean(Object, Class)
     */
    public  AnnotatedStandardMBean(T implementation, Class mbeanInterface)
            throws NotCompliantMBeanException {
        super(implementation, mbeanInterface);
    }
    
    protected AnnotatedStandardMBean(Class mbeanInterface)
            throws NotCompliantMBeanException {
        super(mbeanInterface);
    }
    
    @Override
    protected String getDescription(MBeanInfo info) {
        Description res = (Description) getMBeanInterface().getAnnotation(Description.class);
        return res == null ? super.getDescription(info) : res.value();
    }

    @Override
    protected MBeanConstructorInfo[] getConstructors(
            MBeanConstructorInfo[] ctors, Object impl) {
        MBeanConstructorInfo[] results = new MBeanConstructorInfo[ctors.length];

        for (int i = 0; i < ctors.length; i++) {
            MBeanConstructorInfo info = ctors[i];
            try {
                String name = info.getName();

                Constructor c = getConstructor(info);

                Description res = c.getAnnotation(Description.class);
                String desc = res == null
                        ? super.getDescription(info)
                        : res.value();

                results[i] = new MBeanConstructorInfo(name, desc,
                    info.getSignature());
            } catch (Exception e) {
                log.warn("Error accessing bean constructor", e);
                results[i] = info;
            }
        }

        return results;
    }

    @Override
    protected String getParameterName(MBeanConstructorInfo ctor,
            MBeanParameterInfo param, int sequence) {
        Name desc = getParamAnnotation(ctor, sequence, Name.class);

        return desc == null
                ? super.getParameterName(ctor, param, sequence)
                : desc.value();
    }

    @Override
    protected String getDescription(MBeanConstructorInfo ctor,
            MBeanParameterInfo param, int sequence) {
        Description desc = getParamAnnotation(ctor, sequence, Description.class);

        return desc == null
                ? super.getDescription(ctor, param, sequence)
                : desc.value();
    }

    @Override
    protected String getDescription(MBeanAttributeInfo info) {
        try {
            Description desc = getAnnotation(info, Description.class);
            return desc == null ? super.getDescription(info) : desc.value();
        } catch (Exception e) {
            log.warn("Error accessing bean method", e);
            return super.getDescription(info);
        }
    }

    @Override
    protected String getDescription(MBeanOperationInfo info) {
        try {
            Description res = getMethod(info).getAnnotation(Description.class);
            return res == null ? super.getDescription(info) : res.value();
        } catch (Exception e) {
            log.warn("Error accessing bean method", e);
            return super.getDescription(info);
        }
    }

    @Override
    protected int getImpact(MBeanOperationInfo info) {
        try {
            Impact res = getMethod(info).getAnnotation(Impact.class);
            return res == null ? super.getImpact(info) : res.value();
        } catch (Exception e) {
            log.warn("Error accessing bean method", e);
            return super.getImpact(info);
        }
    }

    @Override
    protected String getParameterName(MBeanOperationInfo op,
            MBeanParameterInfo param, int sequence) {
        Name desc = getParamAnnotation(op, sequence, Name.class);

        return desc == null
                ? super.getParameterName(op, param, sequence)
                : desc.value();
    }

    @Override
    protected String getDescription(MBeanOperationInfo op,
            MBeanParameterInfo param, int sequence) {
        Description desc = getParamAnnotation(op, sequence, Description.class);

        return desc == null
                ? super.getDescription(op, param, sequence)
                : desc.value();
    }

    protected Constructor getConstructor(MBeanConstructorInfo info)
            throws ClassNotFoundException, NoSuchMethodException {
        MBeanParameterInfo[] sig = info.getSignature();

        Class[] params = new Class[info.getSignature().length];
        for (int i = 0; i < sig.length; i++) {
            MBeanParameterInfo p = sig[i];
            params[i] = Utils.loadClass(p.getType(),
                getMBeanInterface().getClassLoader());
        }

        return getImplementationClass().getConstructor(params);
    }

    protected  T getAnnotation(MBeanAttributeInfo info,
            Class a) throws NoSuchMethodException, ClassNotFoundException {
        if (info.isReadable()) {
            T res = getReadMethod(info).getAnnotation(a);

            if (res != null) {
                return res;
            }

            if (!info.isWritable()) {
                return null;
            }
        }

        return getWriteMethod(info).getAnnotation(a);
    }

    protected  T getParamAnnotation(
            MBeanConstructorInfo ctor, int sequence, Class clazz) {
        try {
            Constructor c = getConstructor(ctor);
            Annotation[][] anns = c.getParameterAnnotations();
            Annotation[] a = anns[sequence];

            for (int i = 0; i < a.length; i++) {
                Annotation a1 = a[i];
                if (clazz.isAssignableFrom(a1.getClass())) {
                    return (T) a1;
                }
            }

            return null;
        } catch (Exception e) {
            log.warn("Error accessing bean method", e);
            return null;
        }
    }

    protected  T getParamAnnotation(
            MBeanOperationInfo op, int sequence, Class clazz) {
        try {
            Method m = getMethod(op);
            Annotation[][] anns = m.getParameterAnnotations();
            Annotation[] a = anns[sequence];

            for (int i = 0; i < a.length; i++) {
                Annotation a1 = a[i];
                if (clazz.isAssignableFrom(a1.getClass())) {
                    return (T) a1;
                }
            }

            return null;
        } catch (Exception e) {
            log.warn("Error accessing bean method", e);
            return null;
        }
    }

    protected Method getReadMethod(MBeanAttributeInfo info)
            throws NoSuchMethodException {
        if (info.isIs()) {
            return getMBeanInterface().getMethod("is" + info.getName(),
                new Class[0]);
        }

        return getMBeanInterface().getMethod("get" + info.getName(),
            new Class[0]);
    }

    protected Method getWriteMethod(MBeanAttributeInfo info)
            throws NoSuchMethodException, ClassNotFoundException {
        return getMBeanInterface().getMethod(
            "set" + info.getName(),
            new Class[] { Utils.loadClass(info.getType(),
                getMBeanInterface().getClassLoader()) });
    }

    protected Method getMethod(MBeanOperationInfo info)
            throws ClassNotFoundException, NoSuchMethodException {
        MBeanParameterInfo[] sig = info.getSignature();

        Class[] params = new Class[info.getSignature().length];
        for (int i = 0; i < sig.length; i++) {
            MBeanParameterInfo p = sig[i];
            params[i] = Utils.loadClass(p.getType(),
                getMBeanInterface().getClassLoader());
        }

        return getMBeanInterface().getMethod(info.getName(), params);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy