package org.testfun.jee.runner; import org.testfun.jee.runner.inject.*; import java.lang.reflect.Field; import java.util.Arrays; import java.util.LinkedList; import java.util.List; public class DependencyInjector { private static final DependencyInjector INSTANCE = new DependencyInjector(); public static DependencyInjector getInstance() { return INSTANCE; } private List<Injector> injectors = new LinkedList<>(); private DependencyInjector() { MockRegistrar mockRegistrar = new MockRegistrar(); injectors = Arrays.asList( mockRegistrar, // the MockRegistrar injector must be listed before the EJB injector to guarantee that mocks are registered before they are used. new EjbInjector().withMocking(mockRegistrar), new PersistenceContextInjector(), new ResourceInjector().withMocking(mockRegistrar) ); } public <P> P injectDependencies(P pojo) { if (pojo == null) { return null; } // Loop over the class hierarchy of the target pojo for (Class clazz = pojo.getClass(); !clazz.equals(Object.class); clazz = clazz.getSuperclass()) { // For each class, iterate over its field and inject a value if a proper injector was found for the field's annotation. // Note that the outer loop is over the injector so mock objects will be registered before any injection is attempted Field[] fields = clazz.getDeclaredFields(); for (Injector injector : injectors) { for (Field field : fields) { injector.inject(pojo, field); } } } return pojo; } public void reset() { for (Injector injector : injectors) { injector.reset(); } } }