package org.kevoree.bootstrap.reflect;
import org.kevoree.api.helper.ReflectUtils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
*
*/
public class Injector {
private Class<? extends Annotation> injectAnnotationClass;
private Map<Class<?>, Object> registry = new HashMap<>();
public Injector(Class<? extends Annotation> injectAnnotationClass) {
this.injectAnnotationClass = injectAnnotationClass;
}
/**
*
* @param ctxType the service class to register
* @param impl the implementation of that service to bind
* @param <T> the service type
*/
public <T> void register(Class<T> ctxType, T impl) {
registry.put(ctxType, impl);
}
/**
*
* @param ctxType the service class to unregister
* @param <T> the service type
*/
public <T> void unregister(Class<T> ctxType) {
registry.remove(ctxType);
}
/**
* Injects any available service registered if asked by the instance with
* the Annotation class given in the Injector constructor
* @param instance the instance to inject services to
*/
public void inject(Object instance) {
List<Field> fields = ReflectUtils.getAllFieldsWithAnnotation(instance.getClass(), injectAnnotationClass);
for (Field field : fields) {
Object impl = this.registry.get(field.getType());
if (impl != null) {
boolean isAccessible = field.isAccessible();
if (!isAccessible) {
field.setAccessible(true);
}
try {
field.set(instance, impl);
} catch (IllegalAccessException e) {
e.printStackTrace();
} finally {
if (!isAccessible) {
field.setAccessible(false);
}
}
} else {
throw new RuntimeException("Unable to find implementation of type "+field.getType().getName()+" to inject");
}
}
}
}