KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > picocontainer > gems > ThreadLocalComponentAdapterTest


1 /*****************************************************************************
2  * Copyright (c) PicoContainer Organization. All rights reserved. *
3  * ------------------------------------------------------------------------- *
4  * The software in this package is published under the terms of the BSD *
5  * style license a copy of which has been included with this distribution in *
6  * the LICENSE.txt file. *
7  * *
8  * Original code by Joerg Schaible *
9  *****************************************************************************/

10 package org.picocontainer.gems;
11
12 import org.picocontainer.ComponentAdapter;
13 import org.picocontainer.MutablePicoContainer;
14 import org.picocontainer.Parameter;
15 import org.picocontainer.PicoIntrospectionException;
16 import org.picocontainer.defaults.ConstantParameter;
17 import org.picocontainer.defaults.ConstructorInjectionComponentAdapter;
18 import org.picocontainer.defaults.DefaultPicoContainer;
19 import org.picocontainer.tck.AbstractComponentAdapterTestCase;
20 import org.picocontainer.testmodel.SimpleTouchable;
21 import org.picocontainer.testmodel.Touchable;
22
23 import java.util.ArrayList JavaDoc;
24 import java.util.Collections JavaDoc;
25 import java.util.HashSet JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Set JavaDoc;
28
29
30 /**
31  * Unit test for ThreadLocalComponentAdapter.
32  * @author Jörg Schaible
33  */

34 public class ThreadLocalComponentAdapterTest extends AbstractComponentAdapterTestCase {
35
36     protected Class JavaDoc getComponentAdapterType() {
37         return ThreadLocalComponentAdapter.class;
38     }
39
40     protected int getComponentAdapterNature() {
41         return super.getComponentAdapterNature() & ~(RESOLVING | VERIFYING | INSTANTIATING);
42     }
43
44     private ComponentAdapter createComponentAdapterWithSimpleTouchable() {
45         return new ThreadLocalComponentAdapter(new ConstructorInjectionComponentAdapter(
46                 Touchable.class, SimpleTouchable.class, null));
47     }
48
49     protected ComponentAdapter prepDEF_verifyWithoutDependencyWorks(MutablePicoContainer picoContainer) {
50         return createComponentAdapterWithSimpleTouchable();
51     }
52
53     protected ComponentAdapter prepDEF_verifyDoesNotInstantiate(MutablePicoContainer picoContainer) {
54         return createComponentAdapterWithSimpleTouchable();
55     }
56
57     protected ComponentAdapter prepDEF_visitable() {
58         return createComponentAdapterWithSimpleTouchable();
59     }
60
61     protected ComponentAdapter prepDEF_isAbleToTakeParameters(MutablePicoContainer picoContainer) {
62         return new ThreadLocalComponentAdapter(new ConstructorInjectionComponentAdapter(
63                 List JavaDoc.class, ArrayList JavaDoc.class, new Parameter[]{new ConstantParameter(new Integer JavaDoc(10))}));
64     }
65
66     protected ComponentAdapter prepSER_isSerializable(MutablePicoContainer picoContainer) {
67         return createComponentAdapterWithSimpleTouchable();
68     }
69
70     protected ComponentAdapter prepSER_isXStreamSerializable(MutablePicoContainer picoContainer) {
71         return createComponentAdapterWithSimpleTouchable();
72     }
73
74     /**
75      * Helper class testing ThreadLocal cache.
76      */

77     public static class Runner implements Runnable JavaDoc {
78
79         private final Touchable m_touchable;
80         private final List JavaDoc m_list;
81         private final Set JavaDoc m_set;
82
83         /**
84          * Constructs a Runner.
85          * @param touchable The instance
86          * @param list The list to which all instances are added
87          * @param set The set to which all instances are added
88          */

89         public Runner(final Touchable touchable, final List JavaDoc list, final Set JavaDoc set) {
90             m_touchable = touchable;
91             m_list = list;
92             m_set = set;
93         }
94
95         /**
96          * @see java.lang.Runnable#run()
97          */

98         public void run() {
99             final Thread JavaDoc thread = Thread.currentThread();
100             while (!Thread.interrupted()) {
101                 m_set.add(m_touchable);
102                 m_list.add(m_touchable);
103                 try {
104                     synchronized (thread) {
105                         thread.wait();
106                     }
107                 } catch (InterruptedException JavaDoc e) {
108                     thread.interrupt();
109                 }
110             }
111         }
112     }
113
114     /**
115      * Test usage from multiple threads.
116      * @throws InterruptedException
117      */

118     public final void testInstancesUsedFromMultipleThreads() throws InterruptedException JavaDoc {
119         final Set JavaDoc set = Collections.synchronizedSet(new HashSet JavaDoc());
120         final List JavaDoc list = Collections.synchronizedList(new ArrayList JavaDoc());
121         final ComponentAdapter componentAdapter = new ThreadLocalComponentAdapter(new ConstructorInjectionComponentAdapter(
122                 Touchable.class, SimpleTouchable.class, null));
123         final Touchable touchable = (Touchable)componentAdapter.getComponentInstance(null);
124
125         final Thread JavaDoc[] threads = {
126                 new Thread JavaDoc(new Runner(touchable, list, set), "junit-1"), new Thread JavaDoc(new Runner(touchable, list, set), "junit-2"),
127                 new Thread JavaDoc(new Runner(touchable, list, set), "junit-3"),};
128         for (int i = threads.length; i-- > 0;) {
129             threads[i].start();
130         }
131         Thread.sleep(300);
132         for (int i = threads.length; i-- > 0;) {
133             synchronized (threads[i]) {
134                 threads[i].notify();
135             }
136         }
137         Thread.sleep(300);
138         for (int i = threads.length; i-- > 0;) {
139             threads[i].interrupt();
140         }
141         Thread.sleep(300);
142         assertEquals(6, list.size());
143         assertEquals(3, set.size());
144     }
145
146     /**
147      * Test instances from different containers.
148      */

149     public final void testInstancesAreNotSharedBetweenContainers() {
150         final MutablePicoContainer picoA = new DefaultPicoContainer();
151         final MutablePicoContainer picoB = new DefaultPicoContainer();
152         picoA.registerComponent(new ThreadLocalComponentAdapter(new ConstructorInjectionComponentAdapter(
153                 List JavaDoc.class, ArrayList JavaDoc.class, null)));
154         picoB.registerComponent(new ThreadLocalComponentAdapter(new ConstructorInjectionComponentAdapter(
155                 List JavaDoc.class, ArrayList JavaDoc.class, null)));
156         final List JavaDoc hello1 = (List JavaDoc)picoA.getComponentInstance(List JavaDoc.class);
157         final List JavaDoc hello2 = (List JavaDoc)picoA.getComponentInstance(List JavaDoc.class);
158         hello1.add("foo");
159         assertEquals(hello1, hello2);
160         final List JavaDoc hello3 = (List JavaDoc)picoB.getComponentInstance(List JavaDoc.class);
161         assertEquals(0, hello3.size());
162     }
163
164     /**
165      * Test fail-fast for components without interface.
166      */

167     public void testComponentMustImplementInterface() {
168         try {
169             new ThreadLocalComponentAdapter(new ConstructorInjectionComponentAdapter(Object JavaDoc.class, Object JavaDoc.class, null));
170             fail("PicoIntrospectionException expected");
171         } catch (final PicoIntrospectionException e) {
172             assertTrue(e.getMessage().endsWith("It does not implement any interfaces."));
173         }
174     }
175
176     public static interface TargetInvocationExceptionTester {
177         public void throwsCheckedException() throws ClassNotFoundException JavaDoc;
178
179         public void throwsRuntimeException();
180
181         public void throwsError();
182     }
183
184     public static class ThrowingComponent implements TargetInvocationExceptionTester {
185         public void throwsCheckedException() throws ClassNotFoundException JavaDoc {
186             throw new ClassNotFoundException JavaDoc("junit");
187         }
188
189         public void throwsRuntimeException() {
190             throw new RuntimeException JavaDoc("junit");
191         }
192
193         public void throwsError() {
194             throw new Error JavaDoc("junit");
195         }
196     }
197
198     public void testExceptionHandling() {
199         final ComponentAdapter componentAdapter = new ThreadLocalComponentAdapter(new ConstructorInjectionComponentAdapter(
200                 TargetInvocationExceptionTester.class, ThrowingComponent.class, null));
201         final TargetInvocationExceptionTester tester = (TargetInvocationExceptionTester)componentAdapter.getComponentInstance(null);
202         try {
203             tester.throwsCheckedException();
204             fail("ClassNotFoundException expected");
205         } catch (final ClassNotFoundException JavaDoc e) {
206             assertEquals("junit", e.getMessage());
207         }
208         try {
209             tester.throwsRuntimeException();
210             fail("RuntimeException expected");
211         } catch (final RuntimeException JavaDoc e) {
212             assertEquals("junit", e.getMessage());
213         }
214         try {
215             tester.throwsError();
216             fail("Error expected");
217         } catch (final Error JavaDoc e) {
218             assertEquals("junit", e.getMessage());
219         }
220     }
221
222     /**
223      * Test ComponentAdapter using simple keys.
224      */

225     public final void testSimpleKeys() {
226         final ComponentAdapter componentAdapter = new ThreadLocalComponentAdapter(new ConstructorInjectionComponentAdapter(
227                 "List", ArrayList JavaDoc.class, null));
228         final List JavaDoc hello = (List JavaDoc)componentAdapter.getComponentInstance(null);
229         assertNotNull(hello);
230     }
231 }
232
Popular Tags