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 org.picocontainer.DefaultPicoContainer;
013    
014    import junit.framework.TestCase;
015    
016    public class StoringTestCase extends TestCase {
017    
018        public static class Foo {
019            public Foo(StringBuilder sb) {
020                sb.append("<Foo");
021            }
022        }
023    
024        public static class Bar {
025            private final Foo foo;
026            public Bar(StringBuilder sb, Foo foo) {
027                this.foo = foo;
028                sb.append("<Bar");
029            }
030        }
031    
032        public void testThatForASingleThreadTheBehaviorIsTheSameAsPlainCaching() {
033    
034            DefaultPicoContainer parent = new DefaultPicoContainer(new Caching());
035            Storing storeCaching = new Storing();
036            DefaultPicoContainer child = new DefaultPicoContainer(storeCaching, parent);
037    
038            parent.addComponent(StringBuilder.class);
039            child.addComponent(Foo.class);
040    
041            StringBuilder sb = parent.getComponent(StringBuilder.class);
042            Foo foo = child.getComponent(Foo.class);
043            Foo foo2 = child.getComponent(Foo.class);
044            assertNotNull(foo);
045            assertNotNull(foo2);
046            assertEquals(foo,foo2);
047            assertEquals("<Foo", sb.toString());
048            assertEquals("Cached:ConstructorInjector-class org.picocontainer.behaviors.StoringTestCase$Foo", child.getComponentAdapter(Foo.class).toString());
049        }
050    
051        public void testThatTwoThreadsHaveSeparatedCacheValues() {
052    
053            final Foo[] foos = new Foo[4];
054    
055            DefaultPicoContainer parent = new DefaultPicoContainer(new Caching());
056            final DefaultPicoContainer child = new DefaultPicoContainer(new Storing(), parent);
057    
058            parent.addComponent(StringBuilder.class);
059            child.addComponent(Foo.class);
060    
061            StringBuilder sb = parent.getComponent(StringBuilder.class);
062            foos[0] = child.getComponent(Foo.class);
063    
064            Thread thread = new Thread() {
065                public void run() {
066                    foos[1] = child.getComponent(Foo.class);
067                    foos[3] = child.getComponent(Foo.class);
068                }
069            };
070            thread.start();
071            foos[2] = child.getComponent(Foo.class);
072            sleepALittle();
073    
074            assertNotNull(foos[0]);
075            assertNotNull(foos[1]);
076            assertNotNull(foos[2]);
077            assertNotNull(foos[3]);
078            assertSame(foos[0],foos[2]);
079            assertEquals(foos[1],foos[3]);
080            assertFalse(foos[0] == foos[1]);
081            assertEquals("<Foo<Foo", sb.toString());
082            assertEquals("Cached:ConstructorInjector-class org.picocontainer.behaviors.StoringTestCase$Foo", child.getComponentAdapter(Foo.class).toString());
083        }
084    
085        public void testThatTwoThreadsHaveSeparatedCacheValuesForThreeScopeScenario() {
086    
087            final Foo[] foos = new Foo[4];
088            final Bar[] bars = new Bar[4];
089    
090            DefaultPicoContainer appScope = new DefaultPicoContainer(new Caching());
091            final DefaultPicoContainer sessionScope = new DefaultPicoContainer(new Storing(), appScope);
092            final DefaultPicoContainer requestScope = new DefaultPicoContainer(new Storing(), sessionScope);
093    
094            appScope.addComponent(StringBuilder.class);
095            sessionScope.addComponent(Foo.class);
096            requestScope.addComponent(Bar.class);
097    
098            StringBuilder sb = appScope.getComponent(StringBuilder.class);
099            foos[0] = sessionScope.getComponent(Foo.class);
100            bars[0] = requestScope.getComponent(Bar.class);
101    
102            Thread thread = new Thread() {
103                public void run() {
104                    foos[1] = sessionScope.getComponent(Foo.class);
105                    bars[1] = requestScope.getComponent(Bar.class);
106                    foos[3] = sessionScope.getComponent(Foo.class);
107                    bars[3] = requestScope.getComponent(Bar.class);
108                }
109            };
110            thread.start();
111            foos[2] = sessionScope.getComponent(Foo.class);
112            bars[2] = requestScope.getComponent(Bar.class);
113            sleepALittle();
114    
115            assertSame(bars[0],bars[2]);
116            assertEquals(bars[1],bars[3]);
117            assertFalse(bars[0] == bars[1]);
118            assertSame(bars[0].foo,foos[0]);
119            assertSame(bars[1].foo,foos[1]);
120            assertSame(bars[2].foo,foos[2]);
121            assertSame(bars[3].foo,foos[3]);
122            assertEquals("<Foo<Bar<Foo<Bar", sb.toString());
123            assertEquals("Cached:ConstructorInjector-class org.picocontainer.behaviors.StoringTestCase$Foo", sessionScope.getComponentAdapter(Foo.class).toString());
124        }
125    
126        public void testThatCacheMapCanBeReUsedOnASubsequentThreadSimulatingASessionConcept() {
127    
128            final Foo[] foos = new Foo[4];
129    
130            DefaultPicoContainer parent = new DefaultPicoContainer(new Caching());
131            final Storing storeCaching = new Storing();
132            final DefaultPicoContainer child = new DefaultPicoContainer(storeCaching, parent);
133    
134            parent.addComponent(StringBuilder.class);
135            child.addComponent(Foo.class);
136    
137            StringBuilder sb = parent.getComponent(StringBuilder.class);
138    
139            final Storing.StoreWrapper[] tmpMap = new Storing.StoreWrapper[1];
140            Thread thread = new Thread() {
141                public void run() {
142                    foos[0] = child.getComponent(Foo.class);
143                    foos[1] = child.getComponent(Foo.class);
144                    tmpMap[0] = storeCaching.getCacheForThread();
145    
146                }
147            };
148            thread.start();
149            sleepALittle();
150            thread = new Thread() {
151                public void run() {
152                    storeCaching.putCacheForThread(tmpMap[0]);
153                    foos[2] = child.getComponent(Foo.class);
154                    foos[3] = child.getComponent(Foo.class);
155                    tmpMap[0] = storeCaching.getCacheForThread();
156    
157                }
158            };
159            thread.start();
160            sleepALittle();
161    
162            assertNotNull(foos[0]);
163            assertNotNull(foos[1]);
164            assertNotNull(foos[2]);
165            assertNotNull(foos[3]);
166            assertSame(foos[0],foos[1]);
167            assertSame(foos[1],foos[2]);
168            assertSame(foos[2],foos[3]);
169            assertEquals("<Foo", sb.toString());
170            assertEquals("Cached:ConstructorInjector-class org.picocontainer.behaviors.StoringTestCase$Foo", child.getComponentAdapter(Foo.class).toString());
171        }
172    
173        private void sleepALittle() {
174            try {
175                Thread.sleep(100);
176            } catch (InterruptedException e) {
177            }
178        }
179    
180    
181    }