/*
* Copyright (C) 2013 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.exoplatform.container;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.exoplatform.container.component.BaseComponentPlugin;
import org.exoplatform.container.jmx.AbstractTestContainer;
import org.exoplatform.container.jmx.MX4JComponentAdapterMT;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.picocontainer.Startable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Qualifier;
import javax.inject.Singleton;
/**
* @author <a href="mailto:nfilotto@exoplatform.com">Nicolas Filotto</a>
* @version $Id$
*
*/
@RunWith(Parameterized.class)
public class TestExoContainerMT extends TestExoContainer
{
private Mode[] modes;
public TestExoContainerMT(Mode... modes)
{
this.modes = modes;
}
@Before
public void setUp()
{
Mode.setModes(modes);
}
@After
public void tearDown()
{
Mode.clearModes();
}
@Parameters
public static List<Object[]> data()
{
return Arrays.asList(new Object[][]{{null}, {new Mode[]{Mode.MULTI_THREADED}},
{new Mode[]{Mode.MULTI_THREADED, Mode.DISABLE_MT_ON_STARTUP_COMPLETE}}, {new Mode[]{Mode.AUTO_SOLVE_DEP_ISSUES}},
{new Mode[]{Mode.MULTI_THREADED, Mode.AUTO_SOLVE_DEP_ISSUES}},
{new Mode[]{Mode.MULTI_THREADED, Mode.AUTO_SOLVE_DEP_ISSUES, Mode.DISABLE_MT_ON_STARTUP_COMPLETE}}});
}
@Test
public void testBadCyclicRef() throws Exception
{
RootContainer container = AbstractTestContainer.createRootContainer(getClass(), "test-exo-container-mt.xml", "testBadCyclicRef");
try
{
container.getComponentInstanceOfType(TestExoContainer.A1.class);
fail("A CyclicDependencyException was expected");
}
catch (CyclicDependencyException e)
{
// expected exception
}
}
@Test
public void testBadCyclicRef2() throws Exception
{
try
{
AbstractTestContainer.createRootContainer(getClass(), "test-exo-container-mt.xml", "testBadCyclicRef2");
}
catch (CyclicDependencyException e)
{
// expected exception
}
}
@Test
public void testBadCyclicRef3() throws Exception
{
RootContainer container = AbstractTestContainer.createRootContainer(getClass(), "test-exo-container-mt.xml", "testBadCyclicRef3");
try
{
container.getComponentInstanceOfType(A1.class);
fail("A CyclicDependencyException was expected");
}
catch (CyclicDependencyException e)
{
// expected exception
}
}
@Test
public void testBadCyclicRef4() throws Exception
{
try
{
AbstractTestContainer.createRootContainer(getClass(), "test-exo-container-mt.xml", "testBadCyclicRef4");
}
catch (CyclicDependencyException e)
{
// expected exception
}
}
public static class A1
{
public B1 b;
public A1(ExoContainerContext ctx)
{
this.b = ctx.getContainer().getComponentInstanceOfType(B1.class);
}
}
public static class B1
{
public A1 a;
public B1(ExoContainerContext ctx)
{
this.a = ctx.getContainer().getComponentInstanceOfType(A1.class);
}
}
public static class A2 implements Startable
{
public B2 b;
public A2(ExoContainerContext ctx)
{
this.b = ctx.getContainer().getComponentInstanceOfType(B2.class);
}
public void start()
{
}
public void stop()
{
}
}
public static class B2
{
public A2 a;
public B2(ExoContainerContext ctx)
{
this.a = ctx.getContainer().getComponentInstanceOfType(A2.class);
}
}
@Test
public void testBadCyclicRef5() throws Exception
{
RootContainer container = AbstractTestContainer.createRootContainer(getClass(), "test-exo-container-mt.xml", "testBadCyclicRef5");
try
{
container.getComponentInstanceOfType(A3.class);
fail("A CyclicDependencyException was expected");
}
catch (CyclicDependencyException e)
{
// expected exception
}
}
@Test
public void testBadCyclicRef6() throws Exception
{
try
{
AbstractTestContainer.createRootContainer(getClass(), "test-exo-container-mt.xml", "testBadCyclicRef6");
}
catch (CyclicDependencyException e)
{
// expected exception
}
}
@Singleton
public static class A3
{
public B3 b;
@Inject
public A3(Provider<B3> p)
{
this.b = p.get();
}
}
@Singleton
public static class B3
{
public A3 a;
@Inject
public B3(Provider<A3> p)
{
this.a = p.get();
}
}
@Singleton
public static class A4 implements Startable
{
public B4 b;
@Inject
public A4(Provider<B4> p)
{
this.b = p.get();
}
public void start()
{
}
public void stop()
{
}
}
@Singleton
public static class B4
{
public A4 a;
@Inject
public B4(Provider<A4> p)
{
this.a = p.get();
}
}
@Test
public void testAutoSolveDepIssues()
{
RootContainer container = AbstractTestContainer.createRootContainer(getClass(), "test-exo-container-mt.xml", "testAutoSolveDepIssues");
MX4JComponentAdapterMT<ASDI_1> adapter1 =
(MX4JComponentAdapterMT<ASDI_1>)container.getComponentAdapterOfType(ASDI_1.class);
MX4JComponentAdapterMT<ASDI_2> adapter2 =
(MX4JComponentAdapterMT<ASDI_2>)container.getComponentAdapterOfType(ASDI_2.class);
MX4JComponentAdapterMT<ASDI_2_2> adapter3 =
(MX4JComponentAdapterMT<ASDI_2_2>)container.getComponentAdapterOfType(ASDI_2_2.class);
if (Mode.hasMode(Mode.AUTO_SOLVE_DEP_ISSUES))
{
assertEquals(2, adapter1.getCreateDependencies().size());
assertEquals(3, adapter1.getInitDependencies().size());
assertEquals(4, adapter2.getCreateDependencies().size());
assertEquals(4, adapter2.getInitDependencies().size());
}
else
{
assertEquals(1, adapter1.getCreateDependencies().size());
assertEquals(1, adapter1.getInitDependencies().size());
assertEquals(1, adapter2.getCreateDependencies().size());
assertEquals(1, adapter2.getInitDependencies().size());
}
assertEquals(3, adapter3.getCreateDependencies().size());
for (Dependency dep : adapter3.getCreateDependencies())
{
assertTrue(dep.isLazy());
}
assertEquals(3, adapter3.getInitDependencies().size());
for (Dependency dep : adapter3.getInitDependencies())
{
assertTrue(dep.isLazy());
}
}
public static class ASDI_1 implements Startable
{
private ExoContainer container;
public ASDI_1(ExoContainerContext ctx)
{
container = ctx.getContainer();
container.getComponentInstanceOfType(ASDI_2.class);
}
public void addPlugin(ASDI_1Plugin plugin)
{
container.getComponentInstanceOfType(ASDI_2.class);
}
public void start()
{
}
public void stop()
{
}
}
public static class ASDI_1Plugin extends BaseComponentPlugin
{
public ASDI_1Plugin(ExoContainerContext ctx)
{
ctx.getContainer().getComponentInstanceOfType(ASDI_2_2.class);
}
}
@Singleton
public static class ASDI_2
{
@Inject
public ASDI_2(ExoContainerContext ctx)
{
ctx.getContainer().getComponentInstanceOfType(ASDI_3.class);
ctx.getContainer().getComponentInstance("ASDI_4", ASDI_4.class);
ctx.getContainer().getComponentInstance(ASDI_5Qualifier.class, ASDI_5.class);
}
@Inject
public void init(ExoContainerContext ctx)
{
ctx.getContainer().getComponentInstanceOfType(ASDI_3.class);
ctx.getContainer().getComponentInstance("ASDI_4", ASDI_4.class);
ctx.getContainer().getComponentInstance(ASDI_5Qualifier.class, ASDI_5.class);
}
}
@Singleton
public static class ASDI_2_2
{
@Inject
public ASDI_2_2(Provider<ASDI_3> p1, @Named("ASDI_4") Provider<ASDI_4> p2, @ASDI_5Qualifier Provider<ASDI_5> p3)
{
p1.get();
p2.get();
p3.get();
}
@Inject
public void init(Provider<ASDI_3> p1, @Named("ASDI_4") Provider<ASDI_4> p2, @ASDI_5Qualifier Provider<ASDI_5> p3)
{
p1.get();
p2.get();
p3.get();
}
}
public static class ASDI_3
{
}
public static class ASDI_4
{
}
public static class ASDI_5
{
}
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public static @interface ASDI_5Qualifier {
}
}