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