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

io.github.wycst.wast.common.reflect.SetterInfo Maven / Gradle / Ivy

package io.github.wycst.wast.common.reflect;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;

public class SetterInfo {

    // field of class
    Field field;
    // field memory offset
    long fieldOffset = -1;
    private String name;
    private Class parameterType;

    private Class actualTypeArgument;

    // 索引位置, 当宿主类型为record时或者通过构造方法设置对象的属性值时使用
    private int index;

    /**
     * 泛型信息
     * Generic information
     */
    private GenericParameterizedType genericParameterizedType;

    /**
     * 非实例化类型
     * (排除集合或者map后的接口或者抽象类,无法通过new创建实例对象)
     */
    private boolean nonInstanceType;

    // 注解集合
    private Map, Annotation> annotations;

    // 是否存在默认值
    private Boolean existDefault;
    private boolean fieldDisabled;

    public static SetterInfo fromField(Field field) {
        boolean primitive = field.getType().isPrimitive();
        SetterInfo setterInfo = primitive ? new PrimitiveImpl() : new SetterInfo();
        setterInfo.setField(field);
        return setterInfo;
    }

    public final boolean isInstance(Object target) {
        return field.getDeclaringClass().isInstance(target);
    }

    public void invoke(Object target, Object value) {
        target.getClass();
        if ((parameterType.isInstance(value) || value == null) && isInstance(target)) {
            invokeInternal(target, value);
        } else {
            throw new SecurityException("invoke error: parameter mismatch");
        }
    }

    void invokeInternal(Object target, Object value) {
        UnsafeHelper.UNSAFE.putObject(target, fieldOffset, value);
    }

    public final String getName() {
        return name;
    }

    void setName(String name) {
        this.name = name;
    }

    public final Class getParameterType() {
        return parameterType;
    }

    void setParameterType(Class parameterType) {
        this.parameterType = parameterType;
    }

    public final Class getActualTypeArgument() {
        return actualTypeArgument;
    }

    void setActualTypeArgument(Class actualTypeArgument) {
        this.actualTypeArgument = actualTypeArgument;
    }

    public final boolean isNonInstanceType() {
        return nonInstanceType;
    }

    void setNonInstanceType(boolean nonInstanceType) {
        this.nonInstanceType = nonInstanceType;
    }

    void setAnnotations(Map, Annotation> annotations) {
        this.annotations = annotations;
    }

    void setField(Field field) {
        this.field = field;
        try {
            this.fieldOffset = UnsafeHelper.objectFieldOffset(field);
        } catch (Throwable throwable) {
            this.fieldOffset = -1;
        }
    }

    public final GenericParameterizedType getGenericParameterizedType() {
        return genericParameterizedType;
    }

    void setGenericParameterizedType(GenericParameterizedType genericParameterizedType) {
        this.genericParameterizedType = genericParameterizedType;
    }

    Object getDefaultFieldValue(Object instance) {
        try {
            if (existDefault == Boolean.FALSE) {
                return null;
            }
            Object fieldValue = getFieldValue(instance);
            this.existDefault = fieldValue != null;
            if (fieldValue != null) {
                return fieldValue;
            }
        } catch (Exception e) {
            existDefault = Boolean.FALSE;
        }
        return null;
    }

    Object getFieldValue(Object instance) throws IllegalAccessException {
        return UnsafeHelper.getObjectValue(instance, fieldOffset);
    }

    public final Annotation getAnnotation(Class annotationType) {
        return annotations.get(annotationType);
    }

    public boolean isMethod() {
        return false;
    }

    public boolean isPrivate() {
        return Modifier.isPrivate(field.getModifiers());
    }

    public final int getIndex() {
        return index;
    }

    void setIndex(int index) {
        this.index = index;
    }

    void setFieldDisabled(boolean disabled) {
        this.fieldDisabled = disabled;
    }

    public boolean isFieldDisabled() {
        return fieldDisabled;
    }

    static final class FieldImpl extends SetterInfo {
        void setField(Field field) {
            this.field = field;
        }

        public void invoke(Object target, Object value) {
            invokeInternal(target, value);
        }

        Object getFieldValue(Object instance) throws IllegalAccessException {
            return field.get(instance);
        }

        void invokeInternal(Object target, Object value) {
            try {
                field.set(target, value);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
    }

    static final class PrimitiveImpl extends SetterInfo {
        private ReflectConsts.PrimitiveType primitiveType;

        public void invoke(Object target, Object value) {
            if (isInstance(target)) {
                primitiveType.put(target, fieldOffset, value);
            } else {
                throw new SecurityException("invoke error: parameter mismatch");
            }
        }

        @Override
        void invokeInternal(Object target, Object value) {
            primitiveType.putValue(target, fieldOffset, value);
        }

        Object getFieldValue(Object instance) {
            return primitiveType.get(instance, fieldOffset);
        }

        void setField(Field field) {
            super.setField(field);
            this.primitiveType = ReflectConsts.PrimitiveType.typeOf(field.getType());
        }
    }
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy