/*
* Copyright (C) 2011 Red Hat, Inc. and/or its affiliates.
*
* 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 org.jboss.errai.cdi.injection.client.test;
import static org.jboss.errai.ioc.client.container.IOC.getBeanManager;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.enterprise.inject.Instance;
import org.jboss.errai.cdi.injection.client.ApplicationScopedBeanA;
import org.jboss.errai.cdi.injection.client.DefaultImpl;
import org.jboss.errai.cdi.injection.client.DependentBeanA;
import org.jboss.errai.cdi.injection.client.DependentInstanceTestBean;
import org.jboss.errai.cdi.injection.client.IfaceWithMultipleDefaultImpls;
import org.jboss.errai.cdi.injection.client.IfaceWithMultipleImpls;
import org.jboss.errai.cdi.injection.client.InstanceTestBean;
import org.jboss.errai.cdi.injection.client.InterfaceA;
import org.jboss.errai.cdi.injection.client.OtherDefaultImpl;
import org.jboss.errai.cdi.injection.client.Qual1And2Impl;
import org.jboss.errai.cdi.injection.client.Qual1Impl;
import org.jboss.errai.cdi.injection.client.QualifiedInstanceModule;
import org.jboss.errai.cdi.injection.client.UnmanagedBean;
import org.jboss.errai.cdi.injection.client.qualifier.Qual2;
import org.jboss.errai.enterprise.client.cdi.AbstractErraiCDITest;
import org.jboss.errai.ioc.client.container.IOC;
/**
* @author Mike Brock
*/
public class InstanceInjectionIntegrationTest extends AbstractErraiCDITest {
{
disableBus = true;
}
@Override
public String getModuleName() {
return "org.jboss.errai.cdi.injection.InjectionTestModule";
}
public void testSelectIsMoreSpecific() throws Exception {
final QualifiedInstanceModule module = IOC.getBeanManager().lookupBean(QualifiedInstanceModule.class).getInstance();
final Instance<IfaceWithMultipleImpls> instance = module.ambiguousQual1;
try {
assertNotNull("Instance was not injected.", instance);
assertExactlyTheseBeans(instance, Qual1Impl.class, Qual1And2Impl.class);
} catch (AssertionError ae) {
throw new AssertionError("Precondition failed.", ae);
}
final Instance<IfaceWithMultipleImpls> selectedInstance = instance.select(new Qual2() {
@Override
public Class<? extends Annotation> annotationType() {
return Qual2.class;
}
});
assertNotNull("Instance was not returned by select.", selectedInstance);
assertExactlyTheseBeans(selectedInstance, Qual1And2Impl.class);
}
public void testSelectWithSubtypeIsMoreSpecific() throws Exception {
final QualifiedInstanceModule module = IOC.getBeanManager().lookupBean(QualifiedInstanceModule.class).getInstance();
final Instance<IfaceWithMultipleImpls> instance = module.ambiguousQual1;
try {
assertNotNull("Instance was not injected.", instance);
assertExactlyTheseBeans(instance, Qual1Impl.class, Qual1And2Impl.class);
} catch (AssertionError ae) {
throw new AssertionError("Precondition failed.", ae);
}
final Instance<IfaceWithMultipleImpls> selectedInstance = instance.select(IfaceWithMultipleImpls.class, new Qual2() {
@Override
public Class<? extends Annotation> annotationType() {
return Qual2.class;
}
});
assertNotNull("Instance was not returned by select.", selectedInstance);
assertExactlyTheseBeans(selectedInstance, Qual1And2Impl.class);
}
public void testAmbiguousDefaultInstance() throws Exception {
final QualifiedInstanceModule module = IOC.getBeanManager().lookupBean(QualifiedInstanceModule.class).getInstance();
final Instance<IfaceWithMultipleDefaultImpls> instance = module.ambiguousDefault;
assertNotNull("Instance was not injected.", instance);
assertExactlyTheseBeans(instance, DefaultImpl.class, OtherDefaultImpl.class);
}
public void testAmbiguousAnyInstance() throws Exception {
final QualifiedInstanceModule module = IOC.getBeanManager().lookupBean(QualifiedInstanceModule.class).getInstance();
final Instance<IfaceWithMultipleDefaultImpls> instance = module.ambiguousAny;
assertNotNull("Instance was not injected.", instance);
assertExactlyTheseBeans(instance, DefaultImpl.class, OtherDefaultImpl.class);
}
public void testAmbiguousQualifiedInstance() throws Exception {
final QualifiedInstanceModule module = IOC.getBeanManager().lookupBean(QualifiedInstanceModule.class).getInstance();
final Instance<IfaceWithMultipleImpls> instance = module.ambiguousQual1;
assertNotNull("Instance was not injected.", instance);
assertExactlyTheseBeans(instance, Qual1Impl.class, Qual1And2Impl.class);
}
public void testUnambiguousAndSatisfiedDefaultInstance() throws Exception {
final QualifiedInstanceModule module = IOC.getBeanManager().lookupBean(QualifiedInstanceModule.class).getInstance();
final Instance<IfaceWithMultipleImpls> instance = module.gettableDefault;
assertNotNull("Instance was not injected.", instance);
assertExactlyTheseBeans(instance, DefaultImpl.class);
assertGetIsType(instance, DefaultImpl.class);
}
public void testUnambiguousAndSatisfiedExplicitDefaultInstance() throws Exception {
final QualifiedInstanceModule module = IOC.getBeanManager().lookupBean(QualifiedInstanceModule.class).getInstance();
final Instance<IfaceWithMultipleImpls> instance = module.gettableExplicitDefault;
assertNotNull("Instance was not injected.", instance);
assertExactlyTheseBeans(instance, DefaultImpl.class);
assertGetIsType(instance, DefaultImpl.class);
}
public void testUnambiguousAndSatisfiedQual1AndBInstance() throws Exception {
final QualifiedInstanceModule module = IOC.getBeanManager().lookupBean(QualifiedInstanceModule.class).getInstance();
final Instance<IfaceWithMultipleImpls> instance = module.gettableQual1AndB;
assertNotNull("Instance was not injected.", instance);
assertExactlyTheseBeans(instance, Qual1And2Impl.class);
assertGetIsType(instance, Qual1And2Impl.class);
}
public void testUnsatisfiedQual1Instance() throws Exception {
final QualifiedInstanceModule module = IOC.getBeanManager().lookupBean(QualifiedInstanceModule.class).getInstance();
final Instance<IfaceWithMultipleDefaultImpls> instance = module.unsatisfiedQual1;
assertNotNull("Instance was not injected.", instance);
assertExactlyTheseBeans(instance);
}
public void testGetForInjectedInstances() {
final InstanceTestBean testBean = getBeanManager().lookupBean(InstanceTestBean.class).getInstance();
assertNotNull("InstanceTestBean is null", testBean);
final Instance<ApplicationScopedBeanA> instanceApplicationScopedBean
= testBean.getInjectApplicationScoped();
assertNotNull("InstanceTestBean.Instance<ApplicationScopedBeanA> is null", instanceApplicationScopedBean);
final Instance<DependentBeanA> instanceDependentBeanA = testBean.getInjectDependentBeanA();
assertNotNull("InstanceTestBean.Instance<DependentBeanA> is null", instanceDependentBeanA);
final ApplicationScopedBeanA a = instanceApplicationScopedBean.get();
assertNotNull(a);
final DependentBeanA b = instanceDependentBeanA.get();
assertNotNull(b);
final ApplicationScopedBeanA a1 = instanceApplicationScopedBean.get();
final DependentBeanA b1 = instanceDependentBeanA.get();
assertSame(a, a1);
assertNotSame(b, b1);
assertTrue(b1.isPostConstr());
assertNotNull(b1.getBeanB());
assertTrue(b1.getBeanB().isPostConstr());
}
public void testScopingBehaviourViaGet() {
final DependentInstanceTestBean testBean
= getBeanManager().lookupBean(DependentInstanceTestBean.class).getInstance();
assertNotNull("DependentInstanceTestBean is null", testBean);
final Instance<ApplicationScopedBeanA> instanceApplicationScopedBean
= testBean.getInjectApplicationScoped();
assertNotNull("DependentInstanceTestBean.Instance<ApplicationScopedBeanA> is null", instanceApplicationScopedBean);
final Instance<DependentBeanA> instanceDependentBeanA = testBean.getInjectDependentBeanA();
assertNotNull("DependentInstanceTestBean.Instance<DependentBeanA> is null", instanceDependentBeanA);
final ApplicationScopedBeanA a = instanceApplicationScopedBean.get();
assertNotNull(a);
final DependentBeanA b = instanceDependentBeanA.get();
assertNotNull(b);
final ApplicationScopedBeanA a1 = instanceApplicationScopedBean.get();
final DependentBeanA b1 = instanceDependentBeanA.get();
assertSame(a, a1);
assertNotSame(b, b1);
assertTrue(b1.isPostConstr());
assertNotNull(b1.getBeanB());
assertTrue(b1.getBeanB().isPostConstr());
}
public void testUnmangedBeanIsUnsatisfied() {
final InstanceTestBean testBean = getBeanManager().lookupBean(InstanceTestBean.class).getInstance();
assertNotNull("InstanceTestBean is null", testBean);
final Instance<UnmanagedBean> instanceUnmanagedBean = testBean.getUnmanagedBean();
assertNotNull("InstanceTestBean.Instance<UnmanagedBean> is null", instanceUnmanagedBean);
assertTrue("Unmanaged bean should not be satisfied", instanceUnmanagedBean.isUnsatisfied());
}
public void testSatisfiedScopedBeansAreNotUnsatisfied() {
final InstanceTestBean testBean = getBeanManager().lookupBean(InstanceTestBean.class).getInstance();
assertNotNull("InstanceTestBean is null", testBean);
final Instance<ApplicationScopedBeanA> instanceApplicationScopedBean = testBean.getInjectApplicationScoped();
assertFalse(instanceApplicationScopedBean.isUnsatisfied());
final Instance<DependentBeanA> instanceDependentBeanA = testBean.getInjectDependentBeanA();
assertFalse(instanceDependentBeanA.isUnsatisfied());
}
public void testAmbgiousBeanIsNotUnsatisfied() {
final InstanceTestBean testBean = getBeanManager().lookupBean(InstanceTestBean.class).getInstance();
assertNotNull("InstanceTestBean is null", testBean);
final Instance<InterfaceA> instanceAmbiguousBean = testBean.getAmbiguousBean();
assertNotNull("InstanceTestBean.Instance<InterfaceA> is null", instanceAmbiguousBean);
assertFalse("Ambiguous bean should be satisfied", instanceAmbiguousBean.isUnsatisfied());
}
public void testAmbiguousInstanceIsAmbiguous() {
final InstanceTestBean testBean = getBeanManager().lookupBean(InstanceTestBean.class).getInstance();
assertNotNull("InstanceTestBean is null", testBean);
final Instance<InterfaceA> ambiguousBean = testBean.getAmbiguousBean();
assertNotNull("InstanceTestBean.Instance<InterfaceA> is null", ambiguousBean);
assertTrue(ambiguousBean.isAmbiguous());
}
public void testUnmanagedBeanIsNotAmbiguous() {
final InstanceTestBean testBean = getBeanManager().lookupBean(InstanceTestBean.class).getInstance();
assertNotNull("InstanceTestBean is null", testBean);
final Instance<UnmanagedBean> instanceUnmanagedBean = testBean.getUnmanagedBean();
assertNotNull("InstanceTestBean.Instance<UnmanagedBean> is null", instanceUnmanagedBean);
assertFalse(instanceUnmanagedBean.isAmbiguous());
}
public void testUnambiguousScopedBeansAreNotAmbiguous() {
final InstanceTestBean testBean = getBeanManager().lookupBean(InstanceTestBean.class).getInstance();
assertNotNull("InstanceTestBean is null", testBean);
final Instance<ApplicationScopedBeanA> instanceApplicationScopedBean = testBean.getInjectApplicationScoped();
assertFalse(instanceApplicationScopedBean.isAmbiguous());
final Instance<DependentBeanA> instanceDependentBeanA = testBean.getInjectDependentBeanA();
assertFalse(instanceDependentBeanA.isAmbiguous());
}
public void testIterator() {
final DependentInstanceTestBean testBean
= getBeanManager().lookupBean(DependentInstanceTestBean.class).getInstance();
final Instance<DependentBeanA> injectedBean = testBean.getInjectDependentBeanA();
assertTrue(injectedBean.iterator().hasNext());
assertEquals(DependentBeanA.class, injectedBean.iterator().next().getClass());
}
private <T> void assertExactlyTheseBeans(final Instance<T> instance, final Class<?>... clazzes) {
final Set<Class<?>> givenTypes = new HashSet<>(Arrays.asList(clazzes));
final Set<Class<?>> extraTypes = new HashSet<>();
for (final T bean : instance) {
if (!givenTypes.remove(bean.getClass())) {
extraTypes.add(bean.getClass());
}
}
if (!(givenTypes.isEmpty() && extraTypes.isEmpty())) {
fail("Instance did not contain the following: " + givenTypes + "\nInstance had the following unexpected: " + extraTypes);
}
}
private <T> void assertGetIsType(final Instance<T> instance, final Class<?> clazz) {
try {
final T bean = instance.get();
assertNotNull("Instance.get returned null.", bean);
assertEquals("Bean was not of the expected type.", clazz, bean.getClass());
} catch (AssertionError ae) {
throw ae;
} catch (Throwable t) {
throw new AssertionError("Could not use Instance.get. Encountered an error.", t);
}
}
}