View Javadoc

1   package net.sf.twip.cdi;
2   
3   import java.util.Set;
4   
5   import javax.enterprise.context.spi.CreationalContext;
6   import javax.enterprise.inject.spi.*;
7   
8   import net.sf.twip.TwipExtension;
9   
10  import org.jboss.weld.environment.se.Weld;
11  import org.junit.runners.model.*;
12  
13  /**
14   * Initializing CDI is expensive, so this {@link TwipExtension} is not auto-loaded... you'll have to
15   * annotate your tests with <code>@TwipExtensions(CdiExtension.class)</code>.
16   */
17  public class CdiExtension extends TwipExtension {
18  	private static final BeanManager beanManager = new Weld().initialize().getBeanManager();
19  
20  	private class CdiStatement<T> extends Statement {
21  		private final Statement statement;
22  		private final T instance;
23  		private final CreationalContext<T> ctx;
24  		private final InjectionTarget<T> target;
25  
26  		public CdiStatement(Statement statement, T instance) {
27  			this.statement = statement;
28  			this.instance = instance;
29  
30  			@SuppressWarnings("unchecked")
31  			Class<T> testType = (Class<T>) instance.getClass();
32  
33  			Bean<T> bean = getUniqueBean(testType);
34  			this.ctx = beanManager.createCreationalContext(bean);
35  
36  			AnnotatedType<T> type = beanManager.createAnnotatedType(testType);
37  			this.target = beanManager.createInjectionTarget(type);
38  		}
39  
40  		private Bean<T> getUniqueBean(Class<T> testType) {
41  			Set<Bean<?>> beans = beanManager.getBeans(testType);
42  			assert beans.size() == 1 : "there are " + beans.size() + " beans of " + testType;
43  			@SuppressWarnings("unchecked")
44  			Bean<T> bean = (Bean<T>) beans.iterator().next();
45  			return bean;
46  		}
47  
48  		@Override
49  		public void evaluate() throws Throwable {
50  			target.inject(instance, ctx);
51  			target.postConstruct(instance);
52  
53  			try {
54  				statement.evaluate();
55  			} finally {
56  				target.preDestroy(instance);
57  				target.dispose(instance);
58  				ctx.release();
59  			}
60  		}
61  	}
62  
63  	@Override
64  	public Statement wrapOuter(FrameworkMethod method, Object testInstance, Statement statement) {
65  		return new CdiStatement<Object>(statement, testInstance);
66  	}
67  }