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

com.mycila.jmx.BeanProperty Maven / Gradle / Ivy

There is a newer version: 3.9
Show newest version
/**
 * Copyright (C) 2010 Mycila ([email protected])
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mycila.jmx;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author Mathieu Carbou ([email protected])
 */
public final class BeanProperty implements AnnotatedElement {
    private Method readMethod;
    private Method writeMethod;
    private final Class type;
    private final String name;

    private BeanProperty(String name, Method readMethod, Method writeMethod) {
        if (readMethod == null && writeMethod == null)
            throw new IllegalArgumentException("Invalid property " + name + ": missing at least one accessor method");
        if (readMethod != null && writeMethod != null && !readMethod.getReturnType().equals(writeMethod.getParameterTypes()[0]))
            throw new IllegalArgumentException("return type differs: " + readMethod.getReturnType() + " and " + writeMethod.getParameterTypes()[0]);
        this.name = name;
        this.type = readMethod != null ? readMethod.getReturnType() : writeMethod.getParameterTypes()[0];
        this.readMethod = readMethod;
        this.writeMethod = writeMethod;
    }

    public Method getReadMethod() {
        return readMethod;
    }

    public Method getWriteMethod() {
        return writeMethod;
    }

    public Class getType() {
        return type;
    }

    public String getName() {
        return name;
    }

    public boolean isReadable() {
        return readMethod != null;
    }

    public boolean isWritable() {
        return writeMethod != null;
    }

    public void clearReadable() {
        readMethod = null;
    }

    public void clearWritable() {
        writeMethod = null;
    }

    public Object get(Object o) throws Throwable {
        if (!isReadable())
            throw new IllegalStateException("Property not readable: " + this);
        if (!getReadMethod().isAccessible())
            getReadMethod().setAccessible(true);
        try {
            Object res = getReadMethod().invoke(o);
            if (!ClassUtils.isAssignableValue(getType(), res))
                throw new IllegalArgumentException("Invalid property: got type " + res.getClass().getName() + " but expect " + getType().getName());
            return res;
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        }
    }

    public void set(Object o, Object value) throws Throwable {
        if (!isWritable())
            throw new IllegalStateException("Property not writable: " + this);
        if (!getWriteMethod().isAccessible())
            getWriteMethod().setAccessible(true);
        try {
            getWriteMethod().invoke(o, value);
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        }
    }

    @Override
    public  A getAnnotation(Class annotationClass) {
        A annot = null;
        if (isReadable())
            annot = getReadMethod().getAnnotation(annotationClass);
        if (annot == null && isWritable())
            annot = getWriteMethod().getAnnotation(annotationClass);
        return annot;
    }

    @Override
    public boolean isAnnotationPresent(Class annotationClass) {
        return isReadable() && getReadMethod().isAnnotationPresent(annotationClass)
            || isWritable() && getWriteMethod().isAnnotationPresent(annotationClass);
    }

    @Override
    public Annotation[] getAnnotations() {
        Annotation[] annots = new Annotation[0];
        if (isReadable())
            annots = getReadMethod().getAnnotations();
        if (annots.length == 0 && isWritable())
            annots = getWriteMethod().getAnnotations();
        return annots;
    }

    @Override
    public Annotation[] getDeclaredAnnotations() {
        Annotation[] annots = new Annotation[0];
        if (isReadable())
            annots = getReadMethod().getDeclaredAnnotations();
        if (annots.length == 0 && isWritable())
            annots = getWriteMethod().getDeclaredAnnotations();
        return annots;
    }

    @Override
    public String toString() {
        return ClassUtils.getQualifiedName(getType()) + " " + getName();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        BeanProperty that = (BeanProperty) o;
        return getName().equals(that.getName()) && getType().equals(that.getType());
    }

    @Override
    public int hashCode() {
        int result = getType().hashCode();
        result = 31 * result + getName().hashCode();
        return result;
    }

    public static BeanProperty findProperty(Class clazz, Method method) {
        if (ReflectionUtils.isIsMethod(method))
            return findProperty(clazz, StringUtils.uncapitalize(method.getName().substring(2)), method.getReturnType());
        if (ReflectionUtils.isGetMethod(method))
            return findProperty(clazz, StringUtils.uncapitalize(method.getName().substring(3)), method.getReturnType());
        if (ReflectionUtils.isSetter(method))
            return findProperty(clazz, StringUtils.uncapitalize(method.getName().substring(3)), method.getParameterTypes()[0]);
        return null;
    }

    public static BeanProperty findProperty(Class clazz, String property) {
        return findProperty(clazz, property, null);
    }

    public static BeanProperty findProperty(Class clazz, String property, Class type) {
        String name = StringUtils.capitalize(property);
        Method is = ReflectionUtils.findMethod(clazz, "is" + name, type, new Class[0]);
        Method get = ReflectionUtils.findMethod(clazz, "get" + name, type, new Class[0]);
        Method setter = ReflectionUtils.findMethod(clazz, "set" + name, Void.TYPE, type);
        Method getter = get != null ? get : is;
        if (setter == null && getter == null
            || setter != null && getter != null && !setter.getParameterTypes()[0].equals(getter.getReturnType()))
            return null;
        return new BeanProperty(property, getter, setter);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy