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