*/
package org.wamblee.test.inject;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.wamblee.inject.Injector;
import org.wamblee.reflection.Accessor;
import org.wamblee.reflection.AnnotationUtils;
+import org.wamblee.reflection.ObjectTraversal;
+import org.wamblee.reflection.ObjectTraversal.ObjectVisitor;
/**
- * Injector that performs additional injection on top of the injections that are standard
- * available (e.g. entity manager in Java SE environment).
+ * <p>
+ * Injector that performs additional injection on top of the injections that are
+ * standard available (e.g. entity manager in Java SE environment).
+ * </p>
+ *
+ * <p>
+ * It works by first delegating to the default injector (typically CDI). Afterwards it traverses the
+ * object graph of the injected object and performs custom injection of test objects as specified by the
+ * {@link Binding} class. This approach makes sure that test dependencies also find their way into
+ * objects that were created by the injection framework.
+ * </p>
*
* @author Erik Brakkee
*/
public class JavaEETestInjector implements Injector {
- private EntityManager entityManager;
+ private class InjectionVisitor implements ObjectVisitor {
+ @Override
+ public boolean mustVisit(Class aClass) {
+ if (EntityManager.class.isAssignableFrom(aClass)) {
+ return false;
+ }
+ return true;
+ }
+ @Override
+ public boolean mustVisit(Field aField) {
+ // just process any field with annotations
+ return aField.getAnnotations().length > 0;
+ }
+ @Override
+ public boolean mustVisit(Method aMethod) {
+ return false;
+ }
+ @Override
+ public boolean visitArray(Object aArray) {
+ return true;
+ }
+ @Override
+ public boolean visitList(List aObject) {
+ return true;
+ }
+ @Override
+ public boolean visitMap(Map aObject) {
+ return true;
+ }
+ @Override
+ public boolean visitPlainObject(Object aObject) {
+ performTestInjections(aObject);
+ return true;
+ }
+ @Override
+ public boolean visitSet(Set aSet) {
+ return true;
+ }
+ }
+
+ private List<Binding> bindings;
private Injector delegate;
- private List<Accessor> accessors;
/**
- * Constructs the injector.
- * @param aClass Class to inject for.
- * @param aEntityManager Entity manager.
- * @param aDelegate Injecto to delegate to to perform the standard injections.
+ * Constructs the injector.
+ *
+ * @param aClass
+ * Class to inject for.
+ * @param aBindings
+ * Binding of an object value.
+ * @param aDelegate
+ * Injecto to delegate to to perform the standard injections.
*/
- public JavaEETestInjector(Class aClass, EntityManager aEntityManager,
+ public JavaEETestInjector(Class aClass, List<Binding> aBindings,
Injector aDelegate) {
- entityManager = aEntityManager;
+ bindings = aBindings;
delegate = aDelegate;
- accessors = AnnotationUtils.analyse(aClass, PersistenceContext.class);
}
@Override
public void inject(Object aComponent) {
+ // basic injection
delegate.inject(aComponent);
- for (Accessor accessor: accessors) {
- accessor.set(aComponent, entityManager);
+
+ // Now perform test injections.
+ ObjectTraversal traversal = new ObjectTraversal(new InjectionVisitor());
+ traversal.accept(aComponent);
+ }
+
+ private void performTestInjections(Object aComponent) {
+ for (Binding binding : bindings) {
+ binding.inject(aComponent);
}
}