/** * This file Copyright (c) 2011-2012 Magnolia International * Ltd. (http://www.magnolia-cms.com). All rights reserved. * * * This file is dual-licensed under both the Magnolia * Network Agreement and the GNU General Public License. * You may elect to use one or the other of these licenses. * * This file is distributed in the hope that it will be * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT. * Redistribution, except as permitted by whichever of the GPL * or MNA you select, is prohibited. * * 1. For the GPL license (GPL), you can redistribute and/or * modify this file under the terms of the GNU General * Public License, Version 3, as published by the Free Software * Foundation. You should have received a copy of the GNU * General Public License, Version 3 along with this program; * if not, write to the Free Software Foundation, Inc., 51 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * 2. For the Magnolia Network Agreement (MNA), this file * and the accompanying materials are made available under the * terms of the MNA which accompanies this distribution, and * is available at http://www.magnolia-cms.com/mna.html * * Any modifications to this file must keep this entire header * intact. * */ package info.magnolia.objectfactory.configuration; import java.io.IOException; import java.io.InputStream; import java.util.Collections; import java.util.Deque; import java.util.LinkedList; import javax.inject.Provider; import org.junit.After; import org.junit.Before; import org.junit.Test; import info.magnolia.cms.core.SystemProperty; import info.magnolia.context.ContextFactory; import info.magnolia.context.MgnlContext; import info.magnolia.context.SystemContext; import info.magnolia.objectfactory.ComponentFactory; import info.magnolia.objectfactory.guice.GuiceComponentProvider; import info.magnolia.objectfactory.guice.GuiceComponentProviderBuilder; import info.magnolia.test.AbstractMagnoliaTestCase; import info.magnolia.test.ComponentsTestUtil; import info.magnolia.test.TestMagnoliaConfigurationProperties; import info.magnolia.test.mock.MockContext; import info.magnolia.test.mock.MockUtil; import info.magnolia.test.mock.MockWebContext; import info.magnolia.test.mock.jcr.MockSession; import info.magnolia.test.mock.jcr.SessionTestUtil; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; public class ComponentProviderConfigurationBuilderTest extends AbstractMagnoliaTestCase { private static Deque<String> events = new LinkedList<String>(); private MockContext mockContext; public static void addEvent(String event) { events.addLast(event); } public static void assertNoMoreEvents() { assertTrue("No more events expected, was: " + events, events.isEmpty()); } public static void assertEvent(String event) { if (!events.isEmpty() && events.peekFirst().equals(event)) { events.removeFirst(); } else { fail("Expected event " + event); } } public static class SimpleComponent { public SimpleComponent() { addEvent("SimpleComponent"); } } @Before @Override public void setUp() throws Exception { mockContext = new MockWebContext(); MgnlContext.setInstance(mockContext); try { final InputStream in = getClass().getResourceAsStream("/test-magnolia.properties"); final TestMagnoliaConfigurationProperties cfg = new TestMagnoliaConfigurationProperties(in); SystemProperty.setMagnoliaConfigurationProperties(cfg); } catch (IOException e) { throw new RuntimeException(e); } MockSession session = SessionTestUtil.createSession("config", "/foo/bar/component.class=" + SimpleComponent.class.getName(), "/foo/bar/componentWithProperty.class=" + SimpleComponentWithProperty.class.getName() ); MockUtil.setSessionAndHierarchyManager(session); } @After @Override public void tearDown() throws Exception { super.tearDown(); events.clear(); ComponentsTestUtil.clear(); } @Test public void testNonScopedComponent() { GuiceComponentProvider componentProvider = getComponentProvider("test-components-simple.xml"); assertNoMoreEvents(); SimpleComponent simpleComponent = componentProvider.getComponent(SimpleComponent.class); assertEvent("SimpleComponent"); assertNoMoreEvents(); SimpleComponent simpleComponent2 = componentProvider.getComponent(SimpleComponent.class); assertEvent("SimpleComponent"); assertNoMoreEvents(); assertNotSame(simpleComponent, simpleComponent2); componentProvider.destroy(); assertNoMoreEvents(); } @Test public void testLazySingletonScopedComponent() { GuiceComponentProvider componentProvider = getComponentProvider("test-components-simple-singleton.xml"); assertNoMoreEvents(); SimpleComponent simpleComponent = componentProvider.getComponent(SimpleComponent.class); assertEvent("SimpleComponent"); assertNoMoreEvents(); SimpleComponent simpleComponent2 = componentProvider.getComponent(SimpleComponent.class); assertNoMoreEvents(); assertSame(simpleComponent, simpleComponent2); componentProvider.destroy(); assertNoMoreEvents(); } @Test public void testEagerSingletonScopedComponent() { GuiceComponentProvider componentProvider = getComponentProvider("test-components-simple-eagersingleton.xml"); assertEvent("SimpleComponent"); assertNoMoreEvents(); SimpleComponent simpleComponent = componentProvider.getComponent(SimpleComponent.class); assertNoMoreEvents(); SimpleComponent simpleComponent2 = componentProvider.getComponent(SimpleComponent.class); assertNoMoreEvents(); assertSame(simpleComponent, simpleComponent2); componentProvider.destroy(); assertNoMoreEvents(); } public static class SimpleComponentProvider implements Provider<SimpleComponent> { @Override public SimpleComponent get() { return new SimpleComponent(); } } @Test public void testProvider() { GuiceComponentProvider componentProvider = getComponentProvider("test-components-provider.xml"); assertNoMoreEvents(); SimpleComponent simpleComponent = componentProvider.getComponent(SimpleComponent.class); assertEvent("SimpleComponent"); assertNoMoreEvents(); SimpleComponent simpleComponent2 = componentProvider.getComponent(SimpleComponent.class); assertEvent("SimpleComponent"); assertNoMoreEvents(); assertNotSame(simpleComponent, simpleComponent2); componentProvider.destroy(); assertNoMoreEvents(); } @Test public void testSingletonScopedProvider() { GuiceComponentProvider componentProvider = getComponentProvider("test-components-provider-singleton.xml"); assertNoMoreEvents(); SimpleComponent simpleComponent = componentProvider.getComponent(SimpleComponent.class); assertEvent("SimpleComponent"); assertNoMoreEvents(); SimpleComponent simpleComponent2 = componentProvider.getComponent(SimpleComponent.class); assertNoMoreEvents(); assertSame(simpleComponent, simpleComponent2); componentProvider.destroy(); assertNoMoreEvents(); } public static class SimpleComponentFactory implements ComponentFactory<SimpleComponent> { @Override public SimpleComponent newInstance() { return new SimpleComponent(); } } @Test public void testComponentFactory() { GuiceComponentProvider componentProvider = getComponentProvider("test-components-componentfactory.xml"); assertNoMoreEvents(); SimpleComponent simpleComponent = componentProvider.getComponent(SimpleComponent.class); assertEvent("SimpleComponent"); assertNoMoreEvents(); SimpleComponent simpleComponent2 = componentProvider.getComponent(SimpleComponent.class); assertEvent("SimpleComponent"); assertNoMoreEvents(); assertNotSame(simpleComponent, simpleComponent2); componentProvider.destroy(); assertNoMoreEvents(); } @Test public void testSingletonScopedComponentFactory() { GuiceComponentProvider componentProvider = getComponentProvider("test-components-componentfactory-singleton.xml"); assertNoMoreEvents(); SimpleComponent simpleComponent = componentProvider.getComponent(SimpleComponent.class); assertEvent("SimpleComponent"); assertNoMoreEvents(); SimpleComponent simpleComponent2 = componentProvider.getComponent(SimpleComponent.class); assertNoMoreEvents(); assertSame(simpleComponent, simpleComponent2); componentProvider.destroy(); assertNoMoreEvents(); } @Test public void testConfigured() { GuiceComponentProvider componentProvider = getComponentProvider("test-components-configured.xml"); assertNoMoreEvents(); SimpleComponent simpleComponent = componentProvider.getComponent(SimpleComponent.class); assertEvent("SimpleComponent"); assertNoMoreEvents(); SimpleComponent simpleComponent2 = componentProvider.getComponent(SimpleComponent.class); assertEvent("SimpleComponent"); assertNoMoreEvents(); assertNotSame(simpleComponent, simpleComponent2); componentProvider.destroy(); assertNoMoreEvents(); } @Test public void testConfiguredSingleton() { GuiceComponentProvider componentProvider = getComponentProvider("test-components-configured-singleton.xml"); assertNoMoreEvents(); SimpleComponent simpleComponent = componentProvider.getComponent(SimpleComponent.class); assertEvent("SimpleComponent"); assertNoMoreEvents(); SimpleComponent simpleComponent2 = componentProvider.getComponent(SimpleComponent.class); assertNoMoreEvents(); assertSame(simpleComponent, simpleComponent2); componentProvider.destroy(); assertNoMoreEvents(); } @Test public void testConfiguredEagerSingleton() { GuiceComponentProvider componentProvider = getComponentProvider("test-components-configured-eagersingleton.xml"); assertEvent("SimpleComponent"); assertNoMoreEvents(); SimpleComponent simpleComponent = componentProvider.getComponent(SimpleComponent.class); assertNoMoreEvents(); SimpleComponent simpleComponent2 = componentProvider.getComponent(SimpleComponent.class); assertNoMoreEvents(); assertSame(simpleComponent, simpleComponent2); componentProvider.destroy(); assertNoMoreEvents(); } public static class SimpleComponentWithProperty extends SimpleComponent { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } @Test public void testObserved() { GuiceComponentProvider componentProvider = getComponentProvider("test-components-observed.xml"); assertNoMoreEvents(); SimpleComponentWithProperty simpleComponent = componentProvider.getComponent(SimpleComponentWithProperty.class); assertEvent("SimpleComponent"); // There's two of these since the proxy also adds it assertEvent("SimpleComponent"); assertNoMoreEvents(); SimpleComponentWithProperty simpleComponent2 = componentProvider.getComponent(SimpleComponentWithProperty.class); assertEvent("SimpleComponent"); // There's two of these since the proxy also adds it assertEvent("SimpleComponent"); assertNoMoreEvents(); // Make sure that its two completely different instances behind the proxies simpleComponent.setName("1"); simpleComponent2.setName("2"); assertEquals("1", simpleComponent.getName()); assertEquals("2", simpleComponent2.getName()); componentProvider.destroy(); assertNoMoreEvents(); } private GuiceComponentProvider getComponentProvider(String resourcePath) { ComponentProviderConfigurationBuilder builder = new ComponentProviderConfigurationBuilder(); ComponentProviderConfiguration configuration = builder.readConfiguration(Collections.singletonList("/info/magnolia/objectfactory/configuration/" + resourcePath), "main"); configuration.registerImplementation(info.magnolia.jcr.node2bean.Node2BeanProcessor.class, info.magnolia.jcr.node2bean.impl.Node2BeanProcessorImpl.class); configuration.registerImplementation(info.magnolia.jcr.node2bean.Node2BeanTransformer.class, info.magnolia.jcr.node2bean.impl.Node2BeanTransformerImpl.class); configuration.registerImplementation(info.magnolia.jcr.node2bean.TransformationState.class, info.magnolia.jcr.node2bean.impl.TransformationStateImpl.class); configuration.registerImplementation(info.magnolia.jcr.node2bean.TypeMapping.class, info.magnolia.jcr.node2bean.impl.TypeMappingImpl.class); configuration.registerImplementation(ContextFactory.class, ContextFactory.class); configuration.registerInstance(SystemContext.class, mockContext); return new GuiceComponentProviderBuilder().withConfiguration(configuration).exposeGlobally().build(); } }