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 }