/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.dlect.test.helper; import com.google.common.collect.Lists; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.List; import org.dlect.test.Resettable; import org.dlect.test.Resettables; /** * * @author lee */ public class ObjectHelper { // TODO(Later) test these methods. public static Resettable storeStaticStateOf(Class<?>... classes) throws Exception { List<Resettable> fieldResetters = Lists.newArrayList(); for (Class<?> clz : classes) { Field[] declaredFields = clz.getDeclaredFields(); for (Field f : declaredFields) { // only restore static non-final fields. // Also ignore the `$jacoco` object that is injected. if (Modifier.isStatic(f.getModifiers()) && !Modifier.isFinal(f.getModifiers()) && !f.getName().contains("$")) { fieldResetters.add(new ObjectConfig(f, null, getField(f, null))); } } } return Resettables.join(fieldResetters); } public static ObjectConfig setStaticField(Class<?> c, String name, Object val) throws Exception { Field pcsField = getClassField(c, name); Object oldVal = setField(pcsField, null, val); return new ObjectConfig(pcsField, null, oldVal); } public static ObjectConfig getStaticFieldResetter(Class<?> c, String name) throws Exception { Field pcsField = getClassField(c, name); Object oldVal = getField(pcsField, null); return new ObjectConfig(pcsField, null, oldVal); } public static Object getStaticField(Class<?> c, String name) throws Exception { Field pcsField = getClassField(c, name); return getField(pcsField, null); } public static Field getClassField(Class<?> c, String name) throws NoSuchFieldException, SecurityException { assert c != null; Field pcsField = c.getDeclaredField(name); return pcsField; } public static Object setField(Field pcsField, Object instance, Object value) throws Exception { boolean access = pcsField.isAccessible(); try { pcsField.setAccessible(true); Object original = pcsField.get(instance); pcsField.set(instance, value); return original; } finally { pcsField.setAccessible(access); } } public static Object getField(Field pcsField, Object instance) throws Exception { boolean access = pcsField.isAccessible(); try { pcsField.setAccessible(true); return pcsField.get(instance); } finally { pcsField.setAccessible(access); } } public static class ObjectConfig implements Resettable { private final Field f; private final Object instance; private final Object oldVal; public ObjectConfig(Field f, Object instance, Object oldVal) { this.f = f; this.instance = instance; this.oldVal = oldVal; } @Override public void reset() throws Exception { setField(f, instance, oldVal); } } private ObjectHelper() { } }