/* * Copyright open knowledge GmbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.openknowledge.cdi.test; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import javax.enterprise.context.RequestScoped; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import org.apache.webbeans.config.WebBeansContext; import org.apache.webbeans.inject.OWBInjector; import org.apache.webbeans.spi.ContainerLifecycle; import org.apache.webbeans.spi.ContextsService; import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; import org.junit.runners.model.Statement; /** * A Cdi junit runner. Adds a system property called <code>junit.test</code> * with the value <code>"true"</code> as system property. * * @author Arne Limburg - open knowledge GmbH */ public class CdiJunit4TestRunner extends BlockJUnit4ClassRunner { public static final String JUNIT_TEST = "junit.test"; private Class<?> testType; private OWBInjector owbInjector; public CdiJunit4TestRunner(Class<?> type) throws InitializationError { super(type); testType = type; } protected Object createTest() throws Exception { System.setProperty(JUNIT_TEST, "true"); ContainerLifecycle lifecycle = WebBeansContext.currentInstance().getService(ContainerLifecycle.class); lifecycle.startApplication(testType); BeanManager beanManager = lifecycle.getBeanManager(); Set<Bean<?>> testBeans = new HashSet<Bean<?>>(beanManager.getBeans(testType)); //filter out subclasses for (Iterator<Bean<?>> i = testBeans.iterator(); i.hasNext(); ) { if (!i.next().getBeanClass().equals(testType)) { i.remove(); } } if (testBeans.isEmpty()) { Object test = super.createTest(); owbInjector = new OWBInjector(); owbInjector.inject(test); return test; } Bean<?> testBean = beanManager.resolve(testBeans); CreationalContext<?> creationalContext = beanManager.createCreationalContext(testBean); return beanManager.getReference(testBean, testType, creationalContext); } protected Statement methodBlock(FrameworkMethod method) { return new OpenWebBeansStopApplicationStatement(super.methodBlock(method)); } protected Statement withPotentialTimeout(FrameworkMethod method, Object test, Statement next) { return super.withPotentialTimeout(method, test, new RequestScopedStatement(next)); } public class OpenWebBeansStopApplicationStatement extends Statement { private Statement delegate; public OpenWebBeansStopApplicationStatement(Statement statement) { delegate = statement; } @Override public void evaluate() throws Throwable { try { delegate.evaluate(); } finally { System.clearProperty(JUNIT_TEST); if (owbInjector != null) { owbInjector.destroy(); owbInjector = null; } ContainerLifecycle lifecycle = WebBeansContext.currentInstance().getService(ContainerLifecycle.class); lifecycle.stopApplication(testType); } } } public class RequestScopedStatement extends Statement { private Statement next; public RequestScopedStatement(Statement next) { this.next = next; } @Override public void evaluate() throws Throwable { ContextsService contextsService = WebBeansContext.currentInstance().getContextsService(); try { contextsService.startContext(RequestScoped.class, null); next.evaluate(); } finally { contextsService.endContext(RequestScoped.class, null); } } } }