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.implementationHiding;
014    import static org.picocontainer.behaviors.Behaviors.synchronizing;
015    import org.picocontainer.behaviors.ImplementationHiding;
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.AdaptiveInjection\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.AdaptiveInjection\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.AdaptiveInjection\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.AdaptiveInjection\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.AdaptiveInjection\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.AdaptiveInjection\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.ImplementationHiding\n" +
159                    "    delegate=org.picocontainer.injectors.AdaptiveInjection\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 ImplementationHiding()).build();
168            String foo = simplifyRepresentation(mpc);
169            assertEquals("PICO\n" +
170                    "  componentFactory=org.picocontainer.behaviors.ImplementationHiding\n" +
171                    "    delegate=org.picocontainer.injectors.AdaptiveInjection\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(), synchronizing(), implementationHiding()).build();
180            String foo = simplifyRepresentation(mpc);
181            assertEquals("PICO\n" +
182                    "  componentFactory=org.picocontainer.behaviors.Caching\n" +
183                    "    delegate=org.picocontainer.behaviors.Synchronizing\n" +
184                    "      delegate=org.picocontainer.behaviors.ImplementationHiding\n" +
185                    "        delegate=org.picocontainer.injectors.SetterInjection\n" +
186                    "          set\n" +
187                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
188                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
189                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
190                    "PICO",foo);
191        }
192    
193    
194        public static class CustomParentcontainer extends EmptyPicoContainer {}
195    
196        public void testWithCustomParentContainer() {
197            MutablePicoContainer mpc = new PicoBuilder(new CustomParentcontainer()).build();
198            String foo = simplifyRepresentation(mpc);
199            assertEquals("PICO\n" +
200                    "  componentFactory=org.picocontainer.injectors.AdaptiveInjection\n" +
201                    "  parent=org.picocontainer.PicoBuilderTestCase_CustomParentcontainer\n" +
202                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
203                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
204                    "PICO",foo);
205        }
206    
207        public void testWithBogusParentContainerBehavesAsIfNotSet() {
208            MutablePicoContainer mpc = new PicoBuilder((PicoContainer)null).build();
209            String foo = simplifyRepresentation(mpc);
210            assertEquals("PICO\n" +
211                         "  componentFactory=org.picocontainer.injectors.AdaptiveInjection\n" +
212                         "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
213                         "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
214                         "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
215                         "PICO", foo);
216        }
217    
218    
219        public void testWithSetterDI() {
220            MutablePicoContainer mpc = new PicoBuilder().withSetterInjection().build();
221            String foo = simplifyRepresentation(mpc);
222            assertEquals("PICO\n" +
223                    "  componentFactory=org.picocontainer.injectors.SetterInjection\n" +
224                    "    set\n" +
225                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
226                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
227                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
228                    "PICO",foo);
229        }
230    
231        public void testWithAnnotatedMethodDI() {
232                MutablePicoContainer mpc = new PicoBuilder().withAnnotatedMethodInjection().build();
233            String foo = simplifyRepresentation(mpc);
234            assertEquals("PICO\n" +
235                    "  componentFactory=org.picocontainer.injectors.AnnotatedMethodInjection\n" +
236                    "    org.picocontainer.annotations.Inject\n" +
237                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
238                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
239                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
240                    "PICO",foo);
241        }
242    
243        public void testWithAnnotatedFieldDI() {
244                MutablePicoContainer mpc = new PicoBuilder().withAnnotatedFieldInjection().build();
245            String foo = simplifyRepresentation(mpc);
246            assertEquals("PICO\n" +
247                    "  componentFactory=org.picocontainer.injectors.AnnotatedFieldInjection\n" +
248                    "    org.picocontainer.annotations.Inject\n" +
249                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
250                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
251                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
252                    "PICO",foo);
253        }
254    
255        public void testWithCtorDI() {
256            MutablePicoContainer mpc = new PicoBuilder().withConstructorInjection().build();
257            String foo = simplifyRepresentation(mpc);
258            assertEquals("PICO\n" +
259                    "  componentFactory=org.picocontainer.injectors.ConstructorInjection\n" +
260                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
261                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
262                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
263                    "PICO",foo);
264        }
265    
266        public void testWithImplementationHidingAndSetterDI() {
267            MutablePicoContainer mpc = new PicoBuilder().withHiddenImplementations().withSetterInjection().build();
268            String foo = simplifyRepresentation(mpc);
269            assertEquals("PICO\n" +
270                    "  componentFactory=org.picocontainer.behaviors.ImplementationHiding\n" +
271                    "    delegate=org.picocontainer.injectors.SetterInjection\n" +
272                    "      set\n" +
273                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
274                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
275                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
276                    "PICO",foo);
277        }
278    
279        public void testWithCachingImplementationHidingAndSetterDI() {
280            MutablePicoContainer mpc = new PicoBuilder().withCaching().withHiddenImplementations().withSetterInjection().build();
281            String foo = simplifyRepresentation(mpc);
282            assertEquals("PICO\n" +
283                    "  componentFactory=org.picocontainer.behaviors.Caching\n" +
284                    "    delegate=org.picocontainer.behaviors.ImplementationHiding\n" +
285                    "      delegate=org.picocontainer.injectors.SetterInjection\n" +
286                    "        set\n" +                
287                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
288                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
289                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
290                    "PICO",foo);
291        }
292    
293        public void testWithSynchronizing() {
294            MutablePicoContainer mpc = new PicoBuilder().withSynchronizing().build();
295            String foo = simplifyRepresentation(mpc);
296            assertEquals("PICO\n" +
297                    "  componentFactory=org.picocontainer.behaviors.Synchronizing\n" +
298                    "    delegate=org.picocontainer.injectors.AdaptiveInjection\n" +
299                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
300                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
301                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
302                    "PICO",foo);
303        }
304    
305        public void testWithLocking() {
306            MutablePicoContainer mpc = new PicoBuilder().withLocking().build();
307            String foo = simplifyRepresentation(mpc);
308            assertEquals("PICO\n" +
309                    "  componentFactory=org.picocontainer.behaviors.Locking\n" +
310                    "    delegate=org.picocontainer.injectors.AdaptiveInjection\n" +
311                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
312                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
313                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
314                    "PICO",foo);
315        }
316    
317        public void testWithPropertyApplier() {
318            MutablePicoContainer mpc = new PicoBuilder().withPropertyApplier().build();
319            String foo = simplifyRepresentation(mpc);
320            assertEquals("PICO\n" +
321                         "  componentFactory=org.picocontainer.behaviors.PropertyApplying\n" +
322                         "    delegate=org.picocontainer.injectors.AdaptiveInjection\n" +
323                         "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
324                         "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
325                         "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
326                         "PICO",foo);
327        }
328    
329        //TODO - fix up to refer to SomeContainerDependency
330        public void testWithCustomComponentFactory() {
331            MutablePicoContainer mpc = new PicoBuilder().withCustomContainerComponent(new SomeContainerDependency()).withComponentFactory(CustomComponentFactory.class).build();
332            String foo = simplifyRepresentation(mpc);
333            assertEquals("PICO\n" +
334                         "  componentFactory=org.picocontainer.PicoBuilderTestCase_CustomComponentFactory\n" +
335                         "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
336                         "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
337                         "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
338                         "PICO",foo);
339        }
340    
341        public static class SomeContainerDependency {
342        }
343        public static class CustomComponentFactory implements ComponentFactory {
344    
345            @SuppressWarnings({ "UnusedDeclaration" })
346            public CustomComponentFactory(SomeContainerDependency someDependency) {
347            }
348    
349            public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor,
350                                                           LifecycleStrategy lifecycleStrategy,
351                                                           Properties componentProperties,
352                                                           Object componentKey,
353                                                           Class componentImplementation,
354                                                           Parameter... parameters) throws PicoCompositionException {
355                return null;
356            }
357        }
358    
359    
360        public void testWithCustomPicoContainer() {
361            MutablePicoContainer mpc = new PicoBuilder().implementedBy(TestPicoContainer.class).build();
362            String foo = simplifyRepresentation(mpc);
363            assertEquals("org.picocontainer.PicoBuilderTestCase_-TestPicoContainer\n" +
364                    "  componentFactory=org.picocontainer.injectors.AdaptiveInjection\n" +
365                    "  parent=org.picocontainer.containers.EmptyPicoContainer\n" +
366                    "  lifecycleStrategy=org.picocontainer.lifecycle.NullLifecycleStrategy\n" +
367                    "  componentMonitor=org.picocontainer.monitors.NullComponentMonitor\n" +
368                    "org.picocontainer.PicoBuilderTestCase_-TestPicoContainer",foo);
369        }
370    
371    
372        public static class TestPicoContainer extends DefaultPicoContainer {
373            public TestPicoContainer(ComponentFactory componentFactory, ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, PicoContainer parent) {
374                super(componentFactory, lifecycleStrategy, parent, monitor);
375            }
376        }
377    
378    
379        private String simplifyRepresentation(MutablePicoContainer mpc) {
380            String foo = xs.toXML(mpc);
381            foo = foo.replace('$','_');
382            foo = foo.replaceAll("/>","");
383            foo = foo.replaceAll("</","");
384            foo = foo.replaceAll("<","");
385            foo = foo.replaceAll(">","");
386            foo = foo.replaceAll("\n  startedComponentAdapters","");
387            foo = foo.replaceAll("\n  componentKeyToAdapterCache","");
388            foo = foo.replaceAll("\n  componentAdapters","");
389            foo = foo.replaceAll("\n  orderedComponentAdapters","");
390            foo = foo.replaceAll("\n  childrenStarted","");
391            foo = foo.replaceAll("\n  started","");
392            foo = foo.replaceAll("\n  disposed","");
393            foo = foo.replaceAll("\n  handler","");
394            foo = foo.replaceAll("\n  children","");
395            foo = foo.replaceAll("injectionAnnotation","");
396            foo = foo.replaceAll("setterMethodPrefix","");
397            foo = foo.replaceAll("\n  lifecycleStrategy\n","\n");
398            foo = foo.replaceAll("\n  componentMonitor\n","\n");
399            foo = foo.replaceAll("\n    componentMonitor\n","\n");
400            foo = foo.replaceAll("\n  delegate\n","\n");
401            foo = foo.replaceAll("\n    delegate\n","\n");
402            foo = foo.replaceAll("\n      delegate\n","\n");
403            foo = foo.replaceAll("\n        delegate\n","\n");
404            foo = foo.replaceAll("\n  componentCharacteristic class=\"org.picocontainer.DefaultPicoContainer$1\"","");
405            foo = foo.replaceAll("\n  componentProperties","");
406            foo = foo.replaceAll("\n    startedComponentAdapters","");
407            foo = foo.replaceAll("\"class=","\"\nclass=");
408            foo = foo.replaceAll("\n  componentFactory\n","\n");
409            foo = foo.replaceAll("\n  lifecycleManager","");
410            foo = foo.replaceAll("class=\"org.picocontainer.DefaultPicoContainer_1\"","");
411            foo = foo.replaceAll("class=","=");
412            foo = foo.replaceAll("\"","");
413            foo = foo.replaceAll(" \n","\n");
414            foo = foo.replaceAll(" =","=");
415            foo = foo.replaceAll("\n\n","\n");
416    
417            return foo;
418        }
419    
420    
421    }