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 public 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());
044 assertNotNull(map);
045 Map map2 = (Map)ca.getComponentInstance(new EmptyPicoContainer());
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());
057 assertNotNull(map);
058 Map map2 = (Map)ca.getComponentInstance(new EmptyPicoContainer());
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());
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());
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());
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());
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());
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-interface 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 }