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 }