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