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