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

net.amygdalum.testrecorder.util.Reflections Maven / Gradle / Ivy

The newest version!
package net.amygdalum.testrecorder.util;

import static java.lang.reflect.Modifier.isFinal;
import static java.lang.reflect.Modifier.isPublic;
import static net.amygdalum.testrecorder.util.Types.getDeclaredField;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Modifier;

public final class Reflections {

    private static final String MODIFIERS = "modifiers";

    private Reflections() {
    }

    public static  Accessing accessing(T o) {
        return new Accessing<>(o);
    }

    public static Object getValue(String fieldName, Object item) throws ReflectiveOperationException {
        Field field = getDeclaredField(item.getClass(), fieldName);

        return getValue(field, item);
    }

    public static Object getValue(Field field, Object item) throws ReflectiveOperationException {
        return accessing(field).call(f -> f.get(item));
    }

    public static class Accessing {

        private T object;

        public Accessing(T object) {
            this.object = object;
        }

        public  S call(AccessFunction code) throws ReflectiveOperationException {
            boolean reset = ensureAccess();
            try {
                S result = code.apply(object);
                return result;
            } finally {
                resetAccess(reset);
            }
        }

        public void exec(AccessConsumer code) throws ReflectiveOperationException {
            boolean reset = ensureAccess();
            try {
                code.accept(object);
            } finally {
                resetAccess(reset);
            }
        }

        private boolean ensureAccess() throws ReflectiveOperationException {
            int modifiers = object.getModifiers();
            if (isFinal(modifiers) && object instanceof Field) {
                makeNonFinal((Field) object);
            }
            if (isPublic(modifiers) && isPublic(object.getDeclaringClass().getModifiers())) {
                return false;
            } else if (!object.isAccessible()) {
                object.setAccessible(true);
                return true;
            } else {
                return false;
            }
        }

        private void makeNonFinal(Field field) throws ReflectiveOperationException {
            Field modifiersField = Field.class.getDeclaredField(MODIFIERS);
            modifiersField.setAccessible(true);
            modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
        }

        private void resetAccess(boolean reset) {
            if (reset) {
                object.setAccessible(false);
            }
        }

    }

    public interface AccessFunction {

        S apply(T member) throws ReflectiveOperationException;

    }

    public interface AccessConsumer {

        void accept(T member) throws ReflectiveOperationException;

    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy