001    /*****************************************************************************
002     * Copyright (C) PicoContainer Organization. All rights reserved.            *
003     * ------------------------------------------------------------------------- *
004     * The software in this package is published under the terms of the BSD      *
005     * style license a copy of which has been included with this distribution in *
006     * the LICENSE.txt file.                                                     *
007     *                                                                           *
008     * Original code by                                                          *
009     *****************************************************************************/
010    package org.picocontainer;
011    
012    import static org.picocontainer.behaviors.Behaviors.caching;
013    import static org.picocontainer.behaviors.Behaviors.implHiding;
014    import static org.picocontainer.behaviors.Behaviors.threadSafe;
015    import org.picocontainer.behaviors.ImplementationHidingBehaviorFactory;
016    import org.picocontainer.containers.EmptyPicoContainer;
017    import static org.picocontainer.injectors.Injectors.SDI;
018    import org.picocontainer.monitors.ConsoleComponentMonitor;
019    import org.picocontainer.monitors.NullComponentMonitor;
020    
021    import java.util.ArrayList;
022    import java.util.HashMap;
023    import java.util.HashSet;
024    import java.util.Properties;
025    
026    import com.thoughtworks.xstream.XStream;
027    import com.thoughtworks.xstream.converters.Converter;
028    import com.thoughtworks.xstream.converters.MarshallingContext;
029    import com.thoughtworks.xstream.converters.UnmarshallingContext;
030    import com.thoughtworks.xstream.io.HierarchicalStreamReader;
031    import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
032    import junit.framework.TestCase;
033    
034    public class PicoBuilderTestCase extends TestCase {
035    
036        private XStream xs;
037    
038        protected void setUp() throws Exception {
039            xs = new XStream();
040            xs.alias("PICO", DefaultPicoContainer.class);
041            xs.registerConverter(new Converter() {
042                public boolean canConvert(Class aClass) {
043                    return aClass.getName().equals("org.picocontainer.DefaultPicoContainer$1") ||
044                           aClass.getName().equals("org.picocontainer.Properties") ||
045                           aClass == Boolean.class ||
046                           aClass == HashSet.class ||
047                           aClass == ArrayList.class;
048                }
049    
050                public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
051                }
052    
053                public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
054                    return null;
055                }
056            });
057            xs.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
058        }
059    
060        public void testBasic() {
061            MutablePicoContainer mpc = new PicoBuilder().build();
062            String foo = simplifyRepresentation(mpc);
063            assertEquals("PICO\n" +
064                    "  componentFactory=org.picocontainer.injectors.AdaptiveInjectionFactory\n" +
065                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
066                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
067                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
068                    "PICO",foo);
069        }
070    
071        public void testWithStartableLifecycle() {
072    
073            new NullComponentMonitor();
074    
075            MutablePicoContainer mpc = new PicoBuilder().withLifecycle().build();
076            String foo = simplifyRepresentation(mpc);
077            assertEquals("PICO\n" +
078                    "  componentFactory=org.picocontainer.injectors.AdaptiveInjectionFactory\n" +
079                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
080                    "  lifecycleStrategy=org.picocontainer.lifecycle.StartableLifecycleStrategy\n" +
081                    "    componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
082                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor reference=/PICO/lifecycleStrategy/componentMonitor\n" +
083                    "PICO",foo);
084        }
085    
086        public void testWithReflectionLifecycle() {
087            MutablePicoContainer mpc = new PicoBuilder().withReflectionLifecycle().build();
088            String foo = simplifyRepresentation(mpc);
089            assertEquals("PICO\n" +
090                    "  componentFactory=org.picocontainer.injectors.AdaptiveInjectionFactory\n" +
091                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
092                    "  lifecycleStrategy=org.picocontainer.lifecycle.ReflectionLifecycleStrategy\n" +
093                    "    methodNames\n" +
094                    "      stringstartstring\n" +
095                    "      stringstopstring\n" +
096                    "      stringdisposestring\n" +
097                    "    methodNames\n" +
098                    "    componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
099                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor reference=/PICO/lifecycleStrategy/componentMonitor\n" +
100                    "PICO",foo);
101        }
102    
103    
104        public void testWithConsoleMonitor() {
105            MutablePicoContainer mpc = new PicoBuilder().withConsoleMonitor().build();
106            String foo = simplifyRepresentation(mpc);
107            assertEquals("PICO\n" +
108                    "  componentFactory=org.picocontainer.injectors.AdaptiveInjectionFactory\n" +
109                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
110                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
111                    "  componentMonitor=org.picocontainer.monitors.ConsoleComponentMonitor\n" +
112                    "    delegate=org.picocontainer.monitors.NullComponentMonitor\n" +
113                    "PICO",foo);
114        }
115    
116        public void testWithConsoleMonitorAndLifecycleUseTheSameUltimateMonitor() {
117            MutablePicoContainer mpc = new PicoBuilder().withLifecycle().withConsoleMonitor().build();
118            String foo = simplifyRepresentation(mpc);
119            assertEquals("PICO\n" +
120                         "  componentFactory=org.picocontainer.injectors.AdaptiveInjectionFactory\n" +
121                         "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
122                         "  lifecycleStrategy=org.picocontainer.lifecycle.StartableLifecycleStrategy\n" +
123                         "    componentMonitor=org.picocontainer.monitors.ConsoleComponentMonitor\n" +
124                         "      delegate=org.picocontainer.monitors.NullComponentMonitor\n" +
125                         "  componentMonitor=org.picocontainer.monitors.ConsoleComponentMonitor reference=/PICO/lifecycleStrategy/componentMonitor\n" +
126                         "PICO",foo);
127        }
128    
129    
130        public void testWithCustomMonitorByClass() {
131            MutablePicoContainer mpc = new PicoBuilder().withMonitor(ConsoleComponentMonitor.class).build();
132            String foo = simplifyRepresentation(mpc);
133            assertEquals("PICO\n" +
134                    "  componentFactory=org.picocontainer.injectors.AdaptiveInjectionFactory\n" +
135                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
136                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
137                    "  componentMonitor=org.picocontainer.monitors.ConsoleComponentMonitor\n" +
138                    "    delegate=org.picocontainer.monitors.NullComponentMonitor\n" +
139                    "PICO",foo);
140        }
141    
142        @SuppressWarnings({ "unchecked" })
143        public void testWithBogusCustomMonitorByClass() {
144            // We do unchecked assignment so we test what its really doing, and smart IDE's don't complain
145            try {
146                Class aClass = HashMap.class;
147                new PicoBuilder().withMonitor(aClass).build();
148                fail("should have barfed");
149            } catch (ClassCastException e) {
150                // expected
151            }
152        }
153    
154        public void testWithImplementationHiding() {
155            MutablePicoContainer mpc = new PicoBuilder().withHiddenImplementations().build();
156            String foo = simplifyRepresentation(mpc);
157            assertEquals("PICO\n" +
158                    "  componentFactory=org.picocontainer.behaviors.ImplementationHidingBehaviorFactory\n" +
159                    "    delegate=org.picocontainer.injectors.AdaptiveInjectionFactory\n" +
160                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
161                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
162                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
163                    "PICO",foo);
164        }
165    
166        public void testWithImplementationHidingInstance() {
167            MutablePicoContainer mpc = new PicoBuilder().withComponentFactory(new ImplementationHidingBehaviorFactory()).build();
168            String foo = simplifyRepresentation(mpc);
169            assertEquals("PICO\n" +
170                    "  componentFactory=org.picocontainer.behaviors.ImplementationHidingBehaviorFactory\n" +
171                    "    delegate=org.picocontainer.injectors.AdaptiveInjectionFactory\n" +
172                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
173                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
174                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
175                    "PICO",foo);
176        }
177    
178        public void testWithCafsListChainThingy() {
179            MutablePicoContainer mpc = new PicoBuilder(SDI()).withBehaviors(caching(), threadSafe(), implHiding()).build();
180            String foo = simplifyRepresentation(mpc);
181            assertEquals("PICO\n" +
182                    "  componentFactory=org.picocontainer.behaviors.CachingBehaviorFactory\n" +
183                    "    delegate=org.picocontainer.behaviors.SynchronizedBehaviorFactory\n" +
184                    "      delegate=org.picocontainer.behaviors.ImplementationHidingBehaviorFactory\n" +
185                    "        delegate=org.picocontainer.injectors.SetterInjectionFactory\n" +
186                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
187                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
188                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
189                    "PICO",foo);
190        }
191    
192    
193        public static class CustomParentcontainer extends EmptyPicoContainer {}
194    
195        public void testWithCustomParentContainer() {
196            MutablePicoContainer mpc = new PicoBuilder(new CustomParentcontainer()).build();
197            String foo = simplifyRepresentation(mpc);
198            assertEquals("PICO\n" +
199                    "  componentFactory=org.picocontainer.injectors.AdaptiveInjectionFactory\n" +
200                    "  parent=org.picocontainer.PicoBuilderTestCase_CustomParentcontainer\n" +
201                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
202                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
203                    "PICO",foo);
204        }
205    
206        public void testWithBogusParentContainerBehavesAsIfNotSet() {
207            MutablePicoContainer mpc = new PicoBuilder((PicoContainer)null).build();
208            String foo = simplifyRepresentation(mpc);
209            assertEquals("PICO\n" +
210                         "  componentFactory=org.picocontainer.injectors.AdaptiveInjectionFactory\n" +
211                         "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
212                         "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
213                         "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
214                         "PICO", foo);
215        }
216    
217    
218        public void testWithSetterDI() {
219            MutablePicoContainer mpc = new PicoBuilder().withSetterInjection().build();
220            String foo = simplifyRepresentation(mpc);
221            assertEquals("PICO\n" +
222                    "  componentFactory=org.picocontainer.injectors.SetterInjectionFactory\n" +
223                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
224                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
225                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
226                    "PICO",foo);
227        }
228    
229        public void testWithAnnotationDI() {
230                MutablePicoContainer mpc = new PicoBuilder().withAnnotationInjection().build();
231            String foo = simplifyRepresentation(mpc);
232            assertEquals("PICO\n" +
233                    "  componentFactory=org.picocontainer.injectors.MethodAnnotationInjectionFactory\n" +
234                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
235                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
236                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
237                    "PICO",foo);
238        }
239    
240        public void testWithCtorDI() {
241            MutablePicoContainer mpc = new PicoBuilder().withConstructorInjection().build();
242            String foo = simplifyRepresentation(mpc);
243            assertEquals("PICO\n" +
244                    "  componentFactory=org.picocontainer.injectors.ConstructorInjectionFactory\n" +
245                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
246                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
247                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
248                    "PICO",foo);
249        }
250    
251        public void testWithImplementationHidingAndSetterDI() {
252            MutablePicoContainer mpc = new PicoBuilder().withHiddenImplementations().withSetterInjection().build();
253            String foo = simplifyRepresentation(mpc);
254            assertEquals("PICO\n" +
255                    "  componentFactory=org.picocontainer.behaviors.ImplementationHidingBehaviorFactory\n" +
256                    "    delegate=org.picocontainer.injectors.SetterInjectionFactory\n" +
257                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
258                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
259                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
260                    "PICO",foo);
261        }
262    
263        public void testWithCachingImplementationHidingAndSetterDI() {
264            MutablePicoContainer mpc = new PicoBuilder().withCaching().withHiddenImplementations().withSetterInjection().build();
265            String foo = simplifyRepresentation(mpc);
266            assertEquals("PICO\n" +
267                    "  componentFactory=org.picocontainer.behaviors.CachingBehaviorFactory\n" +
268                    "    delegate=org.picocontainer.behaviors.ImplementationHidingBehaviorFactory\n" +
269                    "      delegate=org.picocontainer.injectors.SetterInjectionFactory\n" +
270                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
271                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
272                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
273                    "PICO",foo);
274        }
275    
276        public void testWithThreadSafety() {
277            MutablePicoContainer mpc = new PicoBuilder().withThreadSafety().build();
278            String foo = simplifyRepresentation(mpc);
279            assertEquals("PICO\n" +
280                    "  componentFactory=org.picocontainer.behaviors.SynchronizedBehaviorFactory\n" +
281                    "    delegate=org.picocontainer.injectors.AdaptiveInjectionFactory\n" +
282                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
283                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
284                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
285                    "PICO",foo);
286        }
287    
288        public void testWithPropertyApplier() {
289            MutablePicoContainer mpc = new PicoBuilder().withPropertyApplier().build();
290            String foo = simplifyRepresentation(mpc);
291            assertEquals("PICO\n" +
292                         "  componentFactory=org.picocontainer.behaviors.PropertyApplyingBehaviorFactory\n" +
293                         "    delegate=org.picocontainer.injectors.AdaptiveInjectionFactory\n" +
294                         "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
295                         "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
296                         "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
297                         "PICO",foo);
298        }
299    
300        //TODO - fix up to refer to SomeContainerDependency
301        public void testWithCustomComponentFactory() {
302            MutablePicoContainer mpc = new PicoBuilder().withCustomContainerComponent(new SomeContainerDependency()).withComponentFactory(CustomComponentFactory.class).build();
303            String foo = simplifyRepresentation(mpc);
304            assertEquals("PICO\n" +
305                         "  componentFactory=org.picocontainer.PicoBuilderTestCase_CustomComponentFactory\n" +
306                         "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
307                         "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
308                         "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
309                         "PICO",foo);
310        }
311    
312        public static class SomeContainerDependency {
313        }
314        public static class CustomComponentFactory implements ComponentFactory {
315    
316            @SuppressWarnings({ "UnusedDeclaration" })
317            public CustomComponentFactory(SomeContainerDependency someDependency) {
318            }
319    
320            public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor,
321                                                           LifecycleStrategy lifecycleStrategy,
322                                                           Properties componentProperties,
323                                                           Object componentKey,
324                                                           Class componentImplementation,
325                                                           Parameter... parameters) throws PicoCompositionException {
326                return null;
327            }
328        }
329    
330    
331        public void testWithCustomPicoContainer() {
332            MutablePicoContainer mpc = new PicoBuilder().implementedBy(TestPicoContainer.class).build();
333            String foo = simplifyRepresentation(mpc);
334            assertEquals("org.picocontainer.PicoBuilderTestCase_-TestPicoContainer\n" +
335                    "  componentFactory=org.picocontainer.injectors.AdaptiveInjectionFactory\n" +
336                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
337                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
338                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
339                    "org.picocontainer.PicoBuilderTestCase_-TestPicoContainer",foo);
340        }
341    
342    
343        public static class TestPicoContainer extends DefaultPicoContainer {
344            public TestPicoContainer(ComponentFactory componentFactory, ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, PicoContainer parent) {
345                super(componentFactory, lifecycleStrategy, parent, monitor);
346            }
347        }
348    
349    
350        private String simplifyRepresentation(MutablePicoContainer mpc) {
351            String foo = xs.toXML(mpc);
352            foo = foo.replace('$','_');
353            foo = foo.replaceAll("/>","");
354            foo = foo.replaceAll("</","");
355            foo = foo.replaceAll("<","");
356            foo = foo.replaceAll(">","");
357            foo = foo.replaceAll("\n  startedComponentAdapters","");
358            foo = foo.replaceAll("\n  childrenStarted","");
359            foo = foo.replaceAll("\n  componentAdapters","");
360            foo = foo.replaceAll("\n  orderedComponentAdapters","");
361            foo = foo.replaceAll("\n  started","");
362            foo = foo.replaceAll("\n  disposed","");
363            foo = foo.replaceAll("\n  handler","");
364            foo = foo.replaceAll("\n  children","");
365            foo = foo.replaceAll("\n  lifecycleStrategy\n","\n");
366            foo = foo.replaceAll("\n  componentMonitor\n","\n");
367            foo = foo.replaceAll("\n    componentMonitor\n","\n");
368            foo = foo.replaceAll("\n  delegate\n","\n");
369            foo = foo.replaceAll("\n    delegate\n","\n");
370            foo = foo.replaceAll("\n      delegate\n","\n");
371            foo = foo.replaceAll("\n  componentCharacteristic class=\"org.picocontainer.DefaultPicoContainer$1\"","");
372            foo = foo.replaceAll("\n  componentProperties","");
373            foo = foo.replaceAll("\n  componentKeyToAdapterCache","");
374            foo = foo.replaceAll("\n    startedComponentAdapters","");
375            foo = foo.replaceAll("\"class=","\"\nclass=");
376            foo = foo.replaceAll("\n  componentFactory\n","\n");
377            foo = foo.replaceAll("\n  lifecycleManager","");
378            foo = foo.replaceAll("class=\"org.picocontainer.DefaultPicoContainer_1\"","");
379            foo = foo.replaceAll("class=","=");
380            foo = foo.replaceAll("\"","");
381            foo = foo.replaceAll(" \n","\n");
382            foo = foo.replaceAll(" =","=");
383            foo = foo.replaceAll("\n\n","\n");
384    
385            return foo;
386        }
387    
388    
389    }