KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > picocontainer > gems > adapters > HotSwappingComponentAdapterFactoryTestCase


1 package org.picocontainer.gems.adapters;
2
3 import com.thoughtworks.proxy.factory.CglibProxyFactory;
4 import com.thoughtworks.proxy.toys.hotswap.Swappable;
5
6 import org.picocontainer.MutablePicoContainer;
7 import org.picocontainer.defaults.CachingComponentAdapter;
8 import org.picocontainer.defaults.CachingComponentAdapterFactory;
9 import org.picocontainer.defaults.ComponentAdapterFactory;
10 import org.picocontainer.defaults.ConstructorInjectionComponentAdapter;
11 import org.picocontainer.defaults.ConstructorInjectionComponentAdapterFactory;
12 import org.picocontainer.defaults.DefaultComponentAdapterFactory;
13 import org.picocontainer.defaults.DefaultPicoContainer;
14 import org.picocontainer.tck.AbstractComponentAdapterFactoryTestCase;
15
16 import java.io.Serializable JavaDoc;
17 import java.util.ArrayList JavaDoc;
18 import java.util.Collection JavaDoc;
19 import java.util.List JavaDoc;
20
21
22 public class HotSwappingComponentAdapterFactoryTestCase extends AbstractComponentAdapterFactoryTestCase {
23     private HotSwappingComponentAdapterFactory implementationHidingComponentAdapterFactory = new HotSwappingComponentAdapterFactory(
24             new DefaultComponentAdapterFactory());
25     private CachingComponentAdapterFactory cachingComponentAdapterFactory = new CachingComponentAdapterFactory(
26             implementationHidingComponentAdapterFactory);
27
28     public void testComponentRegisteredWithInterfaceKeyOnlyImplementsThatInterfaceUsingStandardProxyfactory() {
29         DefaultPicoContainer pico = new DefaultPicoContainer(new HotSwappingComponentAdapterFactory(
30                 new ConstructorInjectionComponentAdapterFactory()));
31         pico.registerComponentImplementation(Collection JavaDoc.class, ArrayList JavaDoc.class);
32         Object JavaDoc collection = pico.getComponentInstance(Collection JavaDoc.class);
33         assertTrue(collection instanceof Collection JavaDoc);
34         assertFalse(collection instanceof List JavaDoc);
35         assertFalse(collection instanceof ArrayList JavaDoc);
36     }
37
38     public void testComponentRegisteredWithOtherKeyImplementsAllInterfacesUsingStandardProxyFactory() {
39         DefaultPicoContainer pico = new DefaultPicoContainer(new HotSwappingComponentAdapterFactory(
40                 new ConstructorInjectionComponentAdapterFactory()));
41         pico.registerComponentImplementation("list", ArrayList JavaDoc.class);
42         Object JavaDoc collection = pico.getComponentInstance("list");
43         assertTrue(collection instanceof List JavaDoc);
44         assertFalse(collection instanceof ArrayList JavaDoc);
45     }
46
47     public void testComponentRegisteredWithInterfaceKeyOnlyImplementsThatInterfaceUsingCGLIBProxyfactory() {
48         DefaultPicoContainer pico = new DefaultPicoContainer(new HotSwappingComponentAdapterFactory(
49                 new ConstructorInjectionComponentAdapterFactory(), new CglibProxyFactory()));
50         pico.registerComponentImplementation(Collection JavaDoc.class, ArrayList JavaDoc.class);
51         Object JavaDoc collection = pico.getComponentInstance(Collection JavaDoc.class);
52         assertTrue(collection instanceof Collection JavaDoc);
53         assertFalse(collection instanceof List JavaDoc);
54         assertFalse(collection instanceof ArrayList JavaDoc);
55     }
56
57     public void testComponentRegisteredWithOtherKeyImplementsAllInterfacesUsingCGLIBProxyFactory() {
58         DefaultPicoContainer pico = new DefaultPicoContainer(new HotSwappingComponentAdapterFactory(
59                 new ConstructorInjectionComponentAdapterFactory(), new CglibProxyFactory()));
60         pico.registerComponentImplementation("list", ArrayList JavaDoc.class);
61         Object JavaDoc collection = pico.getComponentInstance("list");
62         assertTrue(collection instanceof Collection JavaDoc);
63         assertTrue(collection instanceof List JavaDoc);
64         assertTrue(collection instanceof ArrayList JavaDoc);
65         assertTrue(collection.getClass().getSuperclass().equals(ArrayList JavaDoc.class));
66     }
67
68     // START SNIPPET: man
69
public static interface Man {
70         Woman getWoman();
71
72         void kiss();
73
74         boolean wasKissed();
75     }
76
77     // END SNIPPET: man
78

79     // START SNIPPET: woman
80
public static interface Woman {
81         Man getMan();
82     }
83
84     // END SNIPPET: woman
85

86     public static interface SuperWoman extends Woman {
87     }
88
89     public static class Husband implements Man {
90         public final Woman partner;
91         private boolean wasKissed;
92
93         public Husband(Woman partner) {
94             this.partner = partner;
95         }
96
97         public Woman getWoman() {
98             return partner;
99         }
100
101         public void kiss() {
102             wasKissed = true;
103         }
104
105         public boolean wasKissed() {
106             return wasKissed;
107         }
108     }
109
110     public static class Wife implements SuperWoman {
111         public final Man partner;
112
113         public Wife(Man partner) {
114             this.partner = partner;
115         }
116
117         public Man getMan() {
118             return partner;
119         }
120     }
121
122     public void testLowLevelCheating() {
123         ComponentAdapterFactory caf = createComponentAdapterFactory();
124         DefaultPicoContainer pico = new DefaultPicoContainer(caf);
125
126         CachingComponentAdapter wifeAdapter = (CachingComponentAdapter)caf.createComponentAdapter("wife", Wife.class, null);
127         CachingComponentAdapter husbandAdapter = (CachingComponentAdapter)caf
128                 .createComponentAdapter("husband", Husband.class, null);
129
130         pico.registerComponent(wifeAdapter);
131         pico.registerComponent(husbandAdapter);
132
133         Woman wife = (Woman)wifeAdapter.getComponentInstance(pico);
134         Man wifesMan = wife.getMan();
135         wifesMan.kiss();
136         Man man = (Man)husbandAdapter.getComponentInstance(pico);
137         assertTrue(man.wasKissed());
138
139         assertSame(man, wife.getMan());
140         assertSame(wife, man.getWoman());
141
142         // Let the wife use another (single) man
143
Man newMan = new Husband(null);
144         Man oldMan = (Man)((Swappable)man).hotswap(newMan);
145
146         wife.getMan().kiss();
147         assertTrue(newMan.wasKissed());
148         assertNotSame(man, oldMan);
149         assertNotSame(oldMan, newMan);
150         assertNotSame(newMan, man);
151
152         assertFalse(man.hashCode() == oldMan.hashCode());
153         assertFalse(oldMan.hashCode() == newMan.hashCode());
154         // TODO: Enable for proxytoys-0.2 final
155
// assertTrue(newMan.hashCode() == man.hashCode());
156
}
157
158
159     public void testTheThingThatPaulDoesNotLikeAboutTheCurrentHotSwapper() {
160         DefaultPicoContainer pico = new DefaultPicoContainer(new HotSwappingComponentAdapterFactory());
161
162         HotSwappingComponentAdapter ca = (HotSwappingComponentAdapter) pico.registerComponentImplementation(List JavaDoc.class, ArrayList JavaDoc.class);
163
164         List JavaDoc list = (List JavaDoc) pico.getComponentInstanceOfType(List JavaDoc.class);
165
166         // I do not like that I can cast the object to something that is mutable beyond the scope
167
// of its design (list functions)
168
List JavaDoc list2 = (List JavaDoc) ((Swappable) list).hotswap(new ArrayList JavaDoc());
169
170         MutablePicoContainer child = pico.makeChildContainer();
171         child.registerComponentImplementation(ExposesListMember.class, ExposesListMemberImpl.class);
172         Object JavaDoc componentInstance = child.getComponentInstanceOfType(ExposesListMember.class);
173         ExposesListMember exposer = (ExposesListMember) componentInstance;
174
175         // still mutable for children :-(
176
List JavaDoc list3 = (List JavaDoc) ((Swappable) exposer.getList()).hotswap(new ArrayList JavaDoc());
177
178         // what I really want ...
179
//ca.swapInstance(...);
180
}
181
182     public static interface ExposesListMember {
183         List JavaDoc getList();
184     }
185
186     public static class ExposesListMemberImpl implements ExposesListMember {
187         private final List JavaDoc list;
188
189         public ExposesListMemberImpl(List JavaDoc l) {
190             list = l;
191         }
192
193         public List JavaDoc getList() {
194             return list;
195         }
196
197     }
198
199
200     public void testHighLevelCheating() {
201         MutablePicoContainer pico = new DefaultPicoContainer(createComponentAdapterFactory());
202
203         // Register two classes with mutual dependencies in the constructor (!!!)
204
pico.registerComponentImplementation(Wife.class);
205         pico.registerComponentImplementation(Husband.class);
206
207         Woman wife = (Woman)pico.getComponentInstance(Wife.class);
208         Man man = (Man)pico.getComponentInstance(Husband.class);
209
210         assertSame(man, wife.getMan());
211         assertSame(wife, man.getWoman());
212
213         // Let the wife use another (single) man
214
Man newMan = new Husband(null);
215         Man oldMan = (Man)((Swappable)man).hotswap(newMan);
216
217         wife.getMan().kiss();
218         assertFalse(oldMan.wasKissed());
219         assertTrue(newMan.wasKissed());
220
221     }
222
223     public void testBigamy() {
224         DefaultPicoContainer pico = new DefaultPicoContainer(new HotSwappingComponentAdapterFactory(
225                 new ConstructorInjectionComponentAdapterFactory()));
226         pico.registerComponentImplementation(Woman.class, Wife.class);
227         Woman firstWife = (Woman)pico.getComponentInstance(Woman.class);
228         Woman secondWife = (Woman)pico.getComponentInstance(Woman.class);
229         assertNotSame(firstWife, secondWife);
230
231     }
232
233     public static class Bad implements Serializable JavaDoc {
234         public Bad() {
235             throw new IllegalStateException JavaDoc("HAHA");
236         }
237     }
238
239     public void testIHCAFwithCTORandNoCaching() {
240         // http://lists.codehaus.org/pipermail/picocontainer-dev/2004-January/001985.html
241
MutablePicoContainer pico = new DefaultPicoContainer();
242         pico.registerComponent(new HotSwappingComponentAdapter(new ConstructorInjectionComponentAdapter("l", ArrayList JavaDoc.class)));
243
244         List JavaDoc list1 = (List JavaDoc)pico.getComponentInstance("l");
245         List JavaDoc list2 = (List JavaDoc)pico.getComponentInstance("l");
246
247         assertNotSame(list1, list2);
248         assertFalse(list1 instanceof ArrayList JavaDoc);
249
250         list1.add("Hello");
251         assertTrue(list1.contains("Hello"));
252         assertFalse(list2.contains("Hello"));
253     }
254
255     public void testSwappingViaSwappableInterface() {
256         MutablePicoContainer pico = new DefaultPicoContainer();
257         pico.registerComponent(new HotSwappingComponentAdapter(new ConstructorInjectionComponentAdapter("l", ArrayList JavaDoc.class)));
258         List JavaDoc l = (List JavaDoc)pico.getComponentInstance("l");
259         l.add("Hello");
260         final ArrayList JavaDoc newList = new ArrayList JavaDoc();
261         ArrayList JavaDoc oldSubject = (ArrayList JavaDoc)((Swappable)l).hotswap(newList);
262         assertEquals("Hello", oldSubject.get(0));
263         assertTrue(l.isEmpty());
264         l.add("World");
265         assertEquals("World", l.get(0));
266     }
267
268     public interface OtherSwappable {
269         Object JavaDoc hotswap(Object JavaDoc newSubject);
270     }
271
272     public static class OtherSwappableImpl implements OtherSwappable {
273         public Object JavaDoc hotswap(Object JavaDoc newSubject) {
274             return "TADA";
275         }
276     }
277
278     public void testInterferingSwapMethodsInComponentMasksHotSwappingFunctionality() {
279         MutablePicoContainer pico = new DefaultPicoContainer();
280         pico.registerComponent(new HotSwappingComponentAdapter(new ConstructorInjectionComponentAdapter(
281                 "os", OtherSwappableImpl.class)));
282         OtherSwappable os = (OtherSwappable)pico.getComponentInstance("os");
283         OtherSwappable os2 = new OtherSwappableImpl();
284
285         assertEquals("TADA", os.hotswap(os2));
286         Swappable os_ = (Swappable)os;
287         assertEquals("TADA", os_.hotswap(os2));
288     }
289
290     protected ComponentAdapterFactory createComponentAdapterFactory() {
291         return cachingComponentAdapterFactory;
292     }
293
294     public static class Yin {
295         private final Yang yang;
296
297         public Yin(Yang yang) {
298             this.yang = yang;
299         }
300
301         public Yang getYang() {
302             return yang;
303         }
304     }
305
306     public static class Yang {
307         private final Yin yin;
308
309         public Yang(Yin yin) {
310             this.yin = yin;
311         }
312
313         public Yin getYin() {
314             return yin;
315         }
316     }
317
318     // TODO: Fails with versions of cglib >= 2.0.1
319
public void testShouldBeAbleToHandleMutualDependenciesWithoutInterfaceImplSeparation() {
320         MutablePicoContainer pico = new DefaultPicoContainer(new CachingComponentAdapterFactory(
321                 new HotSwappingComponentAdapterFactory(new ConstructorInjectionComponentAdapterFactory(), new CglibProxyFactory())));
322
323         pico.registerComponentImplementation(Yin.class);
324         pico.registerComponentImplementation(Yang.class);
325
326         Yin yin = (Yin)pico.getComponentInstance(Yin.class);
327         Yang yang = (Yang)pico.getComponentInstance(Yang.class);
328
329         assertSame(yin, yang.getYin());
330         assertSame(yang, yin.getYang());
331     }
332
333 }
334
Popular Tags