[picocontainer-dev] bug on pico start

"Putrycz, Erik" <[email protected]>
Newsgroups gmane.comp.java.picocontainer.devel
Message-ID <[email protected]>
Attached is a patch and a testcase for a bug on DPC.start. If you even
list the instances inside a startable component, pico throws a
concurrentmodification something. 

 

Erik Putrycz, Ph.D - Research Associate / [email protected]
<mailto:[email protected]>  / (613) 990 0681

Institute for Information Technology - Software Engineering Group

National Research Council, Canada - Building M-50, 1200 Montreal Road

Ottawa, Ontario, CANADA K1A 0R6

---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email
pico2.patch (application/octet-stream, 43.3 KB)
Index: container/src/java/org/picocontainer/DefaultPicoContainer.java
===================================================================
--- container/src/java/org/picocontainer/DefaultPicoContainer.java	(revision 3775)
+++ container/src/java/org/picocontainer/DefaultPicoContainer.java	(working copy)
@@ -711,7 +711,9 @@
         adapters = orderedComponentAdapters;
         // clear list of started CAs
         startedComponentAdapters.clear();
-        for (final ComponentAdapter adapter : adapters) {
+        // clone the adapters
+        Collection<ComponentAdapter<?>> adaptersClone = new ArrayList<ComponentAdapter<?>>(adapters); 
+        for (final ComponentAdapter adapter : adaptersClone) {
             if (adapter instanceof Behavior) {
                 Behavior manager = (Behavior)adapter;
                 manager.start(DefaultPicoContainer.this);
Index: container/src/test/org/picocontainer/DefaultPicoContainerTestCase.java
===================================================================
--- container/src/test/org/picocontainer/DefaultPicoContainerTestCase.java	(revision 3775)
+++ container/src/test/org/picocontainer/DefaultPicoContainerTestCase.java	(working copy)
@@ -53,550 +53,632 @@
  * @author Mauro Talevi
  * @version $Revision$
  */
-public final class DefaultPicoContainerTestCase extends AbstractPicoContainerTestCase {
-    protected MutablePicoContainer createPicoContainer(PicoContainer parent) {
-        return new DefaultPicoContainer(parent);
-    }
+public final class DefaultPicoContainerTestCase extends
+		AbstractPicoContainerTestCase {
+	protected MutablePicoContainer createPicoContainer(PicoContainer parent) {
+		return new DefaultPicoContainer(parent);
+	}
+
+	protected Properties[] getProperties() {
+		return new Properties[0];
+	}
+
+	public void testInstantiationWithNullComponentAdapterFactory() {
+		try {
+			new DefaultPicoContainer((ComponentFactory) null, null);
+			fail("NPE expected");
+		} catch (NullPointerException e) {
+			// expected
+		}
+	}
+
+	public void testUpDownDependenciesCannotBeFollowed() {
+		MutablePicoContainer parent = createPicoContainer(null);
+		MutablePicoContainer child = createPicoContainer(parent);
+
+		// ComponentF -> ComponentA -> ComponentB+C
+		child.addComponent(ComponentF.class);
+		parent.addComponent(ComponentA.class);
+		child.addComponent(ComponentB.class);
+		child.addComponent(ComponentC.class);
 
-    protected Properties[] getProperties() {
-        return new Properties[0];
-    }
+		try {
+			child.getComponent(ComponentF.class);
+			fail("Thrown "
+					+ AbstractInjector.UnsatisfiableDependenciesException.class
+							.getName() + " expected");
+		} catch (final AbstractInjector.UnsatisfiableDependenciesException e) {
+			assertEquals(ComponentB.class, e.getUnsatisfiedDependencyType());
+		}
+	}
 
-    public void testInstantiationWithNullComponentAdapterFactory(){
-        try {
-            new DefaultPicoContainer((ComponentFactory)null, null);
-            fail("NPE expected");
-        } catch (NullPointerException e) {
-            // expected
-        }
-    }
-    public void testUpDownDependenciesCannotBeFollowed() {
-        MutablePicoContainer parent = createPicoContainer(null);
-        MutablePicoContainer child = createPicoContainer(parent);
+	public void testComponentsCanBeRemovedByInstance() {
+		MutablePicoContainer pico = createPicoContainer(null);
+		pico.addComponent(HashMap.class);
+		pico.addComponent(ArrayList.class);
+		List list = pico.getComponent(List.class);
+		pico.removeComponentByInstance(list);
+		assertEquals(1, pico.getComponentAdapters().size());
+		assertEquals(1, pico.getComponents().size());
+		assertEquals(HashMap.class, pico.getComponent(Serializable.class)
+				.getClass());
+	}
 
-        // ComponentF -> ComponentA -> ComponentB+C
-        child.addComponent(ComponentF.class);
-        parent.addComponent(ComponentA.class);
-        child.addComponent(ComponentB.class);
-        child.addComponent(ComponentC.class);
+	public void testComponentInstancesListIsReturnedForNullType() {
+		MutablePicoContainer pico = createPicoContainer(null);
+		List componentInstances = pico.getComponents(null);
+		assertNotNull(componentInstances);
+		assertEquals(0, componentInstances.size());
+	}
 
-        try {
-            child.getComponent(ComponentF.class);
-            fail("Thrown " + AbstractInjector.UnsatisfiableDependenciesException.class.getName() + " expected");
-        } catch (final AbstractInjector.UnsatisfiableDependenciesException e) {
-            assertEquals(ComponentB.class, e.getUnsatisfiedDependencyType());
-        }
-    }
+	public void testComponentsWithCommonSupertypeWhichIsAConstructorArgumentCanBeLookedUpByConcreteType() {
+		MutablePicoContainer pico = createPicoContainer(null);
+		pico.addComponent(LinkedList.class, LinkedList.class, Parameter.ZERO);
+		pico.addComponent(ArrayList.class);
+		assertEquals(ArrayList.class, pico
+				.getComponent((Class) ArrayList.class).getClass());
+	}
 
+	/*
+	 * When pico tries to resolve DecoratedTouchable it find as dependency
+	 * itself and SimpleTouchable. Problem is basically the same as above. Pico
+	 * should not consider self as solution.
+	 * 
+	 * JS fixed it ( PICO-222 ) KP
+	 */
+	public void testUnambiguouSelfDependency() {
+		MutablePicoContainer pico = createPicoContainer(null);
+		pico.addComponent(SimpleTouchable.class);
+		pico.addComponent(DecoratedTouchable.class);
+		Touchable t = (Touchable) pico
+				.getComponent((Object) DecoratedTouchable.class);
+		assertNotNull(t);
+	}
 
+	public void testPicoUsedInBuilderStyle() {
+		MutablePicoContainer pico = createPicoContainer(null);
+		Touchable t = pico.change(Characteristics.CACHE).addComponent(
+				SimpleTouchable.class).addComponent(DecoratedTouchable.class)
+				.getComponent(DecoratedTouchable.class);
+		SimpleTouchable t2 = pico.getComponent(SimpleTouchable.class);
+		assertNotNull(t);
+		assertNotNull(t2);
+		t.touch();
+		assertTrue(t2.wasTouched);
+	}
 
-    public void testComponentsCanBeRemovedByInstance() {
-        MutablePicoContainer pico = createPicoContainer(null);
-        pico.addComponent(HashMap.class);
-        pico.addComponent(ArrayList.class);
-        List list = pico.getComponent(List.class);
-        pico.removeComponentByInstance(list);
-        assertEquals(1, pico.getComponentAdapters().size());
-        assertEquals(1, pico.getComponents().size());
-        assertEquals(HashMap.class, pico.getComponent(Serializable.class).getClass());
-    }
+	public static class Thingie {
+		public Thingie(List c) {
+			assertNotNull(c);
+		}
+	}
 
-    public void testComponentInstancesListIsReturnedForNullType(){
-        MutablePicoContainer pico = createPicoContainer(null);
-        List componentInstances = pico.getComponents(null);
-        assertNotNull(componentInstances);
-        assertEquals(0, componentInstances.size());
-    }
-    
-    public void testComponentsWithCommonSupertypeWhichIsAConstructorArgumentCanBeLookedUpByConcreteType() {
-        MutablePicoContainer pico = createPicoContainer(null);
-        pico.addComponent(LinkedList.class, LinkedList.class, Parameter.ZERO);
-        pico.addComponent(ArrayList.class);
-        assertEquals(ArrayList.class, pico.getComponent((Class) ArrayList.class).getClass());
-    }
+	public void testThangCanBeInstantiatedWithArrayList() {
+		MutablePicoContainer pico = new DefaultPicoContainer();
+		pico.addComponent(Thingie.class);
+		pico.addComponent(ArrayList.class);
+		assertNotNull(pico.getComponent(Thingie.class));
+	}
 
-    /*
-     When pico tries to resolve DecoratedTouchable it find as dependency itself and SimpleTouchable.
-     Problem is basically the same as above. Pico should not consider self as solution.
-     
-     JS
-     fixed it ( PICO-222 )
-     KP
-     */
-    public void testUnambiguouSelfDependency() {
-        MutablePicoContainer pico = createPicoContainer(null);
-        pico.addComponent(SimpleTouchable.class);
-        pico.addComponent(DecoratedTouchable.class);
-        Touchable t = (Touchable) pico.getComponent((Object) DecoratedTouchable.class);
-        assertNotNull(t);
-    }
+	public void testGetComponentAdaptersOfTypeNullReturnsEmptyList() {
+		DefaultPicoContainer pico = new DefaultPicoContainer();
+		List adapters = pico.getComponentAdapters(null);
+		assertNotNull(adapters);
+		assertEquals(0, adapters.size());
+	}
 
+	public static class Service {
+	}
 
-    public void testPicoUsedInBuilderStyle() {
-        MutablePicoContainer pico = createPicoContainer(null);
-        Touchable t = pico.change(Characteristics.CACHE).addComponent(SimpleTouchable.class).addComponent(DecoratedTouchable.class).getComponent(DecoratedTouchable.class);
-        SimpleTouchable t2 = pico.getComponent(SimpleTouchable.class);
-        assertNotNull(t);
-        assertNotNull(t2);
-        t.touch();
-        assertTrue(t2.wasTouched);
-    }
+	public static final class TransientComponent {
+		private final Service service;
 
-    public static class Thingie {
-        public Thingie(List c) {
-            assertNotNull(c);
-        }
-    }
+		public TransientComponent(Service service) {
+			this.service = service;
+		}
+	}
 
-    public void testThangCanBeInstantiatedWithArrayList() {
-        MutablePicoContainer pico = new DefaultPicoContainer();
-        pico.addComponent(Thingie.class);
-        pico.addComponent(ArrayList.class);
-        assertNotNull(pico.getComponent(Thingie.class));
-    }
+	public void testDefaultPicoContainerReturnsNewInstanceForEachCallWhenUsingTransientComponentAdapter() {
 
-    public void testGetComponentAdaptersOfTypeNullReturnsEmptyList() {
-        DefaultPicoContainer pico = new DefaultPicoContainer();
-        List adapters = pico.getComponentAdapters(null);
-        assertNotNull(adapters);
-        assertEquals(0, adapters.size());
-    }
-    
+		DefaultPicoContainer picoContainer = new DefaultPicoContainer(
+				new Caching().wrap(new ConstructorInjectionFactory()));
 
-    public static class Service {
-    }
+		picoContainer.addComponent(Service.class);
+		picoContainer.as(Characteristics.NO_CACHE)
+				.addAdapter(
+						new ConstructorInjector(TransientComponent.class,
+								TransientComponent.class, null,
+								new NullComponentMonitor(),
+								new NullLifecycleStrategy()));
+		TransientComponent c1 = picoContainer
+				.getComponent(TransientComponent.class);
+		TransientComponent c2 = picoContainer
+				.getComponent(TransientComponent.class);
+		assertNotSame(c1, c2);
+		assertSame(c1.service, c2.service);
+	}
 
-    public static final class TransientComponent {
-        private final Service service;
+	public static class DependsOnCollection {
+		public DependsOnCollection(Collection c) {
+		}
+	}
 
-        public TransientComponent(Service service) {
-            this.service = service;
-        }
-    }
+	public void testShouldProvideInfoAboutDependingWhenAmbiguityHappens() {
+		MutablePicoContainer pico = this.createPicoContainer(null);
+		pico.addComponent(new ArrayList());
+		pico.addComponent(new LinkedList());
+		pico.addComponent(DependsOnCollection.class);
+		try {
+			pico.getComponent(DependsOnCollection.class);
+			fail();
+		} catch (AbstractInjector.AmbiguousComponentResolutionException expected) {
+			String doc = DependsOnCollection.class.getName();
+			assertEquals(
+					"class "
+							+ doc
+							+ " needs a 'java.util.Collection' injected, but there are too many choices to inject. These:[class java.util.ArrayList, class java.util.LinkedList], refer http://picocontainer.org/ambiguous-injectable-help.html",
+					expected.getMessage());
+		}
+	}
 
-    public void testDefaultPicoContainerReturnsNewInstanceForEachCallWhenUsingTransientComponentAdapter() {
+	public void testInstantiationWithMonitorAndParent() {
+		StringWriter writer = new StringWriter();
+		ComponentMonitor monitor = new WriterComponentMonitor(writer);
+		DefaultPicoContainer parent = new DefaultPicoContainer();
+		DefaultPicoContainer child = new DefaultPicoContainer(monitor, parent);
+		parent.addComponent("st", SimpleTouchable.class);
+		child.addComponent("dot", DependsOnTouchable.class);
+		DependsOnTouchable dot = (DependsOnTouchable) child.getComponent("dot");
+		assertNotNull(dot);
+		assertTrue("writer not empty", writer.toString().length() > 0);
+	}
 
+	public void testStartCapturedByMonitor() {
+		final StringBuffer sb = new StringBuffer();
+		DefaultPicoContainer dpc = new DefaultPicoContainer(
+				new NullComponentMonitor() {
+					public void invoking(PicoContainer container,
+							ComponentAdapter componentAdapter, Member member,
+							Object instance) {
+						sb.append(member.toString());
+					}
+				});
+		dpc.as(Characteristics.CACHE).addComponent(DefaultPicoContainer.class);
+		dpc.start();
+		assertEquals(
+				"ComponentMonitor should have been notified that the component had been started",
+				"public abstract void org.picocontainer.Startable.start()", sb
+						.toString());
+	}
 
+	public static class StartableClazz implements Startable {
+		private MutablePicoContainer _pico;
 
-        DefaultPicoContainer picoContainer = new DefaultPicoContainer(new Caching().wrap(new ConstructorInjectionFactory()));
+		public void start() {
+			List<SimpleTouchable> cps = _pico
+					.getComponents(SimpleTouchable.class);
+			assertNotNull(cps);
+		}
 
-        picoContainer.addComponent(Service.class);
-        picoContainer.as(Characteristics.NO_CACHE).addAdapter(new ConstructorInjector(TransientComponent.class, TransientComponent.class, null, new NullComponentMonitor(), new NullLifecycleStrategy()));
-        TransientComponent c1 = picoContainer.getComponent(TransientComponent.class);
-        TransientComponent c2 = picoContainer.getComponent(TransientComponent.class);
-        assertNotSame(c1, c2);
-        assertSame(c1.service, c2.service);
-    }
+		public void stop() {
+		}
 
-    public static class DependsOnCollection {
-        public DependsOnCollection(Collection c) {
-        }
-    }
+	}
 
-    public void testShouldProvideInfoAboutDependingWhenAmbiguityHappens() {
-        MutablePicoContainer pico = this.createPicoContainer(null);
-        pico.addComponent(new ArrayList());
-        pico.addComponent(new LinkedList());
-        pico.addComponent(DependsOnCollection.class);
-        try {
-            pico.getComponent(DependsOnCollection.class);
-            fail();
-        } catch (AbstractInjector.AmbiguousComponentResolutionException expected) {
-            String doc = DependsOnCollection.class.getName();
-            assertEquals("class " + doc + " needs a 'java.util.Collection' injected, but there are too many choices to inject. These:[class java.util.ArrayList, class java.util.LinkedList], refer http://picocontainer.org/ambiguous-injectable-help.html", expected.getMessage());
-        }
-    }
+	public void testListComponentsOnStart() {
+		DefaultPicoContainer dpc = new DefaultPicoContainer();
+		dpc.addComponent(SimpleTouchable.class);
+		StartableClazz cl = new StartableClazz();
+		cl._pico = dpc;
+		dpc.addComponent(cl);
+		dpc.start();
+	}
 
-    public void testInstantiationWithMonitorAndParent() {
-        StringWriter writer = new StringWriter();
-        ComponentMonitor monitor = new WriterComponentMonitor(writer);
-        DefaultPicoContainer parent = new DefaultPicoContainer();
-        DefaultPicoContainer child = new DefaultPicoContainer(monitor, parent);
-        parent.addComponent("st", SimpleTouchable.class);
-        child.addComponent("dot", DependsOnTouchable.class);
-        DependsOnTouchable dot = (DependsOnTouchable) child.getComponent("dot");
-        assertNotNull(dot);
-        assertTrue("writer not empty", writer.toString().length() > 0);
-    }
-    
-    public void testStartCapturedByMonitor() {
-        final StringBuffer sb = new StringBuffer();
-        DefaultPicoContainer dpc = new DefaultPicoContainer(new NullComponentMonitor() {
-            public void invoking(PicoContainer container,
-                                 ComponentAdapter componentAdapter,
-                                 Member member,
-                                 Object instance) {
-                sb.append(member.toString());
-            }
-        });
-        dpc.as(Characteristics.CACHE).addComponent(DefaultPicoContainer.class);
-        dpc.start();
-        assertEquals("ComponentMonitor should have been notified that the component had been started",
-                "public abstract void org.picocontainer.Startable.start()", sb.toString());
-    }
+	public void testCanChangeMonitor() {
+		StringWriter writer1 = new StringWriter();
+		ComponentMonitor monitor1 = new WriterComponentMonitor(writer1);
+		DefaultPicoContainer pico = new DefaultPicoContainer(monitor1);
+		pico.addComponent("t1", SimpleTouchable.class);
+		pico.addComponent("t3", SimpleTouchable.class);
+		Touchable t1 = (Touchable) pico.getComponent("t1");
+		assertNotNull(t1);
+		final String s = writer1.toString();
+		assertTrue("writer not empty", s.length() > 0);
+		StringWriter writer2 = new StringWriter();
+		ComponentMonitor monitor2 = new WriterComponentMonitor(writer2);
+		pico.changeMonitor(monitor2);
+		pico.addComponent("t2", SimpleTouchable.class);
+		Touchable t2 = (Touchable) pico.getComponent("t2");
+		assertNotNull(t2);
+		final String s2 = writer2.toString();
+		assertTrue("writer not empty", s2.length() > 0);
+		assertTrue("writers of same length",
+				writer1.toString().length() == writer2.toString().length());
+		Touchable t3 = (Touchable) pico.getComponent("t3");
+		assertNotNull(t3);
+		assertTrue("old writer was used", writer1.toString().length() < writer2
+				.toString().length());
+	}
 
-    public void testCanChangeMonitor() {
-        StringWriter writer1 = new StringWriter();
-        ComponentMonitor monitor1 = new WriterComponentMonitor(writer1);
-        DefaultPicoContainer pico = new DefaultPicoContainer(monitor1);
-        pico.addComponent("t1", SimpleTouchable.class);
-        pico.addComponent("t3", SimpleTouchable.class);
-        Touchable t1 = (Touchable) pico.getComponent("t1");
-        assertNotNull(t1);
-        final String s = writer1.toString();
-        assertTrue("writer not empty", s.length() > 0);
-        StringWriter writer2 = new StringWriter();
-        ComponentMonitor monitor2 = new WriterComponentMonitor(writer2);
-        pico.changeMonitor(monitor2);
-        pico.addComponent("t2", SimpleTouchable.class);
-        Touchable t2 = (Touchable) pico.getComponent("t2");
-        assertNotNull(t2);
-        final String s2 = writer2.toString();
-        assertTrue("writer not empty", s2.length() > 0);
-        assertTrue("writers of same length", writer1.toString().length() == writer2.toString().length());
-        Touchable t3 = (Touchable) pico.getComponent("t3");
-        assertNotNull(t3);
-        assertTrue("old writer was used", writer1.toString().length() < writer2.toString().length());
-    }
+	public void testCanChangeMonitorOfChildContainers() {
+		StringWriter writer1 = new StringWriter();
+		ComponentMonitor monitor1 = new WriterComponentMonitor(writer1);
+		DefaultPicoContainer parent = new DefaultPicoContainer();
+		DefaultPicoContainer child = new DefaultPicoContainer(monitor1);
+		parent.addChildContainer(child);
+		child.addComponent("t1", SimpleTouchable.class);
+		child.addComponent("t3", SimpleTouchable.class);
+		Touchable t1 = (Touchable) child.getComponent("t1");
+		assertNotNull(t1);
+		assertTrue("writer not empty", writer1.toString().length() > 0);
+		StringWriter writer2 = new StringWriter();
+		ComponentMonitor monitor2 = new WriterComponentMonitor(writer2);
+		parent.changeMonitor(monitor2);
+		child.addComponent("t2", SimpleTouchable.class);
+		Touchable t2 = (Touchable) child.getComponent("t2");
+		assertNotNull(t2);
+		assertTrue("writer not empty", writer2.toString().length() > 0);
+		String s1 = writer1.toString();
+		String s2 = writer2.toString();
+		assertTrue("writers of same length", s1.length() == s2.length());
+		Touchable t3 = (Touchable) child.getComponent("t3");
+		assertNotNull(t3);
+		assertTrue("old writer was used", writer1.toString().length() < writer2
+				.toString().length());
+	}
 
-    public void testCanChangeMonitorOfChildContainers() {
-        StringWriter writer1 = new StringWriter();
-        ComponentMonitor monitor1 = new WriterComponentMonitor(writer1);
-        DefaultPicoContainer parent = new DefaultPicoContainer();
-        DefaultPicoContainer child = new DefaultPicoContainer(monitor1);
-        parent.addChildContainer(child);
-        child.addComponent("t1", SimpleTouchable.class);
-        child.addComponent("t3", SimpleTouchable.class);
-        Touchable t1 = (Touchable) child.getComponent("t1");
-        assertNotNull(t1);
-        assertTrue("writer not empty", writer1.toString().length() > 0);
-        StringWriter writer2 = new StringWriter();
-        ComponentMonitor monitor2 = new WriterComponentMonitor(writer2);
-        parent.changeMonitor(monitor2);
-        child.addComponent("t2", SimpleTouchable.class);
-        Touchable t2 = (Touchable) child.getComponent("t2");
-        assertNotNull(t2);
-        assertTrue("writer not empty", writer2.toString().length() > 0);
-        String s1 = writer1.toString();
-        String s2 = writer2.toString();
-        assertTrue("writers of same length", s1.length() == s2.length());
-        Touchable t3 = (Touchable) child.getComponent("t3");
-        assertNotNull(t3);
-        assertTrue("old writer was used", writer1.toString().length() < writer2.toString().length());
-    }
+	public void testChangeMonitorIsIgnoredIfNotSupportingStrategy() {
+		StringWriter writer = new StringWriter();
+		ComponentMonitor monitor = new WriterComponentMonitor(writer);
+		DefaultPicoContainer parent = new DefaultPicoContainer(
+				new ComponentFactoryWithNoMonitor(
+						new ComponentAdapterWithNoMonitor(new SimpleTouchable())));
+		parent.addChildContainer(new EmptyPicoContainer());
+		parent.addComponent("t1", SimpleTouchable.class);
+		parent.changeMonitor(monitor);
+		assertTrue("writer empty", writer.toString().length() == 0);
+	}
 
-    public void testChangeMonitorIsIgnoredIfNotSupportingStrategy(){
-        StringWriter writer = new StringWriter();
-        ComponentMonitor monitor = new WriterComponentMonitor(writer);
-        DefaultPicoContainer parent = new DefaultPicoContainer(new ComponentFactoryWithNoMonitor(new ComponentAdapterWithNoMonitor(new SimpleTouchable())));
-        parent.addChildContainer(new EmptyPicoContainer());
-        parent.addComponent("t1", SimpleTouchable.class);
-        parent.changeMonitor(monitor);
-        assertTrue("writer empty", writer.toString().length() == 0);
-    }
-    
-    public void testCanReturnCurrentMonitorFromComponentAdapterFactory() {
-        StringWriter writer1 = new StringWriter();
-        ComponentMonitor monitor1 = new WriterComponentMonitor(writer1);
-        DefaultPicoContainer pico = new DefaultPicoContainer(monitor1);
-        assertEquals(monitor1, pico.currentMonitor());
-        StringWriter writer2 = new StringWriter();
-        ComponentMonitor monitor2 = new WriterComponentMonitor(writer2);
-        pico.changeMonitor(monitor2);
-        assertEquals(monitor2, pico.currentMonitor());
-    }
-   
-    private static final class ComponentFactoryWithNoMonitor implements ComponentFactory {
-        private final ComponentAdapter adapter;
-        public ComponentFactoryWithNoMonitor(ComponentAdapter adapter){
-            this.adapter = adapter;
-        }
-        public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class componentImplementation, Parameter... parameters) throws PicoCompositionException {
-            return adapter;
-        }        
-    }
-    
-    private static final class ComponentAdapterWithNoMonitor implements ComponentAdapter {
-        private final Object instance;
-        public ComponentAdapterWithNoMonitor(Object instance){
-            this.instance = instance;
-        }
-        public Object getComponentKey() {
-            return instance.getClass();
-        }
-        public Class getComponentImplementation() {
-            return instance.getClass();
-        }
-        public Object getComponentInstance(PicoContainer container) throws PicoCompositionException {
-            return instance;
-        }
-        public void verify(PicoContainer container) throws PicoCompositionException {
-        }
-        public void accept(PicoVisitor visitor) {
-        }
-    }
-    
-    public void testMakeChildContainer() {
-        MutablePicoContainer parent = new DefaultPicoContainer();
-        parent.addComponent("t1", SimpleTouchable.class);
-        MutablePicoContainer child = parent.makeChildContainer();
-        Object t1 = child.getParent().getComponent("t1");
-        assertNotNull(t1);
-        assertTrue(t1 instanceof SimpleTouchable);
-    }
+	public void testCanReturnCurrentMonitorFromComponentAdapterFactory() {
+		StringWriter writer1 = new StringWriter();
+		ComponentMonitor monitor1 = new WriterComponentMonitor(writer1);
+		DefaultPicoContainer pico = new DefaultPicoContainer(monitor1);
+		assertEquals(monitor1, pico.currentMonitor());
+		StringWriter writer2 = new StringWriter();
+		ComponentMonitor monitor2 = new WriterComponentMonitor(writer2);
+		pico.changeMonitor(monitor2);
+		assertEquals(monitor2, pico.currentMonitor());
+	}
 
-    public void testCanUseCustomLifecycleStrategyForClassRegistrations() {
-        DefaultPicoContainer dpc = new DefaultPicoContainer(new FailingLifecycleStrategy(), null);
-        dpc.as(Characteristics.CACHE).addComponent(Startable.class, MyStartable.class);
-        try {
-            dpc.start();
-            fail("should have barfed");
-        } catch (RuntimeException e) {
-            assertEquals("foo", e.getMessage());
-        }
-    }
+	private static final class ComponentFactoryWithNoMonitor implements
+			ComponentFactory {
+		private final ComponentAdapter adapter;
 
-    public void testCanUseCustomLifecycleStrategyForInstanceRegistrations() {
-        DefaultPicoContainer dpc = new DefaultPicoContainer(new FailingLifecycleStrategy(), null);
-        Startable myStartable = new MyStartable();
-        dpc.addComponent(Startable.class, myStartable);
-        try {
-            dpc.start();
-            fail("should have barfed");
-        } catch (RuntimeException e) {
-            assertEquals("foo", e.getMessage());
-        }
-    }
+		public ComponentFactoryWithNoMonitor(ComponentAdapter adapter) {
+			this.adapter = adapter;
+		}
 
-    public static class FailingLifecycleStrategy implements LifecycleStrategy {
-            public void start(Object component) {
-                throw new RuntimeException("foo");
-            }
+		public ComponentAdapter createComponentAdapter(
+				ComponentMonitor componentMonitor,
+				LifecycleStrategy lifecycleStrategy,
+				Properties componentProperties, Object componentKey,
+				Class componentImplementation, Parameter... parameters)
+				throws PicoCompositionException {
+			return adapter;
+		}
+	}
 
-            public void stop(Object component) {
-            }
+	private static final class ComponentAdapterWithNoMonitor implements
+			ComponentAdapter {
+		private final Object instance;
 
-            public void dispose(Object component) {
-            }
+		public ComponentAdapterWithNoMonitor(Object instance) {
+			this.instance = instance;
+		}
 
-            public boolean hasLifecycle(Class type) {
-                return true;
-            }
+		public Object getComponentKey() {
+			return instance.getClass();
+		}
 
-    }
-    public static class MyStartable implements Startable {
-        public MyStartable() {
-        }
+		public Class getComponentImplementation() {
+			return instance.getClass();
+		}
 
-        public void start() {
-        }
+		public Object getComponentInstance(PicoContainer container)
+				throws PicoCompositionException {
+			return instance;
+		}
 
-        public void stop() {
-        }
-    }
+		public void verify(PicoContainer container)
+				throws PicoCompositionException {
+		}
 
-    public static interface A {
+		public void accept(PicoVisitor visitor) {
+		}
+	}
 
-    }
+	public void testMakeChildContainer() {
+		MutablePicoContainer parent = new DefaultPicoContainer();
+		parent.addComponent("t1", SimpleTouchable.class);
+		MutablePicoContainer child = parent.makeChildContainer();
+		Object t1 = child.getParent().getComponent("t1");
+		assertNotNull(t1);
+		assertTrue(t1 instanceof SimpleTouchable);
+	}
 
-    public static class SimpleA implements A
-    {
+	public void testCanUseCustomLifecycleStrategyForClassRegistrations() {
+		DefaultPicoContainer dpc = new DefaultPicoContainer(
+				new FailingLifecycleStrategy(), null);
+		dpc.as(Characteristics.CACHE).addComponent(Startable.class,
+				MyStartable.class);
+		try {
+			dpc.start();
+			fail("should have barfed");
+		} catch (RuntimeException e) {
+			assertEquals("foo", e.getMessage());
+		}
+	}
 
-    }
+	public void testCanUseCustomLifecycleStrategyForInstanceRegistrations() {
+		DefaultPicoContainer dpc = new DefaultPicoContainer(
+				new FailingLifecycleStrategy(), null);
+		Startable myStartable = new MyStartable();
+		dpc.addComponent(Startable.class, myStartable);
+		try {
+			dpc.start();
+			fail("should have barfed");
+		} catch (RuntimeException e) {
+			assertEquals("foo", e.getMessage());
+		}
+	}
 
-    public static class WrappingA implements A
-    {
-        private final A wrapped;
+	public static class FailingLifecycleStrategy implements LifecycleStrategy {
+		public void start(Object component) {
+			throw new RuntimeException("foo");
+		}
 
-        public WrappingA(A wrapped) {
-            this.wrapped = wrapped;
-        }
-    }
+		public void stop(Object component) {
+		}
 
-    public void testCanRegisterTwoComponentsImplementingSameInterfaceOneWithInterfaceAsKey() throws Exception {
-        MutablePicoContainer container = createPicoContainer(null);
+		public void dispose(Object component) {
+		}
 
-        container.addComponent(SimpleA.class);
-        container.addComponent(A.class, WrappingA.class);
+		public boolean hasLifecycle(Class type) {
+			return true;
+		}
 
-        container.start();
+	}
 
-        assertEquals(WrappingA.class, container.getComponent(A.class).getClass());
-    }
+	public static class MyStartable implements Startable {
+		public MyStartable() {
+		}
 
-    public void testCanRegisterTwoComponentsWithSameImplementionAndDifferentKey() throws Exception {
-        MutablePicoContainer container = createPicoContainer(null);
+		public void start() {
+		}
 
-        container.addComponent(SimpleA.class);
-        container.addComponent("A", SimpleA.class);
+		public void stop() {
+		}
+	}
 
-        container.start();
+	public static interface A {
 
-        assertNotNull(container.getComponent("A"));
-        assertNotNull(container.getComponent(SimpleA.class));
-        assertNotSame(container.getComponent("A"), container.getComponent(SimpleA.class));
-    }
+	}
 
-    public void testPicoCanDifferentiateBetweenNamedStringsThatWouldOtherwiseBeAmbiguous() {
-        MutablePicoContainer mpc = createPicoContainer(null);
-        mpc.addComponent("greeting", "1");
-        mpc.addComponent("message", "2");
-        mpc.addComponent(PicoCompositionException.class, PicoCompositionException.class);
-        assertEquals("2", mpc.getComponent(PicoCompositionException.class).getMessage());
-    }
+	public static class SimpleA implements A {
 
-    public void testPicoCanDifferentiateBetweenNamedObjectsThatWouldOtherwiseBeAmbiguous() {
-        MutablePicoContainer mpc = createPicoContainer(null);
-        Horse dobbin = new Horse();
-        Horse redRum = new Horse();
-        mpc.addComponent("dobbin", dobbin);
-        mpc.addComponent("horse", redRum);
-        mpc.addComponent(CdiTurtle.class);
-        assertEquals(redRum, mpc.getComponent(CdiTurtle.class).horse);
-    }
+	}
 
-    public void testPicoCanDifferentiateBetweenNamedIntsThatWouldOtherwiseBeAmbiguous() {
-        MutablePicoContainer mpc = createPicoContainer(null);
-        mpc.addComponent("one", 1);
-        mpc.addComponent("two", 2);
-        mpc.addComponent(NeedsTwo.class);
-        assertEquals(2, mpc.getComponent(NeedsTwo.class).two);
-    }
+	public static class WrappingA implements A {
+		private final A wrapped;
 
-    public static class NeedsTwo {
-        private final int two;
-        public NeedsTwo(Integer two) {
-            this.two = two;
-        }
-    }
+		public WrappingA(A wrapped) {
+			this.wrapped = wrapped;
+		}
+	}
 
-    public static class Horse {}
+	public void testCanRegisterTwoComponentsImplementingSameInterfaceOneWithInterfaceAsKey()
+			throws Exception {
+		MutablePicoContainer container = createPicoContainer(null);
 
-    public static class CdiTurtle {
-        public final Horse horse;
-        public CdiTurtle(Horse horse) {
-            this.horse = horse;
-        }
-    }
+		container.addComponent(SimpleA.class);
+		container.addComponent(A.class, WrappingA.class);
 
-    public static class SdiDonkey {
-        public Horse horse;
-        public void setHorse(Horse horse) {
-            this.horse = horse;
-        }
-    }
+		container.start();
 
-    public static class SdiRabbit {
-        public Horse horse;
-        public void setHorse(Horse horse) {
-            this.horse = horse;
-        }
-    }
+		assertEquals(WrappingA.class, container.getComponent(A.class)
+				.getClass());
+	}
 
-    public void testMixingOfSDIandCDI() {
+	public void testCanRegisterTwoComponentsWithSameImplementionAndDifferentKey()
+			throws Exception {
+		MutablePicoContainer container = createPicoContainer(null);
 
-        MutablePicoContainer container = createPicoContainer(null).change(Characteristics.CACHE);
-        container.addComponent(Horse.class);
-        container.change(SDI);
-        container.addComponent(SdiDonkey.class);
-        container.addComponent(SdiRabbit.class);
-        container.change(CDI);
-        container.addComponent(CdiTurtle.class);
+		container.addComponent(SimpleA.class);
+		container.addComponent("A", SimpleA.class);
 
-        SdiDonkey donkey = container.getComponent(SdiDonkey.class);
-        SdiRabbit rabbit = container.getComponent(SdiRabbit.class);
-        CdiTurtle turtle = container.getComponent(CdiTurtle.class);
+		container.start();
 
-        assertions(donkey, rabbit, turtle);
-    }
+		assertNotNull(container.getComponent("A"));
+		assertNotNull(container.getComponent(SimpleA.class));
+		assertNotSame(container.getComponent("A"), container
+				.getComponent(SimpleA.class));
+	}
 
-    public void testMixingOfSDIandCDIDifferently() {
+	public void testPicoCanDifferentiateBetweenNamedStringsThatWouldOtherwiseBeAmbiguous() {
+		MutablePicoContainer mpc = createPicoContainer(null);
+		mpc.addComponent("greeting", "1");
+		mpc.addComponent("message", "2");
+		mpc.addComponent(PicoCompositionException.class,
+				PicoCompositionException.class);
+		assertEquals("2", mpc.getComponent(PicoCompositionException.class)
+				.getMessage());
+	}
 
-        MutablePicoContainer container = createPicoContainer(null).change(Characteristics.CACHE);
-        container.addComponent(Horse.class);
-        container.addComponent(CdiTurtle.class);
-        container.change(SDI);
-        container.addComponent(SdiDonkey.class);
-        container.addComponent(SdiRabbit.class);
+	public void testPicoCanDifferentiateBetweenNamedObjectsThatWouldOtherwiseBeAmbiguous() {
+		MutablePicoContainer mpc = createPicoContainer(null);
+		Horse dobbin = new Horse();
+		Horse redRum = new Horse();
+		mpc.addComponent("dobbin", dobbin);
+		mpc.addComponent("horse", redRum);
+		mpc.addComponent(CdiTurtle.class);
+		assertEquals(redRum, mpc.getComponent(CdiTurtle.class).horse);
+	}
 
-        SdiDonkey donkey = container.getComponent(SdiDonkey.class);
-        SdiRabbit rabbit = container.getComponent(SdiRabbit.class);
-        CdiTurtle turtle = container.getComponent(CdiTurtle.class);
+	public void testPicoCanDifferentiateBetweenNamedIntsThatWouldOtherwiseBeAmbiguous() {
+		MutablePicoContainer mpc = createPicoContainer(null);
+		mpc.addComponent("one", 1);
+		mpc.addComponent("two", 2);
+		mpc.addComponent(NeedsTwo.class);
+		assertEquals(2, mpc.getComponent(NeedsTwo.class).two);
+	}
 
-        assertions(donkey, rabbit, turtle);
-    }
+	public static class NeedsTwo {
+		private final int two;
 
-    public void testMixingOfSDIandCDIInBuilderStyle() {
+		public NeedsTwo(Integer two) {
+			this.two = two;
+		}
+	}
 
-        MutablePicoContainer container = createPicoContainer(null).change(Characteristics.CACHE);
-        container.addComponent(Horse.class).change(SDI)
-                .addComponent(SdiDonkey.class).addComponent(SdiRabbit.class).change(CDI).addComponent(CdiTurtle.class);
+	public static class Horse {
+	}
 
-        SdiDonkey donkey = container.getComponent(SdiDonkey.class);
-        SdiRabbit rabbit = container.getComponent(SdiRabbit.class);
-        CdiTurtle turtle = container.getComponent(CdiTurtle.class);
+	public static class CdiTurtle {
+		public final Horse horse;
 
-        assertions(donkey, rabbit, turtle);
-    }
+		public CdiTurtle(Horse horse) {
+			this.horse = horse;
+		}
+	}
 
-    private void assertions(SdiDonkey donkey, SdiRabbit rabbit, CdiTurtle turtle) {
-        assertNotNull(rabbit);
-        assertNotNull(donkey);
-        assertNotNull(turtle);
-        assertNotNull(turtle.horse);
-        assertNotNull(donkey.horse);
-        assertNotNull(rabbit.horse);
-        assertSame(donkey.horse, turtle.horse);
-        assertSame(rabbit.horse, turtle.horse);
-    }
+	public static class SdiDonkey {
+		public Horse horse;
 
-    public void testMixingOfSDIandCDIWithTemporaryCharacterizations() {
+		public void setHorse(Horse horse) {
+			this.horse = horse;
+		}
+	}
 
-        MutablePicoContainer container = createPicoContainer(null).change(Characteristics.CACHE);
-        container.addComponent(Horse.class);
-        container.addComponent(CdiTurtle.class);
-        container.as(SDI).addComponent(SdiDonkey.class);
-        container.as(SDI).addComponent(SdiRabbit.class);
+	public static class SdiRabbit {
+		public Horse horse;
 
-        SdiDonkey donkey = container.getComponent(SdiDonkey.class);
-        SdiRabbit rabbit = container.getComponent(SdiRabbit.class);
-        CdiTurtle turtle = container.getComponent(CdiTurtle.class);
+		public void setHorse(Horse horse) {
+			this.horse = horse;
+		}
+	}
 
-        assertions(donkey, rabbit, turtle);
-    }
+	public void testMixingOfSDIandCDI() {
 
-    public void testMixingOfSDIandCDIWithTemporaryCharacterizationsDifferently() {
+		MutablePicoContainer container = createPicoContainer(null).change(
+				Characteristics.CACHE);
+		container.addComponent(Horse.class);
+		container.change(SDI);
+		container.addComponent(SdiDonkey.class);
+		container.addComponent(SdiRabbit.class);
+		container.change(CDI);
+		container.addComponent(CdiTurtle.class);
 
-        MutablePicoContainer container = createPicoContainer(null).change(Characteristics.CACHE);
-        container.as(SDI).addComponent(SdiDonkey.class);
-        container.as(SDI).addComponent(SdiRabbit.class);
-        container.addComponent(Horse.class);
-        container.addComponent(CdiTurtle.class);
+		SdiDonkey donkey = container.getComponent(SdiDonkey.class);
+		SdiRabbit rabbit = container.getComponent(SdiRabbit.class);
+		CdiTurtle turtle = container.getComponent(CdiTurtle.class);
 
-        SdiDonkey donkey = container.getComponent(SdiDonkey.class);
-        SdiRabbit rabbit = container.getComponent(SdiRabbit.class);
-        CdiTurtle turtle = container.getComponent(CdiTurtle.class);
+		assertions(donkey, rabbit, turtle);
+	}
 
-        assertions(donkey, rabbit, turtle);
-    }
+	public void testMixingOfSDIandCDIDifferently() {
 
-    public void testNoComponentIsMonitoredAndPotentiallyLateProvided() {
-        final String[] missingKey = new String[1];
-        
-        String foo = (String) new DefaultPicoContainer(new NullComponentMonitor(){
-            public Object noComponentFound(MutablePicoContainer container, Object componentKey) {
-                missingKey[0] = (String) componentKey;
-                return "foo";
-            }
-        }).getComponent("missingKey");
+		MutablePicoContainer container = createPicoContainer(null).change(
+				Characteristics.CACHE);
+		container.addComponent(Horse.class);
+		container.addComponent(CdiTurtle.class);
+		container.change(SDI);
+		container.addComponent(SdiDonkey.class);
+		container.addComponent(SdiRabbit.class);
 
-        assertNotNull(missingKey[0]);
-        assertEquals("missingKey", missingKey[0]);
-        assertEquals("foo", foo);
+		SdiDonkey donkey = container.getComponent(SdiDonkey.class);
+		SdiRabbit rabbit = container.getComponent(SdiRabbit.class);
+		CdiTurtle turtle = container.getComponent(CdiTurtle.class);
 
-    }
+		assertions(donkey, rabbit, turtle);
+	}
 
-    public void testAcceptImplementsBreadthFirstStrategy() {
-        super.testAcceptImplementsBreadthFirstStrategy();
-    }
+	public void testMixingOfSDIandCDIInBuilderStyle() {
+
+		MutablePicoContainer container = createPicoContainer(null).change(
+				Characteristics.CACHE);
+		container.addComponent(Horse.class).change(SDI).addComponent(
+				SdiDonkey.class).addComponent(SdiRabbit.class).change(CDI)
+				.addComponent(CdiTurtle.class);
+
+		SdiDonkey donkey = container.getComponent(SdiDonkey.class);
+		SdiRabbit rabbit = container.getComponent(SdiRabbit.class);
+		CdiTurtle turtle = container.getComponent(CdiTurtle.class);
+
+		assertions(donkey, rabbit, turtle);
+	}
+
+	private void assertions(SdiDonkey donkey, SdiRabbit rabbit, CdiTurtle turtle) {
+		assertNotNull(rabbit);
+		assertNotNull(donkey);
+		assertNotNull(turtle);
+		assertNotNull(turtle.horse);
+		assertNotNull(donkey.horse);
+		assertNotNull(rabbit.horse);
+		assertSame(donkey.horse, turtle.horse);
+		assertSame(rabbit.horse, turtle.horse);
+	}
+
+	public void testMixingOfSDIandCDIWithTemporaryCharacterizations() {
+
+		MutablePicoContainer container = createPicoContainer(null).change(
+				Characteristics.CACHE);
+		container.addComponent(Horse.class);
+		container.addComponent(CdiTurtle.class);
+		container.as(SDI).addComponent(SdiDonkey.class);
+		container.as(SDI).addComponent(SdiRabbit.class);
+
+		SdiDonkey donkey = container.getComponent(SdiDonkey.class);
+		SdiRabbit rabbit = container.getComponent(SdiRabbit.class);
+		CdiTurtle turtle = container.getComponent(CdiTurtle.class);
+
+		assertions(donkey, rabbit, turtle);
+	}
+
+	public void testMixingOfSDIandCDIWithTemporaryCharacterizationsDifferently() {
+
+		MutablePicoContainer container = createPicoContainer(null).change(
+				Characteristics.CACHE);
+		container.as(SDI).addComponent(SdiDonkey.class);
+		container.as(SDI).addComponent(SdiRabbit.class);
+		container.addComponent(Horse.class);
+		container.addComponent(CdiTurtle.class);
+
+		SdiDonkey donkey = container.getComponent(SdiDonkey.class);
+		SdiRabbit rabbit = container.getComponent(SdiRabbit.class);
+		CdiTurtle turtle = container.getComponent(CdiTurtle.class);
+
+		assertions(donkey, rabbit, turtle);
+	}
+
+	public void testNoComponentIsMonitoredAndPotentiallyLateProvided() {
+		final String[] missingKey = new String[1];
+
+		String foo = (String) new DefaultPicoContainer(
+				new NullComponentMonitor() {
+					public Object noComponentFound(
+							MutablePicoContainer container, Object componentKey) {
+						missingKey[0] = (String) componentKey;
+						return "foo";
+					}
+				}).getComponent("missingKey");
+
+		assertNotNull(missingKey[0]);
+		assertEquals("missingKey", missingKey[0]);
+		assertEquals("foo", foo);
+
+	}
+
+	public void testAcceptImplementsBreadthFirstStrategy() {
+		super.testAcceptImplementsBreadthFirstStrategy();
+	}
 }
\ No newline at end of file
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.