1 10 package org.picocontainer.defaults; 11 12 import java.awt.event.ActionEvent ; 13 import java.awt.event.ActionListener ; 14 import java.lang.reflect.Constructor ; 15 import java.lang.reflect.InvocationTargetException ; 16 import java.util.HashMap ; 17 import java.util.Map ; 18 19 import org.jmock.Mock; 20 import org.jmock.core.Constraint; 21 import org.picocontainer.ComponentAdapter; 22 import org.picocontainer.ComponentMonitor; 23 import org.picocontainer.MutablePicoContainer; 24 import org.picocontainer.Parameter; 25 import org.picocontainer.PicoInitializationException; 26 import org.picocontainer.PicoIntrospectionException; 27 import org.picocontainer.PicoRegistrationException; 28 import org.picocontainer.tck.AbstractComponentAdapterTestCase; 29 import org.picocontainer.testmodel.DependsOnTouchable; 30 import org.picocontainer.testmodel.NullLifecycle; 31 import org.picocontainer.testmodel.SimpleTouchable; 32 import org.picocontainer.testmodel.Touchable; 33 34 35 public class ConstructorInjectionComponentAdapterTestCase extends AbstractComponentAdapterTestCase { 36 37 protected Class getComponentAdapterType() { 38 return ConstructorInjectionComponentAdapter.class; 39 } 40 41 protected ComponentAdapter prepDEF_verifyWithoutDependencyWorks(MutablePicoContainer picoContainer) { 42 return new ConstructorInjectionComponentAdapter("foo", A.class); 43 } 44 45 public static class A { 46 public A() { 47 fail("verification should not instantiate"); 48 } 49 } 50 51 public static class B { 52 public B(A a) { 53 fail("verification should not instantiate"); 54 } 55 } 56 57 protected ComponentAdapter prepDEF_verifyDoesNotInstantiate(MutablePicoContainer picoContainer) { 58 picoContainer.registerComponentImplementation(A.class); 59 return new ConstructorInjectionComponentAdapter(B.class, B.class); 60 } 61 62 protected ComponentAdapter prepDEF_visitable() { 63 return new ConstructorInjectionComponentAdapter("bar", B.class, new Parameter[]{ComponentParameter.DEFAULT}); 64 } 65 66 protected ComponentAdapter prepDEF_isAbleToTakeParameters(MutablePicoContainer picoContainer) { 67 picoContainer.registerComponentImplementation(SimpleTouchable.class); 68 return new ConstructorInjectionComponentAdapter( 69 NamedDependsOnTouchable.class, NamedDependsOnTouchable.class, new Parameter[]{ 70 ComponentParameter.DEFAULT, new ConstantParameter("Name")}); 71 } 72 73 protected ComponentAdapter prepSER_isSerializable(MutablePicoContainer picoContainer) { 74 return new ConstructorInjectionComponentAdapter(SimpleTouchable.class, SimpleTouchable.class); 75 } 76 77 protected ComponentAdapter prepSER_isXStreamSerializable(final MutablePicoContainer picoContainer) { 78 return prepSER_isSerializable(picoContainer); 79 } 80 81 public static class NamedDependsOnTouchable extends DependsOnTouchable { 82 public NamedDependsOnTouchable(Touchable t, String name) { 83 super(t); 84 } 85 } 86 87 protected ComponentAdapter prepVER_verificationFails(MutablePicoContainer picoContainer) { 88 return new ConstructorInjectionComponentAdapter(DependsOnTouchable.class, DependsOnTouchable.class); 89 } 90 91 protected ComponentAdapter prepINS_createsNewInstances(MutablePicoContainer picoContainer) { 92 return new ConstructorInjectionComponentAdapter(SimpleTouchable.class, SimpleTouchable.class); 93 } 94 95 public static class Erroneous { 96 public Erroneous() { 97 throw new VerifyError ("test"); 98 } 99 } 100 101 protected ComponentAdapter prepINS_errorIsRethrown(MutablePicoContainer picoContainer) { 102 return new ConstructorInjectionComponentAdapter(Erroneous.class, Erroneous.class); 103 } 104 105 public static class RuntimeThrowing { 106 public RuntimeThrowing() { 107 throw new RuntimeException ("test"); 108 } 109 } 110 111 protected ComponentAdapter prepINS_runtimeExceptionIsRethrown(MutablePicoContainer picoContainer) { 112 return new ConstructorInjectionComponentAdapter(RuntimeThrowing.class, RuntimeThrowing.class); 113 } 114 115 public static class NormalExceptionThrowing { 116 public NormalExceptionThrowing() throws Exception { 117 throw new Exception ("test"); 118 } 119 } 120 121 protected ComponentAdapter prepINS_normalExceptionIsRethrownInsidePicoInvocationTargetInitializationException( 122 MutablePicoContainer picoContainer) { 123 return new ConstructorInjectionComponentAdapter(NormalExceptionThrowing.class, NormalExceptionThrowing.class); 124 } 125 126 protected ComponentAdapter prepRES_dependenciesAreResolved(MutablePicoContainer picoContainer) { 127 picoContainer.registerComponentImplementation(SimpleTouchable.class); 128 return new ConstructorInjectionComponentAdapter(DependsOnTouchable.class, DependsOnTouchable.class); 129 } 130 131 public static class C1 { 132 public C1(C2 c2) { 133 fail("verification should not instantiate"); 134 } 135 } 136 137 public static class C2 { 138 public C2(C1 c1) { 139 fail("verification should not instantiate"); 140 } 141 } 142 143 protected ComponentAdapter prepRES_failingVerificationWithCyclicDependencyException(MutablePicoContainer picoContainer) { 144 final ComponentAdapter componentAdapter = new ConstructorInjectionComponentAdapter(C1.class, C1.class); 145 picoContainer.registerComponent(componentAdapter); 146 picoContainer.registerComponentImplementation(C2.class, C2.class); 147 return componentAdapter; 148 } 149 150 protected ComponentAdapter prepRES_failingInstantiationWithCyclicDependencyException(MutablePicoContainer picoContainer) { 151 final ComponentAdapter componentAdapter = new ConstructorInjectionComponentAdapter(C1.class, C1.class); 152 picoContainer.registerComponent(componentAdapter); 153 picoContainer.registerComponentImplementation(C2.class, C2.class); 154 return componentAdapter; 155 } 156 157 public void testNormalExceptionThrownInCtorIsRethrownInsideInvocationTargetExeption() { 158 DefaultPicoContainer picoContainer = new DefaultPicoContainer(); 159 picoContainer.registerComponentImplementation(NormalExceptionThrowing.class); 160 try { 161 picoContainer.getComponentInstance(NormalExceptionThrowing.class); 162 fail(); 163 } catch (PicoInvocationTargetInitializationException e) { 164 assertEquals("test", e.getCause().getMessage()); 165 } 166 } 167 168 public abstract class InstantiationExceptionThrowing { 169 public InstantiationExceptionThrowing() { 170 } 171 } 172 173 public void testInstantiationExceptionThrownInCtorIsRethrownInsideInvocationTargetExeption() { 174 DefaultPicoContainer picoContainer = new DefaultPicoContainer(); 175 try { 176 picoContainer.registerComponentImplementation(InstantiationExceptionThrowing.class); 177 picoContainer.getComponentInstance(InstantiationExceptionThrowing.class); 178 fail(); 179 } catch (NotConcreteRegistrationException e) { 180 } 181 } 182 183 public class IllegalAccessExceptionThrowing { 184 private IllegalAccessExceptionThrowing() { 185 } 186 } 187 188 public void XXXtestIllegalAccessExceptionThrownInCtorIsRethrownInsideInvocationTargetExeption() { 192 DefaultPicoContainer picoContainer = new DefaultPicoContainer(); 193 try { 194 picoContainer.registerComponentImplementation(IllegalAccessExceptionThrowing.class); 195 picoContainer.getComponentInstance(IllegalAccessExceptionThrowing.class); 196 fail(); 197 } catch (PicoInitializationException e) { 198 assertTrue(e.getCause().getMessage().indexOf(IllegalAccessExceptionThrowing.class.getName()) > 0); 199 } 200 } 201 202 public void testPicoInitializationExceptionThrownBecauseOfFilteredConstructors() { 203 DefaultPicoContainer picoContainer = new DefaultPicoContainer(); 204 try { 205 picoContainer.registerComponentImplementation(IllegalAccessExceptionThrowing.class); 206 picoContainer.getComponentInstance(IllegalAccessExceptionThrowing.class); 207 fail(); 208 } catch (PicoInitializationException e) { 209 assertTrue(e.getMessage().indexOf(IllegalAccessExceptionThrowing.class.getName()) > 0); 210 } 211 } 212 213 public void testRegisterAbstractShouldFail() throws PicoRegistrationException, PicoIntrospectionException { 214 MutablePicoContainer pico = new DefaultPicoContainer(); 215 216 try { 217 pico.registerComponentImplementation(Runnable .class); 218 fail("Shouldn't be allowed to register abstract classes or interfaces."); 219 } catch (NotConcreteRegistrationException e) { 220 assertEquals(Runnable .class, e.getComponentImplementation()); 221 assertTrue(e.getMessage().indexOf(Runnable .class.getName()) > 0); 222 } 223 } 224 225 private static class Private { 226 private Private() { 227 } 228 } 229 230 private static class NotYourBusiness { 231 private NotYourBusiness(Private aPrivate) { 232 assertNotNull(aPrivate); 233 } 234 } 235 236 public void testShouldBeAbleToInstantiateNonPublicClassesWithNonPublicConstructors() { 238 DefaultPicoContainer pico = new DefaultPicoContainer(new ConstructorInjectionComponentAdapterFactory(true)); 239 pico.registerComponentImplementation(Private.class); 240 pico.registerComponentImplementation(NotYourBusiness.class); 241 assertNotNull(pico.getComponentInstance(NotYourBusiness.class)); 242 } 243 244 static public class Component201 { 245 public Component201(final String s) { 246 } 247 248 protected Component201(final Integer i, final Boolean b) { 249 fail("Wrong constructor taken."); 250 } 251 } 252 253 public void testShouldNotConsiderNonPublicConstructors() { 255 DefaultPicoContainer pico = new DefaultPicoContainer(); 256 pico.registerComponentImplementation(Component201.class); 257 pico.registerComponentInstance(new Integer (2)); 258 pico.registerComponentInstance(new Boolean (true)); 259 pico.registerComponentInstance("Hello"); 260 assertNotNull(pico.getComponentInstance(Component201.class)); 261 } 262 263 public void testMonitoringHappensBeforeAndAfterInstantiation() throws NoSuchMethodException { 264 Mock monitor = mock(ComponentMonitor.class); 265 Constructor emptyHashMapCtor = HashMap .class.getConstructor(new Class [0]); 266 monitor.expects(once()).method("instantiating").with(eq(emptyHashMapCtor)); 267 Constraint durationIsGreaterThanOrEqualToZero = new Constraint() { 268 public boolean eval(Object o) { 269 Long duration = (Long )o; 270 return 0 <= duration.longValue(); 271 } 272 273 public StringBuffer describeTo(StringBuffer stringBuffer) { 274 return stringBuffer.append("The endTime wasn't after the startTime"); 275 } 276 }; 277 Constraint isAHashMapThatWozCreated = new Constraint() { 278 public boolean eval(Object o) { 279 return o instanceof HashMap ; 280 } 281 282 public StringBuffer describeTo(StringBuffer stringBuffer) { 283 return stringBuffer.append("Should have been a hashmap"); 284 } 285 }; 286 287 Constraint injectedIsEmptyArray = new Constraint() { 288 public boolean eval(Object o) { 289 Object [] injected = (Object [])o; 290 return 0 == injected.length; 291 } 292 293 public StringBuffer describeTo(StringBuffer stringBuffer) { 294 return stringBuffer.append("Should have had nothing injected into it"); 295 } 296 }; 297 298 monitor.expects(once()).method("instantiated").with(eq(emptyHashMapCtor), isAHashMapThatWozCreated, injectedIsEmptyArray, durationIsGreaterThanOrEqualToZero); 299 ConstructorInjectionComponentAdapter cica = new ConstructorInjectionComponentAdapter( 300 Map .class, HashMap .class, new Parameter[0], false, (ComponentMonitor)monitor.proxy()); 301 cica.getComponentInstance(null); 302 } 303 304 public void testMonitoringHappensBeforeAndOnFailOfImpossibleComponentsInstantiation() throws NoSuchMethodException { 305 Mock monitor = mock(ComponentMonitor.class); 306 Constructor barfingActionListenerCtor = BarfingActionListener.class.getConstructor(new Class [0]); 307 monitor.expects(once()).method("instantiating").with(eq(barfingActionListenerCtor)); 308 309 Constraint isITE = new Constraint() { 310 public boolean eval(Object o) { 311 Exception ex = (Exception )o; 312 return ex instanceof InvocationTargetException ; 313 } 314 315 public StringBuffer describeTo(StringBuffer stringBuffer) { 316 return stringBuffer.append("Should have been unable to instantiate"); 317 } 318 }; 319 320 monitor.expects(once()).method("instantiationFailed").with(eq(barfingActionListenerCtor), isITE); 321 ConstructorInjectionComponentAdapter cica = new ConstructorInjectionComponentAdapter( 322 ActionListener .class, BarfingActionListener.class, new Parameter[0], false, (ComponentMonitor)monitor.proxy()); 323 try { 324 cica.getComponentInstance(null); 325 fail("Should barf"); 326 } catch (RuntimeException e) { 327 assertEquals("Barf!", e.getMessage()); 328 } 329 } 330 331 private static class BarfingActionListener implements ActionListener { 332 public BarfingActionListener() { 333 throw new RuntimeException ("Barf!"); 334 } 335 336 public void actionPerformed(ActionEvent e) { 337 } 338 } 339 340 public void testCustomLifecycleCanBeInjected() throws NoSuchMethodException { 341 RecordingLifecycleStrategy strategy = new RecordingLifecycleStrategy(new StringBuffer ()); 342 ConstructorInjectionComponentAdapter cica = new ConstructorInjectionComponentAdapter( 343 NullLifecycle.class, NullLifecycle.class, new Parameter[0], false, 344 new DelegatingComponentMonitor(), strategy); 345 Touchable touchable = new SimpleTouchable(); 346 cica.start(touchable); 347 cica.stop(touchable); 348 cica.dispose(touchable); 349 assertEquals("<start<stop<dispose", strategy.recording()); 350 } 351 } 352 | Popular Tags |