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    
020    public class ThreadCachingTestCase {
021    
022        public static class Foo {
023            public Foo(StringBuilder sb) {
024                sb.append("<Foo");
025            }
026        }
027    
028        public static class Bar {
029            private final Foo foo;
030            public Bar(StringBuilder sb, Foo foo) {
031                this.foo = foo;
032                sb.append("<Bar");
033            }
034        }
035    
036        @Test public void testThatForASingleThreadTheBehaviorIsTheSameAsPlainCaching() {
037    
038            DefaultPicoContainer parent = new DefaultPicoContainer(new Caching());
039            DefaultPicoContainer child = new DefaultPicoContainer(new ThreadCaching(), parent);
040    
041            parent.addComponent(StringBuilder.class);
042            child.addComponent(Foo.class);
043    
044            StringBuilder sb = parent.getComponent(StringBuilder.class);
045            Foo foo = child.getComponent(Foo.class);
046            Foo foo2 = child.getComponent(Foo.class);
047            assertNotNull(foo);
048            assertNotNull(foo2);
049            assertEquals(foo,foo2);
050            assertEquals("<Foo", sb.toString());
051            assertEquals("ThreadCached:ConstructorInjector-class org.picocontainer.behaviors.ThreadCachingTestCase$Foo", child.getComponentAdapter(Foo.class).toString());
052        }
053    
054        @Test public void testThatTwoThreadsHaveSeparatedCacheValues() {
055    
056            final Foo[] foos = new Foo[4];
057    
058            DefaultPicoContainer parent = new DefaultPicoContainer(new Caching());
059            final DefaultPicoContainer child = new DefaultPicoContainer(new ThreadCaching(), parent);
060    
061            parent.addComponent(StringBuilder.class);
062            child.addComponent(Foo.class);
063    
064            StringBuilder sb = parent.getComponent(StringBuilder.class);
065            foos[0] = child.getComponent(Foo.class);
066    
067            Thread thread = new Thread() {
068                public void run() {
069                    foos[1] = child.getComponent(Foo.class);
070                    foos[3] = child.getComponent(Foo.class);
071                }
072            };
073            thread.start();
074            foos[2] = child.getComponent(Foo.class);
075            try {
076                Thread.sleep(100);
077            } catch (InterruptedException e) {
078            }
079    
080            assertNotNull(foos[0]);
081            assertNotNull(foos[1]);
082            assertNotNull(foos[2]);
083            assertNotNull(foos[3]);
084            assertSame(foos[0],foos[2]);
085            assertEquals(foos[1],foos[3]);
086            assertFalse(foos[0] == foos[1]);
087            assertEquals("<Foo<Foo", sb.toString());
088            assertEquals("ThreadCached:ConstructorInjector-class org.picocontainer.behaviors.ThreadCachingTestCase$Foo", child.getComponentAdapter(Foo.class).toString());
089        }
090    
091        @Test public void testThatTwoThreadsHaveSeparatedCacheValuesForThreeScopeScenario() {
092    
093            final Foo[] foos = new Foo[4];
094            final Bar[] bars = new Bar[4];
095    
096            DefaultPicoContainer appScope = new DefaultPicoContainer(new Caching());
097            final DefaultPicoContainer sessionScope = new DefaultPicoContainer(new ThreadCaching(), appScope);
098            final DefaultPicoContainer requestScope = new DefaultPicoContainer(new ThreadCaching(), sessionScope);
099    
100            appScope.addComponent(StringBuilder.class);
101            sessionScope.addComponent(Foo.class);
102            requestScope.addComponent(Bar.class);
103    
104            StringBuilder sb = appScope.getComponent(StringBuilder.class);
105            foos[0] = sessionScope.getComponent(Foo.class);
106            bars[0] = requestScope.getComponent(Bar.class);
107    
108            Thread thread = new Thread() {
109                public void run() {
110                    foos[1] = sessionScope.getComponent(Foo.class);
111                    bars[1] = requestScope.getComponent(Bar.class);
112                    foos[3] = sessionScope.getComponent(Foo.class);
113                    bars[3] = requestScope.getComponent(Bar.class);
114                }
115            };
116            thread.start();
117            foos[2] = sessionScope.getComponent(Foo.class);
118            bars[2] = requestScope.getComponent(Bar.class);
119            try {
120                Thread.sleep(100);
121            } catch (InterruptedException e) {
122            }
123    
124            assertSame(bars[0],bars[2]);
125            assertEquals(bars[1],bars[3]);
126            assertFalse(bars[0] == bars[1]);
127            assertSame(bars[0].foo,foos[0]);
128            assertSame(bars[1].foo,foos[1]);
129            assertSame(bars[2].foo,foos[2]);
130            assertSame(bars[3].foo,foos[3]);
131            assertEquals("<Foo<Bar<Foo<Bar", sb.toString());
132            assertEquals("ThreadCached:ConstructorInjector-class org.picocontainer.behaviors.ThreadCachingTestCase$Foo", sessionScope.getComponentAdapter(Foo.class).toString());
133        }
134    
135    
136    }