AnnotatedStandardMBean.java 8.16 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.granite.jmx.annotation;

import com.adobe.granite.jmx.annotation.Description;
import com.adobe.granite.jmx.annotation.Impact;
import com.adobe.granite.jmx.annotation.Name;
import com.adobe.granite.jmx.internal.Utils;
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;

/*
 * This class specifies class file version 49.0 but uses Java 6 signatures.  Assumed Java 6.
 */
public class AnnotatedStandardMBean
extends StandardMBean {
    private static final Logger log = LoggerFactory.getLogger(AnnotatedStandardMBean.class);

    public <T> AnnotatedStandardMBean(T implementation, Class<T> mbeanInterface) throws NotCompliantMBeanException {
        super(implementation, mbeanInterface);
    }

    protected AnnotatedStandardMBean(Class<?> mbeanInterface) throws NotCompliantMBeanException {
        super(mbeanInterface);
    }

    @Override
    protected String getDescription(MBeanInfo info) {
        Description res = this.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 = this.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());
                continue;
            }
            catch (Exception e) {
                log.warn("Error accessing bean constructor", (Throwable)e);
                results[i] = info;
            }
        }
        return results;
    }

    @Override
    protected String getParameterName(MBeanConstructorInfo ctor, MBeanParameterInfo param, int sequence) {
        Name desc = this.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 = this.getParamAnnotation(ctor, sequence, Description.class);
        return desc == null ? super.getDescription(ctor, param, sequence) : desc.value();
    }

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

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

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

    @Override
    protected String getParameterName(MBeanOperationInfo op, MBeanParameterInfo param, int sequence) {
        Name desc = this.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 = this.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(), this.getMBeanInterface().getClassLoader());
        }
        return this.getImplementationClass().getConstructor(params);
    }

    protected <T extends Annotation> T getAnnotation(MBeanAttributeInfo info, Class<T> a) throws NoSuchMethodException, ClassNotFoundException {
        if (info.isReadable()) {
            T res = this.getReadMethod(info).getAnnotation(a);
            if (res != null) {
                return res;
            }
            if (!info.isWritable()) {
                return null;
            }
        }
        return this.getWriteMethod(info).getAnnotation(a);
    }

    protected <T extends Annotation> T getParamAnnotation(MBeanConstructorInfo ctor, int sequence, Class<T> clazz) {
        try {
            Constructor c = this.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())) continue;
                return (T)a1;
            }
            return null;
        }
        catch (Exception e) {
            log.warn("Error accessing bean method", (Throwable)e);
            return null;
        }
    }

    protected <T extends Annotation> T getParamAnnotation(MBeanOperationInfo op, int sequence, Class<T> clazz) {
        try {
            Method m = this.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())) continue;
                return (T)a1;
            }
            return null;
        }
        catch (Exception e) {
            log.warn("Error accessing bean method", (Throwable)e);
            return null;
        }
    }

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

    protected Method getWriteMethod(MBeanAttributeInfo info) throws NoSuchMethodException, ClassNotFoundException {
        return this.getMBeanInterface().getMethod("set" + info.getName(), Utils.loadClass(info.getType(), this.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(), this.getMBeanInterface().getClassLoader());
        }
        return this.getMBeanInterface().getMethod(info.getName(), params);
    }
}