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

com.gitee.feizns.bean.DefaultPropertyImpl Maven / Gradle / Ivy

There is a newer version: 5.5-RELEASE
Show newest version
package com.gitee.feizns.bean;

import com.gitee.feizns.convert.ConvertUtils;
import com.gitee.feizns.reflect.MethodUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;

/**
 * @author feizns
 * @since 2019/6/9 0009
 */
class DefaultPropertyImpl implements Property {

    /**
     * 字段
     */
    private Field field;

    /**
     *
     */
    private Object target;

    /**
     * 读方法
     */
    private Method readMethod;

    /**
     * 写方法
     */
    private Method writeMethod;

    /**
     *
     */
    private String name;

    public DefaultPropertyImpl(Object target, String propertyName) {
        this(target, propertyName, null);
        this.name = propertyName;
        if ( target != null ) {
            this.target = target;
            Class targetType = target.getClass();
            this.readMethod = PropertyUtils.getReadMethod(targetType, propertyName);
            this.field = PropertyUtils.getField(targetType, propertyName);
            Class propertyClass = getPropertyClass(field, readMethod);
            if ( propertyClass != null )
                this.writeMethod = PropertyUtils.getWriteMethod(targetType, propertyName, propertyClass);
        }
    }

    public DefaultPropertyImpl(Object target, String propertyName, Class propertyClass) {
        this.name = propertyName;
        if ( target != null ) {
            this.target = target;
            Class targetType = target.getClass();
            this.readMethod = PropertyUtils.getReadMethod(targetType, propertyName);
            this.field = PropertyUtils.getField(targetType, propertyName);
            Class pClz = getPropertyClass(field, readMethod);
            propertyClass = pClz != null ? pClz : propertyClass;
            if ( propertyClass != null )
                this.writeMethod = PropertyUtils.getWriteMethod(targetType, propertyName, propertyClass);
        }
    }

    private static Class getPropertyClass(Field field, Method readMethod) {
        return field != null ? field.getType() : (readMethod != null ? readMethod.getReturnType() : null);
    }

    @Override
    public D val() {
        return readMethod != null ? (D) MethodUtils.invoke(target, readMethod) : null;
    }

    @Override
    public  R val(Class targetType) {
        return ConvertUtils.to(val(), targetType);
    }

    @Override
    public D getAndSet(D newVal) {
        D oldVal = val();
        set(newVal);
        return oldVal;
    }

    @Override
    public Property set(Object newVal) {
        if ( writeMethod != null ) {
            Object realNewVal = ConvertUtils.to(newVal, writeMethod.getParameterTypes()[0]);
            MethodUtils.invoke(target, writeMethod, realNewVal);
        }
        return this;
    }

    @Override
    public String name() {
        return name;
    }

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

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

    @Override
    public Object getTarget() {
        return target;
    }

    @Override
    public Field getField() {
        return field;
    }

    @Override
    public Method readMethod() {
        return readMethod;
    }

    @Override
    public Method writeMethod() {
        return writeMethod;
    }

    //字段优先.
    @Override
    public  T getAnnotation(Class annotationClass) {
        Stream elements = annotatedElements().filter(item -> item.isAnnotationPresent(annotationClass));
        Optional annotatedElement = elements.findFirst();
        return annotatedElement.isPresent() ? annotatedElement.get().getAnnotation(annotationClass) : null;
    }

    @Override
    public Annotation[] getAnnotations() {
        return annotatedElements().flatMap(item -> Arrays.stream(item.getAnnotations())).toArray(Annotation[]::new);
    }

    @Override
    public Annotation[] getDeclaredAnnotations() {
        return annotatedElements().flatMap(item -> Arrays.stream(item.getDeclaredAnnotations())).toArray(Annotation[]::new);
    }

    //字段优先
    private Stream annotatedElements() {
        return Arrays.stream(new AnnotatedElement[]{ field, readMethod, writeMethod }).filter(Objects::nonNull);
    }

    @Override
    public String toString() {
        StringBuilder ret = new StringBuilder();
        ret.append("Property [ name = ").append(name).append(", ");
        ret.append("field = ").append(field).append(", ");
        ret.append("target = ").append(target).append(", ");
        ret.append("readMethod = ").append(readMethod).append(", ");
        ret.append("writeMethod = ").append(writeMethod).append(" ]");
        return ret.toString();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy