/** * 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.guice; import java.io.IOException; import java.util.Properties; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Provider; import javax.inject.Singleton; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.mockrunner.mock.web.MockHttpServletRequest; import info.magnolia.context.ContextFactory; import info.magnolia.context.MgnlContext; import info.magnolia.context.SystemContext; import info.magnolia.init.MagnoliaConfigurationProperties; import info.magnolia.module.model.ComponentDefinition; import info.magnolia.objectfactory.ComponentProvider; import info.magnolia.objectfactory.NoSuchComponentException; import info.magnolia.objectfactory.configuration.ComponentProviderConfiguration; import info.magnolia.objectfactory.configuration.ConfiguredComponentConfiguration; import info.magnolia.repository.RepositoryConstants; 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.*; public class GuiceComponentProviderTest extends AbstractMagnoliaTestCase { private MockContext mockContext; @Singleton public static class SingletonObject { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } @Override @Before public void setUp() throws Exception { super.setUp(); mockContext = MockUtil.initMockContext(); MockSession session = SessionTestUtil.createSession("config", "/foo/bar/singleton.class=" + SingletonObject.class.getName(), "/foo/bar/singleton.name=foobar" ); MockUtil.setSessionAndHierarchyManager(session); } @Override @After public void tearDown() throws Exception { ComponentsTestUtil.clear(); super.tearDown(); } @Test public void testGetComponentProvider() { ComponentProviderConfiguration configuration = new ComponentProviderConfiguration(); GuiceComponentProvider p = createComponentProvider(configuration); assertSame(p, p.getComponent(ComponentProvider.class)); } @Test (expected=NoSuchComponentException.class) public void getComponentThrowsExeptionForUnconfiguredType() { ComponentProviderConfiguration configuration = new ComponentProviderConfiguration(); GuiceComponentProvider p = createComponentProvider(configuration); p.getComponent(StringBuilder.class); } @Test public void testInstance() { ComponentProviderConfiguration configuration = new ComponentProviderConfiguration(); SingletonObject singletonObject = new SingletonObject(); configuration.registerInstance(SingletonObject.class, singletonObject); GuiceComponentProvider p = createComponentProvider(configuration); assertSame(singletonObject, p.getComponent(SingletonObject.class)); assertSame(singletonObject, p.getComponent(SingletonObject.class)); } @Test public void testImplementation() { ComponentProviderConfiguration configuration = new ComponentProviderConfiguration(); configuration.registerImplementation(SingletonObject.class, SingletonObject.class); GuiceComponentProvider p = createComponentProvider(configuration); SingletonObject singletonObject = p.getComponent(SingletonObject.class); assertNotNull(singletonObject); assertSame(singletonObject, p.getComponent(SingletonObject.class)); } @Test public void testConfigured() { ComponentProviderConfiguration configuration = new ComponentProviderConfiguration(); configuration.addComponent(new ConfiguredComponentConfiguration<SingletonObject>(SingletonObject.class, "/foo/bar/singleton")); GuiceComponentProvider p = createComponentProviderWithContent2Bean(configuration, true); SingletonObject singletonObject = p.getComponent(SingletonObject.class); assertNotNull(singletonObject); assertNotSame(singletonObject, p.getComponent(SingletonObject.class)); assertEquals("foobar", p.getComponent(SingletonObject.class).getName()); } @Test public void testConfiguredInSingletonScope() { ComponentProviderConfiguration configuration = new ComponentProviderConfiguration(); ConfiguredComponentConfiguration<SingletonObject> componentConfiguration = new ConfiguredComponentConfiguration<SingletonObject>(SingletonObject.class, "/foo/bar/singleton"); componentConfiguration.setScope(ComponentDefinition.SCOPE_SINGLETON); configuration.addComponent(componentConfiguration); GuiceComponentProvider p = createComponentProviderWithContent2Bean(configuration, true); SingletonObject singletonObject = p.getComponent(SingletonObject.class); assertNotNull(singletonObject); assertSame(singletonObject, p.getComponent(SingletonObject.class)); assertEquals("foobar", p.getComponent(SingletonObject.class).getName()); } @Test public void testObserved() { ComponentProviderConfiguration configuration = new ComponentProviderConfiguration(); ConfiguredComponentConfiguration<SingletonObject> observed = new ConfiguredComponentConfiguration<SingletonObject>(SingletonObject.class, RepositoryConstants.CONFIG, "/foo/bar/singleton", true); observed.setScope(ComponentDefinition.SCOPE_SINGLETON); configuration.addComponent(observed); GuiceComponentProvider p = createComponentProviderWithContent2Bean(configuration, true); SingletonObject singletonObject = p.getComponent(SingletonObject.class); assertNotNull(singletonObject); assertSame(singletonObject, p.getComponent(SingletonObject.class)); assertEquals("foobar", p.getComponent(SingletonObject.class).getName()); } @Test public void testObservedInRequestScope() { ComponentProviderConfiguration configuration = new ComponentProviderConfiguration(); ConfiguredComponentConfiguration<SingletonObject> observed = new ConfiguredComponentConfiguration<SingletonObject>(SingletonObject.class, RepositoryConstants.CONFIG, "/foo/bar/singleton", true); observed.setScope(ComponentDefinition.SCOPE_LOCAL); configuration.addComponent(observed); MockHttpServletRequest request = new MockHttpServletRequest(); ((MockWebContext) MgnlContext.getWebContext()).setRequest(request); GuiceComponentProvider p = createComponentProviderWithContent2Bean(configuration, true); SingletonObject singletonObject = p.getComponent(SingletonObject.class); assertNotNull(singletonObject); assertSame(singletonObject, p.getComponent(SingletonObject.class)); assertEquals("foobar", p.getComponent(SingletonObject.class).getName()); request.clearAttributes(); SingletonObject singletonObject2 = p.getComponent(SingletonObject.class); assertNotNull(singletonObject2); assertNotSame(singletonObject2, singletonObject); assertSame(singletonObject2, p.getComponent(SingletonObject.class)); assertEquals("foobar", p.getComponent(SingletonObject.class).getName()); } @Singleton public static class OtherSingletonObject { } @Test public void testCreateChild() { ComponentProviderConfiguration configuration = new ComponentProviderConfiguration(); configuration.registerImplementation(SingletonObject.class, SingletonObject.class); GuiceComponentProvider parent = createComponentProvider(configuration); ComponentProviderConfiguration childConfig = new ComponentProviderConfiguration(); childConfig.registerImplementation(OtherSingletonObject.class, OtherSingletonObject.class); GuiceComponentProvider child = createChild(parent, childConfig); assertNotSame(parent, child); assertNotNull(parent.getComponent(SingletonObject.class)); assertNotNull(child.getComponent(SingletonObject.class)); assertSame(parent.getComponent(SingletonObject.class), child.getComponent(SingletonObject.class)); try{ parent.getComponent(OtherSingletonObject.class); fail("the parent should not know " + OtherSingletonObject.class); } catch(NoSuchComponentException e){ // this is expected } assertNotNull(child.getComponent(OtherSingletonObject.class)); } @Singleton public static class SingletonWithPropertyDependencies { private String alpha; @Inject @Named("beta") private Provider<Boolean> beta; @Inject public SingletonWithPropertyDependencies(@Named("alpha") String alpha) { this.alpha = alpha; } public String getAlpha() { return alpha; } public Boolean getBeta() { return beta.get(); } } @Test public void canAccessProperties() throws IOException { Properties properties = new Properties(); properties.setProperty("alpha", "AAA"); properties.setProperty("beta", "true"); TestMagnoliaConfigurationProperties configurationProperties = new TestMagnoliaConfigurationProperties(properties); ComponentProviderConfiguration parentConfiguration = new ComponentProviderConfiguration(); parentConfiguration.registerInstance(MagnoliaConfigurationProperties.class, configurationProperties); GuiceComponentProvider parent = new GuiceComponentProviderBuilder().withConfiguration(parentConfiguration).build(); ComponentProviderConfiguration childConfiguration = new ComponentProviderConfiguration(); childConfiguration.registerImplementation(SingletonWithPropertyDependencies.class); GuiceComponentProvider child = new GuiceComponentProviderBuilder().withConfiguration(childConfiguration).withParent(parent).build(); SingletonWithPropertyDependencies component = child.getComponent(SingletonWithPropertyDependencies.class); assertEquals("AAA", component.getAlpha()); assertTrue(component.getBeta()); } private GuiceComponentProvider createComponentProviderWithContent2Bean(ComponentProviderConfiguration configuration, boolean exposeGlobally) { 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 createComponentProvider(configuration, exposeGlobally); } private GuiceComponentProvider createComponentProvider(ComponentProviderConfiguration configuration) { return createComponentProvider(configuration, false); } private GuiceComponentProvider createComponentProvider(ComponentProviderConfiguration configuration, boolean exposeGlobally) { GuiceComponentProviderBuilder builder = new GuiceComponentProviderBuilder().withConfiguration(configuration); if (exposeGlobally) { builder.exposeGlobally(); } return builder.build(); } public GuiceComponentProvider createChild(GuiceComponentProvider parent, ComponentProviderConfiguration configuration) { return new GuiceComponentProviderBuilder().withConfiguration(configuration).withParent(parent).build(); } }