001    /*****************************************************************************
002     * Copyright (C) PicoContainer Organization. All rights reserved.            *
003     * ------------------------------------------------------------------------- *
004     * The software in this package is published under the terms of the BSD      *
005     * style license a copy of which has been included with this distribution in *
006     * the LICENSE.txt file.                                                     *
007     *                                                                           *
008     * Original code by                                                          *
009     *****************************************************************************/
010    package org.picocontainer.behaviors;
011    
012    import static org.junit.Assert.assertEquals;
013    import static org.junit.Assert.assertFalse;
014    import static org.junit.Assert.assertNotNull;
015    import static org.junit.Assert.assertSame;
016    
017    import org.junit.Test;
018    import org.picocontainer.DefaultPicoContainer;
019    import org.picocontainer.containers.EmptyPicoContainer;
020    import org.picocontainer.lifecycle.NullLifecycleStrategy;
021    
022    public class ThreadCachingTestCase {
023    
024        public static class Foo {
025            public Foo(StringBuilder sb) {
026                sb.append("<Foo");
027            }
028        }
029    
030        public static class Bar {
031            private final Foo foo;
032            public Bar(StringBuilder sb, Foo foo) {
033                this.foo = foo;
034                sb.append("<Bar");
035            }
036        }
037    
038        @Test public void testThatForASingleThreadTheBehaviorIsTheSameAsPlainCaching() {
039    
040            DefaultPicoContainer parent = new DefaultPicoContainer(new Caching());
041            DefaultPicoContainer child = new DefaultPicoContainer(new ThreadCaching(), new NullLifecycleStrategy(), parent);
042    
043            parent.addComponent(StringBuilder.class);
044            child.addComponent(Foo.class);
045    
046            StringBuilder sb = parent.getComponent(StringBuilder.class);
047            Foo foo = child.getComponent(Foo.class);
048            Foo foo2 = child.getComponent(Foo.class);
049            assertNotNull(foo);
050            assertNotNull(foo2);
051            assertEquals(foo,foo2);
052            assertEquals("<Foo", sb.toString());
053            assertEquals("ThreadCached:ConstructorInjector-class org.picocontainer.behaviors.ThreadCachingTestCase$Foo", child.getComponentAdapter(Foo.class).toString());
054        }
055    
056        @Test public void testThatTwoThreadsHaveSeparatedCacheValues() {
057    
058            final Foo[] foos = new Foo[4];
059    
060            DefaultPicoContainer parent = new DefaultPicoContainer(new Caching());
061            final DefaultPicoContainer child = new DefaultPicoContainer(new ThreadCaching(), new NullLifecycleStrategy(), parent);
062    
063            parent.addComponent(StringBuilder.class);
064            child.addComponent(Foo.class);
065    
066            StringBuilder sb = parent.getComponent(StringBuilder.class);
067            foos[0] = child.getComponent(Foo.class);
068    
069            Thread thread = new Thread() {
070                public void run() {
071                    foos[1] = child.getComponent(Foo.class);
072                    foos[3] = child.getComponent(Foo.class);
073                }
074            };
075            thread.start();
076            foos[2] = child.getComponent(Foo.class);
077            try {
078                Thread.sleep(100);
079            } catch (InterruptedException e) {
080            }
081    
082            assertNotNull(foos[0]);
083            assertNotNull(foos[1]);
084            assertNotNull(foos[2]);
085            assertNotNull(foos[3]);
086            assertSame(foos[0],foos[2]);
087            assertEquals(foos[1],foos[3]);
088            assertFalse(foos[0] == foos[1]);
089            assertEquals("<Foo<Foo", sb.toString());
090            assertEquals("ThreadCached:ConstructorInjector-class org.picocontainer.behaviors.ThreadCachingTestCase$Foo", child.getComponentAdapter(Foo.class).toString());
091        }
092    
093        @Test public void testThatTwoThreadsHaveSeparatedCacheValuesForThreeScopeScenario() {
094    
095            final Foo[] foos = new Foo[4];
096            final Bar[] bars = new Bar[4];
097    
098            DefaultPicoContainer appScope = new DefaultPicoContainer(new Caching());
099            final DefaultPicoContainer sessionScope = new DefaultPicoContainer(new ThreadCaching(), new NullLifecycleStrategy(), appScope);
100            final DefaultPicoContainer requestScope = new DefaultPicoContainer(new ThreadCaching(), new NullLifecycleStrategy(), sessionScope);
101    
102            appScope.addComponent(StringBuilder.class);
103            sessionScope.addComponent(Foo.class);
104            requestScope.addComponent(Bar.class);
105    
106            StringBuilder sb = appScope.getComponent(StringBuilder.class);
107            foos[0] = sessionScope.getComponent(Foo.class);
108            bars[0] = requestScope.getComponent(Bar.class);
109    
110            Thread thread = new Thread() {
111                public void run() {
112                    foos[1] = sessionScope.getComponent(Foo.class);
113                    bars[1] = requestScope.getComponent(Bar.class);
114                    foos[3] = sessionScope.getComponent(Foo.class);
115                    bars[3] = requestScope.getComponent(Bar.class);
116                }
117            };
118            thread.start();
119            foos[2] = sessionScope.getComponent(Foo.class);
120            bars[2] = requestScope.getComponent(Bar.class);
121            try {
122                Thread.sleep(100);
123            } catch (InterruptedException e) {
124            }
125    
126            assertSame(bars[0],bars[2]);
127            assertEquals(bars[1],bars[3]);
128            assertFalse(bars[0] == bars[1]);
129            assertSame(bars[0].foo,foos[0]);
130            assertSame(bars[1].foo,foos[1]);
131            assertSame(bars[2].foo,foos[2]);
132            assertSame(bars[3].foo,foos[3]);
133            assertEquals("<Foo<Bar<Foo<Bar", sb.toString());
134            assertEquals("ThreadCached:ConstructorInjector-class org.picocontainer.behaviors.ThreadCachingTestCase$Foo", sessionScope.getComponentAdapter(Foo.class).toString());
135        }
136    
137    
138    }