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 }