package jp.sourceforge.glad.reflect;

import java.lang.reflect.Field;

import jp.sourceforge.glad.util.ValueAccessor;

public class FieldAccessor<T> implements ValueAccessor<T> {

    final Object target;

    final FieldAdapter<T> field;

    public FieldAccessor(Object target, String name) {
        this(target, getField(target.getClass(), name));
    }

    public FieldAccessor(Object target, Field field) {
        this(target, new FieldAdapter<T>(field));
    }

    FieldAccessor(Object target, FieldAdapter<T> field) {
        this.target = target;
        this.field = field;
    }

    static Field getField(Class<?> clazz, String name) {
        for (Class<?> c = clazz; c != null; c = c.getSuperclass()) {
            try {
                return c.getDeclaredField(name);
            } catch (NoSuchFieldException e) {}
        }
        throw new NoSuchFieldRuntimeException(
                ReflectionUtils.fieldToSimpleString(clazz, name));
    }

    public T get() {
        field.makeAccessible();
        return field.get(target);
    }

    public void set(T value) {
        field.makeAccessible();
        field.set(target, value);
    }

}
