    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.behaviors;
    011
    012    import static org.junit.Assert.assertEquals;
    013    import static org.junit.Assert.assertFalse;
    014    import static org.junit.Assert.assertNotNull;
    015    import static org.junit.Assert.assertSame;
    016    import static org.junit.Assert.assertTrue;
    017
    018    import java.util.Enumeration;
    019    import java.util.HashMap;
    020    import java.util.Map;
    021    import java.util.Properties;
    022
    023    import org.junit.Test;
    024    import org.picocontainer.Characteristics;
    025    import org.picocontainer.ComponentAdapter;
    026    import org.picocontainer.adapters.InstanceAdapter;
    027    import org.picocontainer.annotations.Cache;
    028    import org.picocontainer.containers.EmptyPicoContainer;
    029    import org.picocontainer.injectors.SetterInjector;
    030    import org.picocontainer.lifecycle.NullLifecycleStrategy;
    031    import org.picocontainer.monitors.NullComponentMonitor;
    032
    033    import com.thoughtworks.xstream.XStream;
    034
    035    @SuppressWarnings("serial")
    036    public class AdaptingBehaviorTestCase {
    037
    038        @Test public void testCachingBehaviorCanBeAddedByCharacteristics() {
    039            AdaptingBehavior abf = new AdaptingBehavior();
    040            Properties cc = new Properties();
    041            mergeInto(Characteristics.CACHE,cc);
    042            ComponentAdapter ca = abf.createComponentAdapter(new NullComponentMonitor(), new NullLifecycleStrategy(), cc, Map.class, HashMap.class);
    043            assertTrue(ca instanceof Cached);
    044            Map map = (Map)ca.getComponentInstance(new EmptyPicoContainer(), ComponentAdapter.NOTHING.class);
    045            assertNotNull(map);
    046            Map map2 = (Map)ca.getComponentInstance(new EmptyPicoContainer(), ComponentAdapter.NOTHING.class);
    047            assertSame(map, map2);
    048            assertEquals(0, cc.size());
    049            assertEquals("Cached:ConstructorInjector-interface java.util.Map",ca.toString());
    050        }
    051
    052        @Test public void testCachingBehaviorCanBeAddedByAnnotation() {
    053            AdaptingBehavior abf = new AdaptingBehavior();
    054            Properties cc = new Properties();
    055            ComponentAdapter ca = abf.createComponentAdapter(new NullComponentMonitor(), new NullLifecycleStrategy(), cc, Map.class, MyHashMap.class);
    056            assertTrue(ca instanceof Cached);
    057            Map map = (Map)ca.getComponentInstance(new EmptyPicoContainer(), ComponentAdapter.NOTHING.class);
    058            assertNotNull(map);
    059            Map map2 = (Map)ca.getComponentInstance(new EmptyPicoContainer(), ComponentAdapter.NOTHING.class);
    060            assertSame(map, map2);
    061            assertEquals(0, cc.size());
    062            assertEquals("Cached:ConstructorInjector-interface java.util.Map",ca.toString());
    063        }
    064
    065        @Cache
    066        public static class MyHashMap extends HashMap {
    067            public MyHashMap() {
    068            }
    069        }
    070
    071        public static class MyHashMap2 extends HashMap {
    072            private String foo;
    073
    074            public MyHashMap2() {
    075            }
    076            public void setFoo(String foo) {
    077                this.foo = foo;
    078            }
    079        }
    080
    081        @Test public void testImplementationHidingBehaviorCanBeAddedByCharacteristics() {
    082            AdaptingBehavior abf = new AdaptingBehavior();
    083            Properties cc = new Properties();
    084            mergeInto(Characteristics.HIDE_IMPL,cc);
    085            ComponentAdapter ca = abf.createComponentAdapter(new NullComponentMonitor(), new NullLifecycleStrategy(), cc, Map.class, HashMap.class);
    086            assertTrue(ca instanceof HiddenImplementation);
    087            Map map = (Map)ca.getComponentInstance(new EmptyPicoContainer(), ComponentAdapter.NOTHING.class);
    088            assertNotNull(map);
    089            assertTrue(!(map instanceof HashMap));
    090
    091            assertEquals(0, cc.size());
    092            assertEquals("Hidden:ConstructorInjector-interface java.util.Map",ca.toString());
    093
    094        }
    095
    096        @Test public void testPropertyApplyingBehaviorCanBeAddedByCharacteristics() {
    097            AdaptingBehavior abf = new AdaptingBehavior();
    098            Properties cc = new Properties();
    099            mergeInto(Characteristics.PROPERTY_APPLYING,cc);
    100            ComponentAdapter ca = abf.createComponentAdapter(new NullComponentMonitor(), new NullLifecycleStrategy(), cc, Map.class, MyHashMap2.class);
    101            assertTrue(ca instanceof PropertyApplicator);
    102            PropertyApplicator pa = (PropertyApplicator)ca;
    103            pa.setProperty("foo", "bar");
    104            Map map = (Map)ca.getComponentInstance(new EmptyPicoContainer(), ComponentAdapter.NOTHING.class);
    105            assertNotNull(map);
    106            assertTrue(map instanceof HashMap);
    107            assertTrue(map instanceof MyHashMap2);
    108            assertEquals("bar", ((MyHashMap2) map).foo);
    109
    110            assertEquals(0, cc.size());
    111            assertEquals("PropertyApplied:ConstructorInjector-interface java.util.Map",ca.toString());
    112
    113        }
    114
    115        @Test public void testSetterInjectionCanBeTriggereedMeaningAdaptiveInjectorIsUsed() {
    116            AdaptingBehavior abf = new AdaptingBehavior();
    117            Properties cc = new Properties();
    118            mergeInto(Characteristics.SDI,cc);
    119            ComponentAdapter ca = abf.createComponentAdapter(new NullComponentMonitor(), new NullLifecycleStrategy(), cc, Map.class, HashMap.class);
    120            assertTrue(ca instanceof SetterInjector);
    121            Map map = (Map)ca.getComponentInstance(new EmptyPicoContainer(), ComponentAdapter.NOTHING.class);
    122            assertNotNull(map);
    123            assertEquals(0, cc.size());
    124            assertEquals("SetterInjector-interface java.util.Map",ca.toString());
    125
    126        }
    127
    128        @Test public void testCachingAndImplHidingAndThreadSafetySetupCorrectly() {
    129            AdaptingBehavior abf = new AdaptingBehavior();
    130            Properties cc = new Properties();
    131            mergeInto(Characteristics.CACHE,cc);
    132            mergeInto(Characteristics.HIDE_IMPL,cc);
    133            mergeInto(Characteristics.SYNCHRONIZE,cc);
    134            ComponentAdapter ca = abf.createComponentAdapter(new NullComponentMonitor(), new NullLifecycleStrategy(), cc, Map.class, HashMap.class);
    135            assertTrue(ca instanceof Cached);
    136            Map map = (Map)ca.getComponentInstance(new EmptyPicoContainer(), null);
    137            assertNotNull(map);
    138            assertTrue(!(map instanceof HashMap));
    139
    140            XStream xs = new XStream();
    141            String foo = xs.toXML(ca);
    142
    143            int ih = foo.indexOf(HiddenImplementation.class.getName());
    144            int sb = foo.indexOf(Synchronized.class.getName());
    145
    146            // check right nesting order
    147            assertTrue(ih>0);
    148            assertTrue(sb>0);
    149            assertTrue(sb>ih);
    150
    151            assertEquals(0, cc.size());
    152            assertEquals("Cached:Hidden:Synchronized:ConstructorInjector-interface java.util.Map",ca.toString());
    153
    154
    155
    156
    157        }
    158
    159        @Test public void testCachingAndImplHidingAndThreadSafetySetupCorrectlyForExtraCaching() {
    160            Caching cbf = new Caching();
    161            AdaptingBehavior abf = new AdaptingBehavior();
    162            cbf.wrap(abf);
    163            Properties cc = new Properties();
    164            mergeInto(Characteristics.CACHE,cc);
    165            mergeInto(Characteristics.HIDE_IMPL,cc);
    166            mergeInto(Characteristics.SYNCHRONIZE,cc);
    167            ComponentAdapter ca = cbf.createComponentAdapter(new NullComponentMonitor(), new NullLifecycleStrategy(), cc, Map.class, HashMap.class);
    168            assertTrue(ca instanceof Cached);
    169            Map map = (Map)ca.getComponentInstance(new EmptyPicoContainer(), ComponentAdapter.NOTHING.class);
    170            assertNotNull(map);
    171            assertTrue(!(map instanceof HashMap));
    172
    173            XStream xs = new XStream();
    174            String foo = xs.toXML(ca);
    175
    176            assertTrue(foo.indexOf("<" + Cached.class.getName() + ">", 0)  > -1);  // xml does start with CB
    177            assertFalse(foo.indexOf("<" + Cached.class.getName() + ">", 1)  > -1); // but only contains it once.
    178            assertEquals("Cached:Hidden:Synchronized:ConstructorInjector-interface java.util.Map",ca.toString());
    179
    180        }
    181
    182        @Test public void testCachingAndImplHidingAndThreadSafetySetupCorrectlyForExtraCachingForAdapter() {
    183            Caching cbf = new Caching();
    184            AdaptingBehavior abf = new AdaptingBehavior();
    185            cbf.wrap(abf);
    186            Properties cc = new Properties();
    187            mergeInto(Characteristics.CACHE,cc);
    188            mergeInto(Characteristics.HIDE_IMPL,cc);
    189            mergeInto(Characteristics.SYNCHRONIZE,cc);
    190            ComponentAdapter ca = cbf.addComponentAdapter(new NullComponentMonitor(), new NullLifecycleStrategy(), cc, new InstanceAdapter(Map.class, new HashMap(), new NullLifecycleStrategy(), new NullComponentMonitor()));
    191            assertTrue(ca instanceof Cached);
    192            Map map = (Map)ca.getComponentInstance(new EmptyPicoContainer(), ComponentAdapter.NOTHING.class);
    193            assertNotNull(map);
    194            assertTrue(!(map instanceof HashMap));
    195
    196            XStream xs = new XStream();
    197            String foo = xs.toXML(ca);
    198
    199            assertTrue(foo.indexOf("<" + Cached.class.getName() + ">", 0)  > -1);  // xml does start with CB
    200            assertFalse(foo.indexOf("<" + Cached.class.getName() + ">", 1)  > -1); // but only contains it once.
    201            assertEquals("Cached:Hidden:Synchronized:Instance-interface java.util.Map",ca.toString());
    202
    203        }
    204
    205
    206
    207        public void mergeInto(Properties p, Properties into) {
    208            Enumeration e = p.propertyNames();
    209            while (e.hasMoreElements()) {
    210                String s = (String)e.nextElement();
    211                into.setProperty(s, p.getProperty(s));
    212            }
    213
    214        }
    215
    216
    217    }