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 }