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

org.test4j.mock.props.FakeProperties Maven / Gradle / Ivy

package org.test4j.mock.props;

import org.test4j.Logger;
import org.test4j.mock.Stubs;

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

/**
 * 将对象属性设置为stub对象
 *
 * @author wudarui
 */
@SuppressWarnings({"unchecked", "rawtypes"})
public class FakeProperties {
    private final Object target;

    private final Class klass;

    public FakeProperties(Object target) {
        if (target == null) {
            throw new RuntimeException("The target object can't be null.");
        }
        this.target = target;
        this.klass = target.getClass();
    }

    /**
     * 对所有空属性进行赋值, 包括父类定义的字段
     *
     * @return 被设置的属性对象列表
     */
    public Map fakeNullProperties() {
        return this.fakeProperties(f -> f.get(target) == null);
    }

    /**
     * 只对定义了对应Annotation注解的空属性stub操作
     *
     * @param annotationClass 注解类列表
     * @return 被设置的属性对象列表
     */
    public Map fakeNullByAnnotation(Class... annotationClass) {
        return this.fakeProperties(f -> {
            if (f.get(target) != null) {
                return false;
            }
            for (Class aClass : annotationClass) {
                if (f.getAnnotation(aClass) != null) {
                    return true;
                }
            }
            return false;
        });
    }

    /**
     * 对符合条件的field进行stub赋值
     *
     * @param predicate Predicate
     */
    private Map fakeProperties(FieldPredicate predicate) {
        Class aClass = this.klass;
        Map properties = new HashMap<>();
        while (aClass != Object.class) {
            Field[] fields = aClass.getDeclaredFields();
            for (Field field : fields) {
                String fn = field.getName();
                Class ft = field.getType();
                String ftn = ft.getName();
                if (fn.contains("$") ||
                    ft.isArray() ||
                    Enum.class.isAssignableFrom(ft) ||
                    Annotation.class.isAssignableFrom(ft) ||
                    ftn.startsWith("java.") ||
                    ftn.startsWith("sun.")) {
                    continue;
                }
                Object obj = this.fakeField(field, predicate);
                if (obj != null && !aClass.isInterface()) {
                    properties.put(aClass.getName().replace('$', '_') + "#" + field.getName(), obj);
                }
            }
            aClass = aClass.getSuperclass();
        }
        return properties;
    }

    /**
     * 对符合条件的field进行stub赋值
     *
     * @param field     字段
     * @param predicate 判断
     * @return 返回设置的字段值(stub对象), 或者null(未设置)
     */
    private Object fakeField(Field field, FieldPredicate predicate) {
        boolean accessible = field.isAccessible();
        try {
            field.setAccessible(true);
            if (!predicate.test(field)) {
                return null;
            }
            Class aClass = field.getType();
            if (aClass.isPrimitive()) {
                return null;
            }
            Object obj;
            if (Modifier.isFinal(aClass.getModifiers())) {
                Constructor constructor = aClass.getDeclaredConstructor();
                constructor.setAccessible(true);
                obj = constructor.newInstance();
            } else {
                obj = Stubs.fake(field.getType());
            }
            if (obj != null) {
                field.set(target, obj);
            }
            return obj;
        } catch (Exception e) {
            Logger.warn("fakeField[" + field.getType().getName() + "#" + field.getName() + "] error: " + e.getMessage());
        } finally {
            field.setAccessible(accessible);
        }
        return null;
    }

    private interface FieldPredicate {
        boolean test(Field field) throws Exception;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy