1 10 package org.picocontainer.gems.adapters; 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 ; 24 import java.util.Collections ; 25 import java.util.HashSet ; 26 import java.util.List ; 27 import java.util.Set ; 28 29 30 35 public class ThreadLocalComponentAdapterTest extends AbstractComponentAdapterTestCase { 36 37 protected Class getComponentAdapterType() { 38 return ThreadLocalComponentAdapter.class; 39 } 40 41 protected int getComponentAdapterNature() { 42 return super.getComponentAdapterNature() & ~(RESOLVING | VERIFYING | INSTANTIATING); 43 } 44 45 private ComponentAdapter createComponentAdapterWithSimpleTouchable() { 46 return new ThreadLocalComponentAdapter(new ConstructorInjectionComponentAdapter( 47 Touchable.class, SimpleTouchable.class, null)); 48 } 49 50 protected ComponentAdapter prepDEF_verifyWithoutDependencyWorks(MutablePicoContainer picoContainer) { 51 return createComponentAdapterWithSimpleTouchable(); 52 } 53 54 protected ComponentAdapter prepDEF_verifyDoesNotInstantiate(MutablePicoContainer picoContainer) { 55 return createComponentAdapterWithSimpleTouchable(); 56 } 57 58 protected ComponentAdapter prepDEF_visitable() { 59 return createComponentAdapterWithSimpleTouchable(); 60 } 61 62 protected ComponentAdapter prepDEF_isAbleToTakeParameters(MutablePicoContainer picoContainer) { 63 return new ThreadLocalComponentAdapter(new ConstructorInjectionComponentAdapter( 64 List .class, ArrayList .class, new Parameter[]{new ConstantParameter(new Integer (10))})); 65 } 66 67 protected ComponentAdapter prepSER_isSerializable(MutablePicoContainer picoContainer) { 68 return createComponentAdapterWithSimpleTouchable(); 69 } 70 71 protected ComponentAdapter prepSER_isXStreamSerializable(MutablePicoContainer picoContainer) { 72 return createComponentAdapterWithSimpleTouchable(); 73 } 74 75 78 public static class Runner implements Runnable { 79 80 private final Touchable m_touchable; 81 private final List m_list; 82 private final Set m_set; 83 84 91 public Runner(final Touchable touchable, final List list, final Set set) { 92 m_touchable = touchable; 93 m_list = list; 94 m_set = set; 95 } 96 97 100 public void run() { 101 final Thread thread = Thread.currentThread(); 102 while (!Thread.interrupted()) { 103 m_set.add(m_touchable); 104 m_list.add(m_touchable); 105 try { 106 synchronized (thread) { 107 thread.wait(); 108 } 109 } catch (InterruptedException e) { 110 thread.interrupt(); 111 } 112 } 113 } 114 } 115 116 121 public final void testInstancesUsedFromMultipleThreads() throws InterruptedException { 122 final Set set = Collections.synchronizedSet(new HashSet ()); 123 final List list = Collections.synchronizedList(new ArrayList ()); 124 final ComponentAdapter componentAdapter = new ThreadLocalComponentAdapter(new ConstructorInjectionComponentAdapter( 125 Touchable.class, SimpleTouchable.class, null)); 126 final Touchable touchable = (Touchable)componentAdapter.getComponentInstance(null); 127 128 final Thread [] threads = { 129 new Thread (new Runner(touchable, list, set), "junit-1"), new Thread (new Runner(touchable, list, set), "junit-2"), 130 new Thread (new Runner(touchable, list, set), "junit-3"),}; 131 for (int i = threads.length; i-- > 0;) { 132 threads[i].start(); 133 } 134 Thread.sleep(300); 135 for (int i = threads.length; i-- > 0;) { 136 synchronized (threads[i]) { 137 threads[i].notify(); 138 } 139 } 140 Thread.sleep(300); 141 for (int i = threads.length; i-- > 0;) { 142 threads[i].interrupt(); 143 } 144 Thread.sleep(300); 145 assertEquals(6, list.size()); 146 assertEquals(3, set.size()); 147 } 148 149 154 public void testThreadLocalInstancesEqual() throws Exception { 155 final ComponentAdapter componentAdapter = new ThreadLocalComponentAdapter(new ConstructorInjectionComponentAdapter( 156 Touchable.class, SimpleTouchable.class, null)); 157 final Touchable touchable = (Touchable)componentAdapter.getComponentInstance(null); 158 assertEquals(touchable, touchable); 159 } 160 161 164 public final void testInstancesAreNotSharedBetweenContainers() { 165 final MutablePicoContainer picoA = new DefaultPicoContainer(); 166 final MutablePicoContainer picoB = new DefaultPicoContainer(); 167 picoA.registerComponent(new ThreadLocalComponentAdapter(new ConstructorInjectionComponentAdapter( 168 List .class, ArrayList .class, null))); 169 picoB.registerComponent(new ThreadLocalComponentAdapter(new ConstructorInjectionComponentAdapter( 170 List .class, ArrayList .class, null))); 171 final List hello1 = (List )picoA.getComponentInstance(List .class); 172 final List hello2 = (List )picoA.getComponentInstance(List .class); 173 hello1.add("foo"); 174 assertEquals(hello1, hello2); 175 final List hello3 = (List )picoB.getComponentInstance(List .class); 176 assertEquals(0, hello3.size()); 177 } 178 179 182 public void testComponentMustImplementInterface() { 183 try { 184 new ThreadLocalComponentAdapter(new ConstructorInjectionComponentAdapter(Object .class, Object .class, null)); 185 fail("PicoIntrospectionException expected"); 186 } catch (final PicoIntrospectionException e) { 187 assertTrue(e.getMessage().endsWith("It does not implement any interfaces.")); 188 } 189 } 190 191 public static interface TargetInvocationExceptionTester { 192 public void throwsCheckedException() throws ClassNotFoundException ; 193 194 public void throwsRuntimeException(); 195 196 public void throwsError(); 197 } 198 199 public static class ThrowingComponent implements TargetInvocationExceptionTester { 200 public void throwsCheckedException() throws ClassNotFoundException { 201 throw new ClassNotFoundException ("junit"); 202 } 203 204 public void throwsRuntimeException() { 205 throw new RuntimeException ("junit"); 206 } 207 208 public void throwsError() { 209 throw new Error ("junit"); 210 } 211 } 212 213 public void testExceptionHandling() { 214 final ComponentAdapter componentAdapter = new ThreadLocalComponentAdapter(new ConstructorInjectionComponentAdapter( 215 TargetInvocationExceptionTester.class, ThrowingComponent.class, null)); 216 final TargetInvocationExceptionTester tester = (TargetInvocationExceptionTester)componentAdapter.getComponentInstance(null); 217 try { 218 tester.throwsCheckedException(); 219 fail("ClassNotFoundException expected"); 220 } catch (final ClassNotFoundException e) { 221 assertEquals("junit", e.getMessage()); 222 } 223 try { 224 tester.throwsRuntimeException(); 225 fail("RuntimeException expected"); 226 } catch (final RuntimeException e) { 227 assertEquals("junit", e.getMessage()); 228 } 229 try { 230 tester.throwsError(); 231 fail("Error expected"); 232 } catch (final Error e) { 233 assertEquals("junit", e.getMessage()); 234 } 235 } 236 237 240 public final void testSimpleKeys() { 241 final ComponentAdapter componentAdapter = new ThreadLocalComponentAdapter(new ConstructorInjectionComponentAdapter( 242 "List", ArrayList .class, null)); 243 final List hello = (List )componentAdapter.getComponentInstance(null); 244 assertNotNull(hello); 245 } 246 } 247 | Popular Tags |