KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > picocontainer > defaults > DefaultPicoContainerTestCase


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

10 package org.picocontainer.defaults;
11
12 import org.picocontainer.ComponentAdapter;
13 import org.picocontainer.ComponentMonitor;
14 import org.picocontainer.MutablePicoContainer;
15 import org.picocontainer.Parameter;
16 import org.picocontainer.PicoContainer;
17 import org.picocontainer.PicoInitializationException;
18 import org.picocontainer.PicoIntrospectionException;
19 import org.picocontainer.PicoVisitor;
20 import org.picocontainer.Startable;
21 import org.picocontainer.alternatives.EmptyPicoContainer;
22 import org.picocontainer.monitors.DefaultComponentMonitor;
23 import org.picocontainer.monitors.WriterComponentMonitor;
24 import org.picocontainer.tck.AbstractPicoContainerTestCase;
25 import org.picocontainer.testmodel.DecoratedTouchable;
26 import org.picocontainer.testmodel.DependsOnTouchable;
27 import org.picocontainer.testmodel.SimpleTouchable;
28 import org.picocontainer.testmodel.Touchable;
29
30 import java.io.Serializable JavaDoc;
31 import java.io.StringWriter JavaDoc;
32 import java.lang.reflect.Method JavaDoc;
33 import java.util.ArrayList JavaDoc;
34 import java.util.Collection JavaDoc;
35 import java.util.HashMap JavaDoc;
36 import java.util.LinkedList JavaDoc;
37 import java.util.List JavaDoc;
38
39 /**
40  * @author Aslak Hellesøy
41  * @author Paul Hammant
42  * @author Ward Cunningham
43  * @author Mauro Talevi
44  * @version $Revision: 3116 $
45  */

46 public class DefaultPicoContainerTestCase extends AbstractPicoContainerTestCase {
47     protected MutablePicoContainer createPicoContainer(PicoContainer parent) {
48         return new DefaultPicoContainer(parent);
49     }
50
51     public void testInstantiationWithNullComponentAdapterFactory(){
52         try {
53             new DefaultPicoContainer((ComponentAdapterFactory)null, (PicoContainer)null);
54             fail("NPE expected");
55         } catch (NullPointerException JavaDoc e) {
56             // expected
57
}
58     }
59     public void testUpDownDependenciesCannotBeFollowed() {
60         MutablePicoContainer parent = createPicoContainer(null);
61         MutablePicoContainer child = createPicoContainer(parent);
62
63         // ComponentF -> ComponentA -> ComponentB+C
64
child.registerComponentImplementation(ComponentF.class);
65         parent.registerComponentImplementation(ComponentA.class);
66         child.registerComponentImplementation(ComponentB.class);
67         child.registerComponentImplementation(ComponentC.class);
68
69         try {
70             child.getComponentInstance(ComponentF.class);
71             fail("Thrown " + UnsatisfiableDependenciesException.class.getName() + " expected");
72         } catch (final UnsatisfiableDependenciesException e) {
73             assertEquals(ComponentB.class, e.getUnsatisfiedDependencyType());
74         }
75     }
76
77     public void testComponentsCanBeRemovedByInstance() {
78         MutablePicoContainer pico = createPicoContainer(null);
79         pico.registerComponentImplementation(HashMap JavaDoc.class);
80         pico.registerComponentImplementation(ArrayList JavaDoc.class);
81         List JavaDoc list = (List JavaDoc) pico.getComponentInstanceOfType(List JavaDoc.class);
82         pico.unregisterComponentByInstance(list);
83         assertEquals(1, pico.getComponentAdapters().size());
84         assertEquals(1, pico.getComponentInstances().size());
85         assertEquals(HashMap JavaDoc.class, pico.getComponentInstanceOfType(Serializable JavaDoc.class).getClass());
86     }
87
88     public void testComponentInstancesListIsReturnedForNullType(){
89         MutablePicoContainer pico = createPicoContainer(null);
90         List JavaDoc componentInstances = pico.getComponentInstancesOfType(null);
91         assertNotNull(componentInstances);
92         assertEquals(0, componentInstances.size());
93     }
94     
95     public void testComponentsWithCommonSupertypeWhichIsAConstructorArgumentCanBeLookedUpByConcreteType() {
96         MutablePicoContainer pico = createPicoContainer(null);
97         pico.registerComponentImplementation(LinkedList JavaDoc.class, LinkedList JavaDoc.class, new Parameter[0]);
98         pico.registerComponentImplementation(ArrayList JavaDoc.class);
99         assertEquals(ArrayList JavaDoc.class, pico.getComponentInstanceOfType(ArrayList JavaDoc.class).getClass());
100     }
101
102     /*
103      When pico tries to resolve DecoratedTouchable it find as dependency itself and SimpleTouchable.
104      Problem is basically the same as above. Pico should not consider self as solution.
105      
106      JS
107      fixed it ( PICO-222 )
108      KP
109      */

110     public void testUnambiguouSelfDependency() {
111         MutablePicoContainer pico = createPicoContainer(null);
112         pico.registerComponentImplementation(SimpleTouchable.class);
113         pico.registerComponentImplementation(DecoratedTouchable.class);
114         Touchable t = (Touchable) pico.getComponentInstance(DecoratedTouchable.class);
115         assertNotNull(t);
116     }
117
118     public static class Thingie {
119         public Thingie(List JavaDoc c) {
120             assertNotNull(c);
121         }
122     }
123
124     public void testThangCanBeInstantiatedWithArrayList() {
125         MutablePicoContainer pico = new DefaultPicoContainer();
126         pico.registerComponentImplementation(Thingie.class);
127         pico.registerComponentImplementation(ArrayList JavaDoc.class);
128         assertNotNull(pico.getComponentInstance(Thingie.class));
129     }
130
131     public void testGetComponentAdaptersOfTypeNullReturnsEmptyList() {
132         DefaultPicoContainer pico = new DefaultPicoContainer();
133         List JavaDoc adapters = pico.getComponentAdaptersOfType(null);
134         assertNotNull(adapters);
135         assertEquals(0, adapters.size());
136     }
137     
138
139     public static class Service {
140     }
141
142     public static class TransientComponent {
143         private Service service;
144
145         public TransientComponent(Service service) {
146             this.service = service;
147         }
148     }
149
150     public void testDefaultPicoContainerReturnsNewInstanceForEachCallWhenUsingTransientComponentAdapter() {
151         DefaultPicoContainer picoContainer = new DefaultPicoContainer();
152         picoContainer.registerComponentImplementation(Service.class);
153         picoContainer.registerComponent(new ConstructorInjectionComponentAdapter(TransientComponent.class, TransientComponent.class));
154         TransientComponent c1 = (TransientComponent) picoContainer.getComponentInstance(TransientComponent.class);
155         TransientComponent c2 = (TransientComponent) picoContainer.getComponentInstance(TransientComponent.class);
156         assertNotSame(c1, c2);
157         assertSame(c1.service, c2.service);
158     }
159
160     public static class DependsOnCollection {
161         public DependsOnCollection(Collection JavaDoc c) {
162         }
163     }
164
165     public void testShouldProvideInfoAboutDependingWhenAmbiguityHappens() {
166         MutablePicoContainer pico = this.createPicoContainer(null);
167         pico.registerComponentInstance(new ArrayList JavaDoc());
168         pico.registerComponentInstance(new LinkedList JavaDoc());
169         pico.registerComponentImplementation(DependsOnCollection.class);
170         try {
171             pico.getComponentInstanceOfType(DependsOnCollection.class);
172             fail();
173         } catch (AmbiguousComponentResolutionException expected) {
174             String JavaDoc doc = DependsOnCollection.class.getName();
175             assertEquals("class " + doc + " has ambiguous dependency on interface java.util.Collection, resolves to multiple classes: [class java.util.ArrayList, class java.util.LinkedList]", expected.getMessage());
176         }
177     }
178
179     public void testInstantiationWithMonitorAndParent() {
180         StringWriter JavaDoc writer = new StringWriter JavaDoc();
181         ComponentMonitor monitor = new WriterComponentMonitor(writer);
182         DefaultPicoContainer parent = new DefaultPicoContainer();
183         DefaultPicoContainer child = new DefaultPicoContainer(monitor, parent);
184         parent.registerComponentImplementation("st", SimpleTouchable.class);
185         child.registerComponentImplementation("dot", DependsOnTouchable.class);
186         DependsOnTouchable dot = (DependsOnTouchable) child.getComponentInstance("dot");
187         assertNotNull(dot);
188         assertTrue("writer not empty", writer.toString().length() > 0);
189     }
190     
191     public void testStartCapturedByMonitor() {
192         final StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
193         DefaultPicoContainer dpc = new DefaultPicoContainer(new DefaultComponentMonitor() {
194             public void invoking(Method JavaDoc method, Object JavaDoc instance) {
195                 sb.append(method.toString());
196             }
197         });
198         dpc.registerComponentImplementation(DefaultPicoContainer.class);
199         dpc.start();
200         assertEquals("ComponentMonitor should have been notified that the component had been started",
201                 "public abstract void org.picocontainer.Startable.start()", sb.toString());
202     }
203
204     public void testCanChangeMonitor() {
205         StringWriter JavaDoc writer1 = new StringWriter JavaDoc();
206         ComponentMonitor monitor1 = new WriterComponentMonitor(writer1);
207         DefaultPicoContainer pico = new DefaultPicoContainer(monitor1);
208         pico.registerComponentImplementation("t1", SimpleTouchable.class);
209         pico.registerComponentImplementation("t3", SimpleTouchable.class);
210         Touchable t1 = (Touchable) pico.getComponentInstance("t1");
211         assertNotNull(t1);
212         assertTrue("writer not empty", writer1.toString().length() > 0);
213         StringWriter JavaDoc writer2 = new StringWriter JavaDoc();
214         ComponentMonitor monitor2 = new WriterComponentMonitor(writer2);
215         pico.changeMonitor(monitor2);
216         pico.registerComponentImplementation("t2", SimpleTouchable.class);
217         Touchable t2 = (Touchable) pico.getComponentInstance("t2");
218         assertNotNull(t2);
219         assertTrue("writer not empty", writer2.toString().length() > 0);
220         assertTrue("writers of same length", writer1.toString().length() == writer2.toString().length());
221         Touchable t3 = (Touchable) pico.getComponentInstance("t3");
222         assertNotNull(t3);
223         assertTrue("old writer was used", writer1.toString().length() < writer2.toString().length());
224     }
225
226     public void testCanChangeMonitorOfChildContainers() {
227         StringWriter JavaDoc writer1 = new StringWriter JavaDoc();
228         ComponentMonitor monitor1 = new WriterComponentMonitor(writer1);
229         DefaultPicoContainer parent = new DefaultPicoContainer();
230         DefaultPicoContainer child = new DefaultPicoContainer(monitor1);
231         parent.addChildContainer(child);
232         child.registerComponentImplementation("t1", SimpleTouchable.class);
233         child.registerComponentImplementation("t3", SimpleTouchable.class);
234         Touchable t1 = (Touchable) child.getComponentInstance("t1");
235         assertNotNull(t1);
236         assertTrue("writer not empty", writer1.toString().length() > 0);
237         StringWriter JavaDoc writer2 = new StringWriter JavaDoc();
238         ComponentMonitor monitor2 = new WriterComponentMonitor(writer2);
239         parent.changeMonitor(monitor2);
240         child.registerComponentImplementation("t2", SimpleTouchable.class);
241         Touchable t2 = (Touchable) child.getComponentInstance("t2");
242         assertNotNull(t2);
243         assertTrue("writer not empty", writer2.toString().length() > 0);
244         String JavaDoc s1 = writer1.toString();
245         String JavaDoc s2 = writer2.toString();
246         assertTrue("writers of same length", s1.length() == s2.length());
247         Touchable t3 = (Touchable) child.getComponentInstance("t3");
248         assertNotNull(t3);
249         assertTrue("old writer was used", writer1.toString().length() < writer2.toString().length());
250     }
251
252     public void testChangeMonitorIsIgnoredIfNotSupportingStrategy(){
253         StringWriter JavaDoc writer = new StringWriter JavaDoc();
254         ComponentMonitor monitor = new WriterComponentMonitor(writer);
255         DefaultPicoContainer parent = new DefaultPicoContainer(new ComponentAdapterFactoryWithNoMonitor(new ComponentAdapterWithNoMonitor(new SimpleTouchable())));
256         parent.addChildContainer(new EmptyPicoContainer());
257         parent.registerComponentImplementation("t1", SimpleTouchable.class);
258         parent.changeMonitor(monitor);
259         assertTrue("writer empty", writer.toString().length() == 0);
260     }
261     
262     public void testCanReturnCurrentMonitorFromComponentAdapterFactory() {
263         StringWriter JavaDoc writer1 = new StringWriter JavaDoc();
264         ComponentMonitor monitor1 = new WriterComponentMonitor(writer1);
265         DefaultPicoContainer pico = new DefaultPicoContainer(monitor1);
266         assertEquals(monitor1, pico.currentMonitor());
267         StringWriter JavaDoc writer2 = new StringWriter JavaDoc();
268         ComponentMonitor monitor2 = new WriterComponentMonitor(writer2);
269         pico.changeMonitor(monitor2);
270         assertEquals(monitor2, pico.currentMonitor());
271     }
272
273     public void testCanReturnCurrentMonitorFromComponentAdapter() {
274         StringWriter JavaDoc writer1 = new StringWriter JavaDoc();
275         ComponentMonitor monitor1 = new WriterComponentMonitor(writer1);
276         InstanceComponentAdapter adapterWithMonitor = new InstanceComponentAdapter(SimpleTouchable.class.getName(), new SimpleTouchable());
277         adapterWithMonitor.changeMonitor(monitor1);
278         DefaultPicoContainer pico = new DefaultPicoContainer(new ComponentAdapterFactoryWithNoMonitor(adapterWithMonitor));
279         pico.registerComponentImplementation("t1", SimpleTouchable.class);
280         assertEquals(monitor1, pico.currentMonitor());
281         StringWriter JavaDoc writer2 = new StringWriter JavaDoc();
282         ComponentMonitor monitor2 = new WriterComponentMonitor(writer2);
283         pico.changeMonitor(monitor2);
284         assertEquals(monitor2, pico.currentMonitor());
285     }
286
287     public void testCanReturnCurrentMonitorFromChildContainer() {
288         StringWriter JavaDoc writer1 = new StringWriter JavaDoc();
289         ComponentMonitor monitor1 = new WriterComponentMonitor(writer1);
290         DefaultPicoContainer pico = new DefaultPicoContainer(new ComponentAdapterFactoryWithNoMonitor(new ComponentAdapterWithNoMonitor(new SimpleTouchable())));
291         pico.registerComponentImplementation("t1", SimpleTouchable.class);
292         // first child does not support ComponentMonitorStrategy
293
pico.addChildContainer(new EmptyPicoContainer());
294         // second child does support ComponentMonitorStrategy
295
pico.addChildContainer(new DefaultPicoContainer(monitor1));
296         assertEquals(monitor1, pico.currentMonitor());
297         StringWriter JavaDoc writer2 = new StringWriter JavaDoc();
298         ComponentMonitor monitor2 = new WriterComponentMonitor(writer2);
299         pico.changeMonitor(monitor2);
300         assertEquals(monitor2, pico.currentMonitor());
301     }
302     
303     public void testCannotReturnCurrentMonitor() {
304         DefaultPicoContainer pico = new DefaultPicoContainer(new ComponentAdapterFactoryWithNoMonitor(null));
305         try {
306             pico.currentMonitor();
307             fail("PicoIntrospectionException expected");
308         } catch (PicoIntrospectionException e) {
309             assertEquals("No component monitor found in container or its children", e.getMessage());
310         }
311     }
312
313     private static class ComponentAdapterFactoryWithNoMonitor implements ComponentAdapterFactory {
314         private ComponentAdapter adapter;
315         public ComponentAdapterFactoryWithNoMonitor(ComponentAdapter adapter){
316             this.adapter = adapter;
317         }
318         public ComponentAdapter createComponentAdapter(Object JavaDoc componentKey, Class JavaDoc componentImplementation, Parameter[] parameters) throws PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
319             return adapter;
320         }
321     }
322     
323     private static class ComponentAdapterWithNoMonitor implements ComponentAdapter {
324         private Object JavaDoc instance;
325         public ComponentAdapterWithNoMonitor(Object JavaDoc instance){
326             this.instance = instance;
327         }
328         public Object JavaDoc getComponentKey() {
329             return instance.getClass();
330         }
331         public Class JavaDoc getComponentImplementation() {
332             return instance.getClass();
333         }
334         public Object JavaDoc getComponentInstance(PicoContainer container) throws PicoInitializationException, PicoIntrospectionException {
335             return instance;
336         }
337         public void verify(PicoContainer container) throws PicoIntrospectionException {
338         }
339         public void accept(PicoVisitor visitor) {
340         }
341     }
342     
343     public void testMakeChildContainer() {
344         MutablePicoContainer parent = new DefaultPicoContainer();
345         parent.registerComponentImplementation("t1", SimpleTouchable.class);
346         MutablePicoContainer child = parent.makeChildContainer();
347         Object JavaDoc t1 = child.getParent().getComponentInstance("t1");
348         assertNotNull(t1);
349         assertTrue(t1 instanceof SimpleTouchable);
350     }
351
352     public void testCanUseCustomLifecycleStrategyForClassRegistrations() {
353         DefaultPicoContainer dpc = new DefaultPicoContainer(new FailingLifecycleStrategy(), null);
354         dpc.registerComponentImplementation(Startable.class, MyStartable.class);
355         try {
356             dpc.start();
357             fail("should have barfed");
358         } catch (RuntimeException JavaDoc e) {
359             assertEquals("foo", e.getMessage());
360         }
361     }
362
363     public void testCanUseCustomLifecycleStrategyForInstanceRegistrations() {
364         DefaultPicoContainer dpc = new DefaultPicoContainer(new FailingLifecycleStrategy(), null);
365         Startable myStartable = new MyStartable();
366         dpc.registerComponentInstance(Startable.class, myStartable);
367         try {
368             dpc.start();
369             fail("should have barfed");
370         } catch (RuntimeException JavaDoc e) {
371             assertEquals("foo", e.getMessage());
372         }
373     }
374
375     public static class FailingLifecycleStrategy implements LifecycleStrategy {
376             public void start(Object JavaDoc component) {
377                 throw new RuntimeException JavaDoc("foo");
378             }
379
380             public void stop(Object JavaDoc component) {
381             }
382
383             public void dispose(Object JavaDoc component) {
384             }
385
386             public boolean hasLifecycle(Class JavaDoc type) {
387                 return true;
388             }
389
390     }
391     public static class MyStartable implements Startable {
392         public MyStartable() {
393         }
394
395         public void start() {
396         }
397
398         public void stop() {
399         }
400     }
401
402     public static interface A {
403
404     }
405
406     public static class SimpleA implements A
407     {
408
409     }
410
411     public static class WrappingA implements A
412     {
413         private final A wrapped;
414
415         public WrappingA(A wrapped) {
416             this.wrapped = wrapped;
417         }
418     }
419
420     public void testCanRegisterTwoComponentsImplementingSameInterfaceOneWithInterfaceAsKey() throws Exception JavaDoc {
421         MutablePicoContainer container = createPicoContainer(null);
422
423         container.registerComponentImplementation(SimpleA.class);
424         container.registerComponentImplementation(A.class, WrappingA.class);
425
426         container.start();
427
428         assertEquals(WrappingA.class, container.getComponentInstance(A.class).getClass());
429     }
430
431     public void testCanRegisterTwoComponentsWithSameImplementionAndDifferentKey() throws Exception JavaDoc {
432         MutablePicoContainer container = createPicoContainer(null);
433
434         container.registerComponentImplementation(SimpleA.class);
435         container.registerComponentImplementation("A", SimpleA.class);
436
437         container.start();
438
439         assertNotNull(container.getComponentInstance("A"));
440         assertNotNull(container.getComponentInstance(SimpleA.class));
441         assertNotSame(container.getComponentInstance("A"), container.getComponentInstance(SimpleA.class));
442     }
443     
444     public static class MyPicoContainer extends DefaultPicoContainer {
445
446         public ComponentAdapter registerComponent(ComponentAdapter componentAdapter) {
447             return super.registerComponent(new SynchronizedComponentAdapter(componentAdapter));
448         }
449         
450     }
451     
452     public void testDerivedPicoContainerCanOverloadRegisterComponentForAllCreatedComponentAdapters() {
453         MutablePicoContainer mpc = new MyPicoContainer();
454         assertEquals(SynchronizedComponentAdapter.class, mpc.registerComponent(new InstanceComponentAdapter("foo", "bar")).getClass());
455         assertEquals(SynchronizedComponentAdapter.class, mpc.registerComponentInstance("foobar").getClass());
456         assertEquals(SynchronizedComponentAdapter.class, mpc.registerComponentImplementation(SimpleA.class).getClass());
457     }
458 }
Popular Tags