package org.magenta.core.injection;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.magenta.DataSpecification;
import org.magenta.Fixture;
import org.magenta.annotations.InjectFluentRandom;
import org.magenta.random.FluentRandom;
import com.google.common.base.Supplier;
/**
* Inject the current RandomBuilderImplobject into a given field.
*
* @author ngagnon
*
*/
public class FluentRandomFieldHandler<S extends DataSpecification> implements FieldInjectionHandler<S>{
@Override
public boolean handle(Field f, Object target, Supplier<Fixture<S>> current) {
if (f.isAnnotationPresent(org.magenta.annotations.InjectFluentRandom.class)) {
InjectFluentRandom annotation = f.getAnnotation(org.magenta.annotations.InjectFluentRandom.class);
if (FluentRandom.class.equals(f.getType())) {
Enhancer e = new Enhancer();
e.setSuperclass(FluentRandom.class);
e.setCallback(interceptor(supplierOfFluentRandom(current)));
e.setInterceptDuringConstruction(false);
FluentRandom proxy = (FluentRandom)e.create();
FieldInjectorUtils.injectInto(target, f, proxy);
return true;
}else{
throw new IllegalStateException("Annotation "+InjectFluentRandom.class.getName()+" is present on field named "+f.getName()+", but this field type is not a "+FluentRandom.class.getName());
}
} else {
return false;
}
}
private Callback interceptor(final Supplier<FluentRandom> current) {
return new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
return method.invoke(current.get(), args);
}
};
}
private Supplier<FluentRandom> supplierOfFluentRandom(final Supplier<Fixture<S>> current) {
return new Supplier<FluentRandom>() {
@Override
public FluentRandom get() {
Fixture domain = current.get();
if (domain == null) {
throw new IllegalStateException("No FixtureBuilder currently bound to the provided supplier : " + current);
}
return domain.getRandomizer();
}
};
}
}