1 10 package org.picocontainer.tck; 11 12 import java.io.ByteArrayInputStream ; 13 import java.io.ByteArrayOutputStream ; 14 import java.io.IOException ; 15 import java.io.ObjectInputStream ; 16 import java.io.ObjectOutputStream ; 17 import java.io.Serializable ; 18 import java.util.ArrayList ; 19 import java.util.Arrays ; 20 import java.util.Collection ; 21 import java.util.HashMap ; 22 import java.util.HashSet ; 23 import java.util.LinkedList ; 24 import java.util.List ; 25 import java.util.Map ; 26 import java.util.Set ; 27 28 import junit.framework.Assert; 29 30 import org.picocontainer.ComponentAdapter; 31 import org.picocontainer.Disposable; 32 import org.picocontainer.LifecycleManager; 33 import org.picocontainer.MutablePicoContainer; 34 import org.picocontainer.Parameter; 35 import org.picocontainer.PicoContainer; 36 import org.picocontainer.PicoException; 37 import org.picocontainer.PicoInitializationException; 38 import org.picocontainer.PicoIntrospectionException; 39 import org.picocontainer.PicoRegistrationException; 40 import org.picocontainer.PicoVerificationException; 41 import org.picocontainer.PicoVisitor; 42 import org.picocontainer.Startable; 43 import org.picocontainer.defaults.AbstractPicoVisitor; 44 import org.picocontainer.defaults.AmbiguousComponentResolutionException; 45 import org.picocontainer.defaults.AssignabilityRegistrationException; 46 import org.picocontainer.defaults.BasicComponentParameter; 47 import org.picocontainer.defaults.ConstantParameter; 48 import org.picocontainer.defaults.ConstructorInjectionComponentAdapter; 49 import org.picocontainer.defaults.CyclicDependencyException; 50 import org.picocontainer.defaults.DefaultPicoContainer; 51 import org.picocontainer.defaults.DuplicateComponentKeyRegistrationException; 52 import org.picocontainer.defaults.InstanceComponentAdapter; 53 import org.picocontainer.defaults.NotConcreteRegistrationException; 54 import org.picocontainer.defaults.UnsatisfiableDependenciesException; 55 import org.picocontainer.defaults.VerifyingVisitor; 56 import org.picocontainer.testmodel.DependsOnTouchable; 57 import org.picocontainer.testmodel.SimpleTouchable; 58 import org.picocontainer.testmodel.Touchable; 59 import org.picocontainer.testmodel.Washable; 60 import org.picocontainer.testmodel.WashableTouchable; 61 62 import org.jmock.MockObjectTestCase; 63 64 67 public abstract class AbstractPicoContainerTestCase extends MockObjectTestCase { 68 69 protected abstract MutablePicoContainer createPicoContainer(PicoContainer parent); 70 71 protected final MutablePicoContainer createPicoContainerWithDependsOnTouchableOnly() throws 72 PicoRegistrationException, PicoIntrospectionException { 73 MutablePicoContainer pico = createPicoContainer(null); 74 pico.registerComponentImplementation(DependsOnTouchable.class); 75 return pico; 76 77 } 78 79 protected final MutablePicoContainer createPicoContainerWithTouchableAndDependsOnTouchable() throws 80 PicoRegistrationException, PicoIntrospectionException { 81 MutablePicoContainer pico = createPicoContainerWithDependsOnTouchableOnly(); 82 pico.registerComponentImplementation(Touchable.class, SimpleTouchable.class); 83 return pico; 84 } 85 86 public void testBasicInstantiationAndContainment() throws PicoException, PicoRegistrationException { 87 PicoContainer pico = createPicoContainerWithTouchableAndDependsOnTouchable(); 88 assertTrue("Component should be instance of Touchable", Touchable.class.isAssignableFrom(pico.getComponentAdapterOfType(Touchable.class).getComponentImplementation())); 89 } 90 91 public void testRegisteredComponentsExistAndAreTheCorrectTypes() throws PicoException, PicoRegistrationException { 92 PicoContainer pico = createPicoContainerWithTouchableAndDependsOnTouchable(); 93 assertNotNull("Container should have Touchable component", 94 pico.getComponentAdapter(Touchable.class)); 95 assertNotNull("Container should have DependsOnTouchable component", 96 pico.getComponentAdapter(DependsOnTouchable.class)); 97 assertTrue("Component should be instance of Touchable", 98 pico.getComponentInstance(Touchable.class) instanceof Touchable); 99 assertTrue("Component should be instance of DependsOnTouchable", 100 pico.getComponentInstance(DependsOnTouchable.class) instanceof DependsOnTouchable); 101 assertNull("should not have non existent component", pico.getComponentAdapter(Map .class)); 102 } 103 104 public void testRegistersSingleInstance() throws PicoException, PicoInitializationException { 105 MutablePicoContainer pico = createPicoContainer(null); 106 StringBuffer sb = new StringBuffer (); 107 pico.registerComponentInstance(sb); 108 assertSame(sb, pico.getComponentInstance(StringBuffer .class)); 109 } 110 111 public void testContainerIsSerializable() throws PicoException, PicoInitializationException, 112 IOException , ClassNotFoundException { 113 114 getTouchableFromSerializedContainer(); 115 116 } 117 118 private Touchable getTouchableFromSerializedContainer() throws IOException , ClassNotFoundException { 119 MutablePicoContainer pico = createPicoContainerWithTouchableAndDependsOnTouchable(); 120 pico.registerComponentImplementation("list", ArrayList .class, new Parameter[]{new ConstantParameter(new Integer (10))}); 122 123 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 124 ObjectOutputStream oos = new ObjectOutputStream (baos); 125 126 oos.writeObject(pico); 127 ObjectInputStream ois = new ObjectInputStream (new ByteArrayInputStream (baos.toByteArray())); 128 129 pico = (MutablePicoContainer) ois.readObject(); 130 131 DependsOnTouchable dependsOnTouchable = (DependsOnTouchable) pico.getComponentInstance(DependsOnTouchable.class); 132 assertNotNull(dependsOnTouchable); 133 return (Touchable) pico.getComponentInstance(Touchable.class); 134 } 135 136 public void testSerializedContainerCanRetrieveImplementation() throws PicoException, PicoInitializationException, 137 IOException , ClassNotFoundException { 138 139 Touchable touchable = getTouchableFromSerializedContainer(); 140 141 SimpleTouchable simpleTouchable = (SimpleTouchable) touchable; 142 143 assertTrue(simpleTouchable.wasTouched); 144 } 145 146 147 public void testGettingComponentWithMissingDependencyFails() throws PicoException, PicoRegistrationException { 148 PicoContainer picoContainer = createPicoContainerWithDependsOnTouchableOnly(); 149 try { 150 picoContainer.getComponentInstance(DependsOnTouchable.class); 151 fail("should need a Touchable"); 152 } catch (UnsatisfiableDependenciesException e) { 153 assertSame(picoContainer.getComponentAdapterOfType(DependsOnTouchable.class).getComponentImplementation(), e.getUnsatisfiableComponentAdapter().getComponentImplementation()); 154 final Set unsatisfiableDependencies = e.getUnsatisfiableDependencies(); 155 assertEquals(1, unsatisfiableDependencies.size()); 156 157 List unsatisfied = (List ) unsatisfiableDependencies.iterator().next(); 159 assertEquals(1, unsatisfied.size()); 160 assertEquals(Touchable.class, unsatisfied.get(0)); 161 } 162 } 163 164 public void testDuplicateRegistration() throws Exception { 165 try { 166 MutablePicoContainer pico = createPicoContainer(null); 167 pico.registerComponentImplementation(Object .class); 168 pico.registerComponentImplementation(Object .class); 169 fail("Should have failed with duplicate registration"); 170 } catch (DuplicateComponentKeyRegistrationException e) { 171 assertTrue("Wrong key", e.getDuplicateKey() == Object .class); 172 } 173 } 174 175 public void testExternallyInstantiatedObjectsCanBeRegistgeredAndLookedUp() throws PicoException, PicoInitializationException { 176 MutablePicoContainer pico = createPicoContainer(null); 177 final HashMap map = new HashMap (); 178 pico.registerComponentInstance(Map .class, map); 179 assertSame(map, pico.getComponentInstance(Map .class)); 180 } 181 182 public void testAmbiguousResolution() throws PicoRegistrationException, PicoInitializationException { 183 MutablePicoContainer pico = createPicoContainer(null); 184 pico.registerComponentImplementation("ping", String .class); 185 pico.registerComponentInstance("pong", "pang"); 186 try { 187 pico.getComponentInstance(String .class); 188 } catch (AmbiguousComponentResolutionException e) { 189 assertTrue(e.getMessage().indexOf("java.lang.String") != -1); 190 } 191 } 192 193 public void testLookupWithUnregisteredKeyReturnsNull() throws PicoIntrospectionException, PicoInitializationException, AssignabilityRegistrationException, NotConcreteRegistrationException { 194 MutablePicoContainer pico = createPicoContainer(null); 195 assertNull(pico.getComponentInstance(String .class)); 196 } 197 198 public void testLookupWithUnregisteredTypeReturnsNull() throws PicoIntrospectionException, PicoInitializationException, AssignabilityRegistrationException, NotConcreteRegistrationException { 199 MutablePicoContainer pico = createPicoContainer(null); 200 assertNull(pico.getComponentInstanceOfType(String .class)); 201 } 202 203 public static class ListAdder { 204 public ListAdder(Collection list) { 205 list.add("something"); 206 } 207 } 208 209 public void testUnsatisfiableDependenciesExceptionGivesVerboseEnoughErrorMessage() { 210 MutablePicoContainer pico = createPicoContainer(null); 211 pico.registerComponentImplementation(ComponentD.class); 212 213 try { 214 pico.getComponentInstance(ComponentD.class); 215 } catch (UnsatisfiableDependenciesException e) { 216 Set unsatisfiableDependencies = e.getUnsatisfiableDependencies(); 217 assertEquals(1, unsatisfiableDependencies.size()); 218 219 List list = (List ) unsatisfiableDependencies.iterator().next(); 220 221 final List expectedList = new ArrayList (2); 222 expectedList.add(ComponentE.class); 223 expectedList.add(ComponentB.class); 224 225 assertEquals(expectedList, list); 226 } 227 } 228 229 public void testUnsatisfiableDependenciesExceptionGivesUnsatisfiedDependencyTypes() { 230 MutablePicoContainer pico = createPicoContainer(null); 231 pico.registerComponentImplementation(ComponentD.class); 233 234 try { 237 pico.getComponentInstance(ComponentD.class); 238 } catch (UnsatisfiableDependenciesException e) { 239 Set unsatisfiableDependencies = e.getUnsatisfiableDependencies(); 240 assertEquals(1, unsatisfiableDependencies.size()); 241 List list = (List ) unsatisfiableDependencies.iterator().next(); 242 final List expectedList = new ArrayList (2); 243 expectedList.add(ComponentE.class); 244 expectedList.add(ComponentB.class); 245 assertEquals(expectedList, list); 246 247 Class unsatisfiedDependencyType = e.getUnsatisfiedDependencyType(); 248 assertNotNull(unsatisfiedDependencyType); 249 assertEquals(ComponentE.class, unsatisfiedDependencyType); 250 } 251 252 pico.registerComponentImplementation(ComponentE.class); 255 try { 256 pico.getComponentInstance(ComponentD.class); 257 } catch (UnsatisfiableDependenciesException e) { 258 Set unsatisfiableDependencies = e.getUnsatisfiableDependencies(); 259 assertEquals(1, unsatisfiableDependencies.size()); 260 List list = (List ) unsatisfiableDependencies.iterator().next(); 261 final List expectedList = new ArrayList (2); 262 expectedList.add(ComponentE.class); 263 expectedList.add(ComponentB.class); 264 assertEquals(expectedList, list); 265 266 Class unsatisfiedDependencyType = e.getUnsatisfiedDependencyType(); 267 assertNotNull(unsatisfiedDependencyType); 268 assertEquals(ComponentB.class, unsatisfiedDependencyType); 269 } 270 } 271 272 public void testCyclicDependencyThrowsCyclicDependencyException() { 273 assertCyclicDependencyThrowsCyclicDependencyException(createPicoContainer(null)); 274 } 275 276 private static void assertCyclicDependencyThrowsCyclicDependencyException(MutablePicoContainer pico) { 277 pico.registerComponentImplementation(ComponentB.class); 278 pico.registerComponentImplementation(ComponentD.class); 279 pico.registerComponentImplementation(ComponentE.class); 280 281 try { 282 pico.getComponentInstance(ComponentD.class); 283 fail("CyclicDependencyException expected"); 284 } catch (CyclicDependencyException e) { 285 final List dependencies = Arrays.asList(new Class []{ComponentD.class, ComponentE.class, ComponentD.class}); 288 final List reportedDependencies = Arrays.asList(e.getDependencies()); 289 assertEquals(dependencies, reportedDependencies); 290 } catch (StackOverflowError e) { 291 fail(); 292 } 293 } 294 295 public void testCyclicDependencyThrowsCyclicDependencyExceptionWithParentContainer() { 296 MutablePicoContainer pico = createPicoContainer(createPicoContainer(null)); 297 assertCyclicDependencyThrowsCyclicDependencyException(pico); 298 } 299 300 public void testRemovalNonRegisteredComponentAdapterWorksAndReturnsNull() { 301 final MutablePicoContainer picoContainer = createPicoContainer(null); 302 assertNull(picoContainer.unregisterComponent("COMPONENT DOES NOT EXIST")); 303 } 304 305 308 public void testComponentAdapterRegistrationOrderIsMaintained() { 309 310 ConstructorInjectionComponentAdapter c1 = new ConstructorInjectionComponentAdapter("1", Object .class); 311 ConstructorInjectionComponentAdapter c2 = new ConstructorInjectionComponentAdapter("2", String .class); 312 313 MutablePicoContainer picoContainer = createPicoContainer(null); 314 picoContainer.registerComponent(c1); 315 picoContainer.registerComponent(c2); 316 assertEquals("registration order should be maintained", 317 Arrays.asList(new Object []{c1, c2}), picoContainer.getComponentAdapters()); 318 319 picoContainer.getComponentInstances(); assertFalse("instances should be created in same order as adapters are created", 321 picoContainer.getComponentInstances().get(0) instanceof String ); 322 assertTrue("instances should be created in same order as adapters are created", 323 picoContainer.getComponentInstances().get(1) instanceof String ); 324 325 MutablePicoContainer reversedPicoContainer = createPicoContainer(null); 326 reversedPicoContainer.registerComponent(c2); 327 reversedPicoContainer.registerComponent(c1); 328 assertEquals("registration order should be maintained", 329 Arrays.asList(new Object []{c2, c1}), reversedPicoContainer.getComponentAdapters()); 330 331 reversedPicoContainer.getComponentInstances(); assertTrue("instances should be created in same order as adapters are created", 333 reversedPicoContainer.getComponentInstances().get(0) instanceof String ); 334 assertFalse("instances should be created in same order as adapters are created", 335 reversedPicoContainer.getComponentInstances().get(1) instanceof String ); 336 } 337 338 public static class NeedsTouchable { 339 public Touchable touchable; 340 341 public NeedsTouchable(Touchable touchable) { 342 this.touchable = touchable; 343 } 344 } 345 346 public static class NeedsWashable { 347 public Washable washable; 348 349 public NeedsWashable(Washable washable) { 350 this.washable = washable; 351 } 352 } 353 354 public void testSameInstanceCanBeUsedAsDifferentTypeWhenCaching() { 355 MutablePicoContainer pico = createPicoContainer(null); 356 pico.registerComponentImplementation("wt", WashableTouchable.class); 357 pico.registerComponentImplementation("nw", NeedsWashable.class); 358 pico.registerComponentImplementation("nt", NeedsTouchable.class); 359 360 NeedsWashable nw = (NeedsWashable) pico.getComponentInstance("nw"); 361 NeedsTouchable nt = (NeedsTouchable) pico.getComponentInstance("nt"); 362 assertSame(nw.washable, nt.touchable); 363 } 364 365 public void testRegisterComponentWithObjectBadType() throws PicoIntrospectionException { 366 MutablePicoContainer pico = createPicoContainer(null); 367 368 try { 369 pico.registerComponentInstance(Serializable .class, new Object ()); 370 fail("Shouldn't be able to register an Object.class as Serializable because it is not, " + 371 "it does not implement it, Object.class does not implement much."); 372 } catch (AssignabilityRegistrationException e) { 373 } 374 375 } 376 377 public static class JMSService { 378 public final String serverid; 379 public final String path; 380 381 public JMSService(String serverid, String path) { 382 this.serverid = serverid; 383 this.path = path; 384 } 385 } 386 387 public void testPico52() { 389 MutablePicoContainer pico = createPicoContainer(null); 390 391 pico.registerComponentImplementation("foo", JMSService.class, new Parameter[]{ 392 new ConstantParameter("0"), 393 new ConstantParameter("something"), 394 }); 395 JMSService jms = (JMSService) pico.getComponentInstance("foo"); 396 assertEquals("0", jms.serverid); 397 assertEquals("something", jms.path); 398 } 399 400 public static class ComponentA { 401 public ComponentA(ComponentB b, ComponentC c) { 402 Assert.assertNotNull(b); 403 Assert.assertNotNull(c); 404 } 405 } 406 407 public static class ComponentB { 408 } 409 410 public static class ComponentC { 411 } 412 413 public static class ComponentD { 414 public ComponentD(ComponentE e, ComponentB b) { 415 Assert.assertNotNull(e); 416 Assert.assertNotNull(b); 417 } 418 } 419 420 public static class ComponentE { 421 public ComponentE(ComponentD d) { 422 Assert.assertNotNull(d); 423 } 424 } 425 426 public static class ComponentF { 427 public ComponentF(ComponentA a) { 428 Assert.assertNotNull(a); 429 } 430 } 431 432 public void testAggregatedVerificationException() { 433 MutablePicoContainer pico = createPicoContainer(null); 434 pico.registerComponentImplementation(ComponentA.class); 435 pico.registerComponentImplementation(ComponentE.class); 436 try { 437 new VerifyingVisitor().traverse(pico); 438 fail("we expect a PicoVerificationException"); 439 } catch (PicoVerificationException e) { 440 List nested = e.getNestedExceptions(); 441 assertEquals(2, nested.size()); 442 assertTrue(-1 != e.getMessage().indexOf(ComponentA.class.getName())); 443 assertTrue(-1 != e.getMessage().indexOf(ComponentE.class.getName())); 444 } 445 } 446 447 449 456 public static class ContainerDependency { 457 public ContainerDependency(PicoContainer container) { 458 assertNotNull(container); 459 } 460 } 461 462 466 473 public void testShouldReturnNullWhenUnregistereingUnmanagedComponent() { 474 final MutablePicoContainer pico = createPicoContainer(null); 475 assertNull(pico.unregisterComponentByInstance("yo")); 476 } 477 478 public void testShouldReturnNullForComponentAdapterOfUnregisteredType() { 479 final MutablePicoContainer pico = createPicoContainer(null); 480 assertNull(pico.getComponentInstanceOfType(List .class)); 481 } 482 483 public void testShouldReturnNonMutableParent() { 484 DefaultPicoContainer parent = new DefaultPicoContainer(); 485 final MutablePicoContainer picoContainer = createPicoContainer(parent); 486 assertNotSame(parent, picoContainer.getParent()); 487 assertFalse(picoContainer.getParent() instanceof MutablePicoContainer); 488 } 489 490 class Foo implements Startable, Disposable { 491 public boolean started; 492 public boolean stopped; 493 public boolean disposed; 494 495 public void start() { 496 started = true; 497 } 498 499 public void stop() { 500 stopped = true; 501 } 502 503 public void dispose() { 504 disposed = true; 505 } 506 507 } 508 509 public void testContainerCascadesDefaultLifecycle() { 510 final MutablePicoContainer picoContainer = createPicoContainer(null); 511 Foo foo = new Foo(); 512 picoContainer.registerComponentInstance(foo); 513 picoContainer.start(); 514 assertEquals(true, foo.started); 515 picoContainer.stop(); 516 assertEquals(true, foo.stopped); 517 picoContainer.dispose(); 518 assertEquals(true, foo.disposed); 519 } 520 521 public void testComponentInstancesFromParentsAreNotDirectlyAccessible2() { 522 final MutablePicoContainer a = createPicoContainer(null); 523 final MutablePicoContainer b = createPicoContainer(a); 524 final MutablePicoContainer c = createPicoContainer(b); 525 526 Object ao = new Object (); 527 Object bo = new Object (); 528 Object co = new Object (); 529 530 a.registerComponentInstance("a", ao); 531 b.registerComponentInstance("b", bo); 532 c.registerComponentInstance("c", co); 533 534 assertEquals(1, a.getComponentInstances().size()); 535 assertEquals(1, b.getComponentInstances().size()); 536 assertEquals(1, c.getComponentInstances().size()); 537 } 538 539 public void testStartStopAndDisposeCascadedtoChildren() { 540 final MutablePicoContainer parent = createPicoContainer(null); 541 parent.registerComponentInstance(new StringBuffer ()); 542 final MutablePicoContainer child = createPicoContainer(parent); 543 parent.addChildContainer(child); 544 child.registerComponentImplementation(LifeCycleMonitoring.class); 545 parent.start(); 546 try { 547 child.start(); 548 fail("IllegalStateException expected"); 549 } catch (IllegalStateException e) { 550 assertEquals("child already started", "Already started", e.getMessage()); 551 } 552 parent.stop(); 553 try { 554 child.stop(); 555 fail("IllegalStateException expected"); 556 } catch (IllegalStateException e) { 557 assertEquals("child not started", "Not started", e.getMessage()); 558 } 559 parent.dispose(); 560 try { 561 child.dispose(); 562 fail("IllegalStateException expected"); 563 } catch (IllegalStateException e) { 564 assertEquals("child already disposed", "Already disposed", e.getMessage()); 565 } 566 567 } 568 569 public void testMakingOfChildContainer() { 570 final MutablePicoContainer parent = createPicoContainer(null); 571 MutablePicoContainer child = parent.makeChildContainer(); 572 assertNotNull(child); 573 } 574 575 public void testMakingOfChildContainerPercolatesLifecycleManager() { 576 final MutablePicoContainer parent = createPicoContainer(null); 577 parent.registerComponentImplementation("one", TestLifecycleComponent.class); 578 MutablePicoContainer child = parent.makeChildContainer(); 579 assertNotNull(child); 580 child.registerComponentImplementation("two", TestLifecycleComponent.class); 581 parent.start(); 582 try { 583 child.start(); 584 } catch (IllegalStateException e) { 585 assertEquals("child already started", "Already started", e.getMessage()); 586 } 587 } 592 593 public static class TestLifecycleManager implements LifecycleManager { 594 public ArrayList started = new ArrayList (); 595 public void start(PicoContainer node) { 596 started.add(node); 597 } 598 599 public void stop(PicoContainer node) { 600 } 601 602 public void dispose(PicoContainer node) { 603 } 604 605 public boolean hasLifecycle() { 606 return true; 607 } 608 } 609 610 public static class TestLifecycleComponent implements Startable { 611 public boolean started; 612 public void start() { 613 started = true; 614 } 615 public void stop() { 616 } 617 } 618 619 public void testStartStopAndDisposeNotCascadedtoRemovedChildren() { 620 final MutablePicoContainer parent = createPicoContainer(null); 621 parent.registerComponentInstance(new StringBuffer ()); 622 StringBuffer sb = (StringBuffer ) parent.getComponentInstancesOfType(StringBuffer .class).get(0); 623 624 final MutablePicoContainer child = createPicoContainer(parent); 625 assertTrue(parent.addChildContainer(child)); 626 child.registerComponentImplementation(LifeCycleMonitoring.class); 627 assertTrue(parent.removeChildContainer(child)); 628 parent.start(); 629 assertTrue(sb.toString().indexOf("-started") == -1); 630 parent.stop(); 631 assertTrue(sb.toString().indexOf("-stopped") == -1); 632 parent.dispose(); 633 assertTrue(sb.toString().indexOf("-disposed") == -1); 634 } 635 636 public void testShouldCascadeStartStopAndDisposeToChild() { 637 638 StringBuffer sb = new StringBuffer (); 639 final MutablePicoContainer parent = createPicoContainer(null); 640 parent.registerComponentInstance(sb); 641 parent.registerComponentImplementation(Map .class, HashMap .class); 642 643 final MutablePicoContainer child = parent.makeChildContainer(); 644 child.registerComponentImplementation(LifeCycleMonitoring.class); 645 646 Map map = (Map ) parent.getComponentInstance(Map .class); 647 assertNotNull(map); 648 parent.start(); 649 try { 650 child.start(); 651 fail("IllegalStateException expected"); 652 } catch (IllegalStateException e) { 653 assertEquals("child already started", "Already started", e.getMessage()); 654 } 655 parent.stop(); 656 try { 657 child.stop(); 658 fail("IllegalStateException expected"); 659 } catch (IllegalStateException e) { 660 assertEquals("child not started", "Not started", e.getMessage()); 661 } 662 parent.dispose(); 663 try { 664 child.dispose(); 665 fail("IllegalStateException expected"); 666 } catch (IllegalStateException e) { 667 assertEquals("child already disposed", "Already disposed", e.getMessage()); 668 } 669 } 670 671 public static class LifeCycleMonitoring implements Startable, Disposable { 672 StringBuffer sb; 673 674 public LifeCycleMonitoring(StringBuffer sb) { 675 this.sb = sb; 676 sb.append("-instantiated"); 677 } 678 679 public void start() { 680 sb.append("-started"); 681 } 682 683 public void stop() { 684 sb.append("-stopped"); 685 } 686 687 public void dispose() { 688 sb.append("-disposed"); 689 } 690 } 691 692 public static class RecordingStrategyVisitor extends AbstractPicoVisitor { 693 694 private final List list; 695 696 public RecordingStrategyVisitor(List list) { 697 this.list = list; 698 } 699 700 public void visitContainer(PicoContainer pico) { 701 list.add(pico); 702 } 703 704 public void visitComponentAdapter(ComponentAdapter componentAdapter) { 705 list.add(componentAdapter); 706 } 707 708 public void visitParameter(Parameter parameter) { 709 list.add(parameter); 710 } 711 712 } 713 714 public void testAcceptImplementsBreadthFirstStrategy() { 715 final MutablePicoContainer parent = createPicoContainer(null); 716 final MutablePicoContainer child = parent.makeChildContainer(); 717 ComponentAdapter hashMapAdapter = parent.registerComponent(new ConstructorInjectionComponentAdapter(HashMap .class, HashMap .class)); 718 ComponentAdapter hashSetAdapter = parent.registerComponent(new ConstructorInjectionComponentAdapter(HashSet .class, HashSet .class)); 719 ComponentAdapter stringAdapter = parent.registerComponent(new InstanceComponentAdapter(String .class, "foo")); 720 ComponentAdapter arrayListAdapter = child.registerComponent(new ConstructorInjectionComponentAdapter(ArrayList .class, ArrayList .class)); 721 Parameter componentParameter = BasicComponentParameter.BASIC_DEFAULT; 722 Parameter throwableParameter = new ConstantParameter(new Throwable ("bar")); 723 ComponentAdapter exceptionAdapter = child.registerComponent(new ConstructorInjectionComponentAdapter(Exception .class, Exception .class, new Parameter[]{ 724 componentParameter, 725 throwableParameter 726 })); 727 728 List expectedList = Arrays.asList(new Object []{ 729 parent, 730 hashMapAdapter, 731 hashSetAdapter, 732 stringAdapter, 733 child, 734 arrayListAdapter, 735 exceptionAdapter, 736 componentParameter, 737 throwableParameter 738 }); 739 List visitedList = new LinkedList (); 740 PicoVisitor visitor = new RecordingStrategyVisitor(visitedList); 741 visitor.traverse(parent); 742 assertEquals(expectedList, visitedList); 743 } 744 745 public void testAmbiguousDependencies() throws PicoRegistrationException, PicoInitializationException { 746 747 MutablePicoContainer pico = this.createPicoContainer(null); 748 749 pico.registerComponentImplementation(SimpleTouchable.class); 751 pico.registerComponentImplementation(DerivedTouchable.class); 752 753 pico.registerComponentImplementation(DependsOnTouchable.class); 755 756 try { 757 pico.getComponentInstance(DependsOnTouchable.class); 758 fail("DependsOnTouchable should have been confused about the two Touchables"); 759 } catch (AmbiguousComponentResolutionException e) { 760 List componentImplementations = Arrays.asList(e.getAmbiguousComponentKeys()); 761 assertTrue(componentImplementations.contains(DerivedTouchable.class)); 762 assertTrue(componentImplementations.contains(SimpleTouchable.class)); 763 764 assertTrue(e.getMessage().indexOf(DerivedTouchable.class.getName()) != -1); 765 } 766 } 767 768 769 public static class DerivedTouchable extends SimpleTouchable { 770 public DerivedTouchable() { 771 } 772 } 773 774 } 775 | Popular Tags |