001    package org.picocontainer.behaviors;
002    
003    import org.picocontainer.Characteristics;
004    import org.picocontainer.ComponentAdapter;
005    import org.picocontainer.ComponentFactory;
006    import org.picocontainer.DefaultPicoContainer;
007    import org.picocontainer.lifecycle.NullLifecycleStrategy;
008    import org.picocontainer.monitors.NullComponentMonitor;
009    import org.picocontainer.adapters.InstanceAdapter;
010    import org.picocontainer.injectors.AdaptiveInjection;
011    import org.picocontainer.injectors.ConstructorInjection;
012    import org.picocontainer.injectors.ConstructorInjector;
013    import org.picocontainer.tck.AbstractComponentFactoryTestCase;
014    
015    public class ImplementationHidingTestCase extends AbstractComponentFactoryTestCase {
016    
017    
018    
019        public void testAddComponentUsesImplementationHidingBehavior() {
020            DefaultPicoContainer pico =
021                new DefaultPicoContainer(new ImplementationHiding().wrap(new ConstructorInjection()));
022            pico.addComponent("foo", String.class);
023            ComponentAdapter foo = pico.getComponentAdapter("foo");
024            assertEquals(HiddenImplementation.class, foo.getClass());
025            assertEquals(ConstructorInjector.class, ((AbstractBehavior) foo).getDelegate().getClass());
026        }
027    
028        public void testAddComponentUsesImplementationHidingBehaviorWithRedundantHideImplProperty() {
029            DefaultPicoContainer pico =
030                new DefaultPicoContainer(new ImplementationHiding().wrap(new ConstructorInjection()));
031            pico.change(Characteristics.HIDE_IMPL).addComponent("foo", String.class);
032            ComponentAdapter foo = pico.getComponentAdapter("foo");
033            assertEquals(HiddenImplementation.class, foo.getClass());
034            assertEquals(ConstructorInjector.class, ((AbstractBehavior) foo).getDelegate().getClass());
035        }
036    
037        public void testAddComponentNoesNotUseImplementationHidingBehaviorWhenNoCachePropertyIsSpecified() {
038            DefaultPicoContainer pico =
039                new DefaultPicoContainer(new ImplementationHiding().wrap(new ConstructorInjection()));
040            pico.change(Characteristics.NO_HIDE_IMPL).addComponent("foo", String.class);
041            ComponentAdapter foo = pico.getComponentAdapter("foo");
042            assertEquals(ConstructorInjector.class, foo.getClass());
043        }
044    
045        public void testAddAdapterUsesImplementationHidingBehavior() {
046            DefaultPicoContainer pico =
047                new DefaultPicoContainer(new ImplementationHiding().wrap(new ConstructorInjection()));
048            pico.addAdapter(new InstanceAdapter("foo", "bar", new NullLifecycleStrategy(), new NullComponentMonitor()));
049            ComponentAdapter foo = pico.getComponentAdapter("foo");
050            assertEquals(HiddenImplementation.class, foo.getClass());
051            assertEquals(InstanceAdapter.class, ((AbstractBehavior) foo).getDelegate().getClass());
052        }
053    
054        public void testAddAdapterUsesImplementationHidingBehaviorWithRedundantHideImplProperty() {
055            DefaultPicoContainer pico =
056                new DefaultPicoContainer(new ImplementationHiding().wrap(new ConstructorInjection()));
057            pico.change(Characteristics.HIDE_IMPL).addAdapter(new InstanceAdapter("foo", "bar", new NullLifecycleStrategy(), new NullComponentMonitor()));
058            ComponentAdapter foo = pico.getComponentAdapter("foo");
059            assertEquals(HiddenImplementation.class, foo.getClass());
060            assertEquals(InstanceAdapter.class, ((AbstractBehavior) foo).getDelegate().getClass());
061        }
062    
063        public void testAddAdapterNoesNotUseImplementationHidingBehaviorWhenNoCachePropertyIsSpecified() {
064            DefaultPicoContainer pico =
065                new DefaultPicoContainer(new ImplementationHiding().wrap(new ConstructorInjection()));
066            pico.change(Characteristics.NO_HIDE_IMPL).addAdapter(new InstanceAdapter("foo", "bar", new NullLifecycleStrategy(), new NullComponentMonitor()));
067            ComponentAdapter foo = pico.getComponentAdapter("foo");
068            assertEquals(InstanceAdapter.class, foo.getClass());
069        }
070    
071    
072        private final ComponentFactory implementationHidingComponentFactory =
073            new ImplementationHiding().wrap(new AdaptiveInjection());
074    
075        protected ComponentFactory createComponentFactory() {
076            return implementationHidingComponentFactory;
077        }
078    
079    
080        public static interface NeedsStringBuilder {
081            void foo();
082        }
083        public static class NeedsStringBuilderImpl implements NeedsStringBuilder {
084            StringBuilder sb;
085    
086            public NeedsStringBuilderImpl(StringBuilder sb) {
087                this.sb = sb;
088                sb.append("<init>");
089            }
090            public void foo() {
091                sb.append("foo()");
092            }
093        }
094        public static class NeedsNeedsStringBuilder {
095    
096            NeedsStringBuilder nsb;
097    
098            public NeedsNeedsStringBuilder(NeedsStringBuilder nsb) {
099                this.nsb = nsb;
100            }
101            public void foo() {
102                nsb.foo();
103            }
104        }
105    
106        public void testLazyInstantiationSideEffectWhenForceOfDelayedInstantiationOfDependantClass() {
107            DefaultPicoContainer pico =
108                new DefaultPicoContainer(new ImplementationHiding().wrap(new Caching().wrap(new ConstructorInjection())));
109            pico.addComponent(StringBuilder.class);
110            pico.addComponent(NeedsStringBuilder.class, NeedsStringBuilderImpl.class);
111            pico.addComponent(NeedsNeedsStringBuilder.class);
112            NeedsNeedsStringBuilder nnsb = pico.getComponent(NeedsNeedsStringBuilder.class);
113            assertNotNull(nnsb);
114            StringBuilder sb = pico.getComponent(StringBuilder.class);
115            assertEquals("", sb.toString()); // not instantiated yet
116            nnsb.foo();
117            assertEquals("<init>foo()", sb.toString()); // instantiated
118        }
119    
120    
121    }