001 package org.picocontainer.script; 002 003 import static org.junit.Assert.assertEquals; 004 import static org.junit.Assert.assertNotNull; 005 import static org.junit.Assert.assertNull; 006 import static org.junit.Assert.assertSame; 007 008 import java.io.ByteArrayInputStream; 009 import java.io.ByteArrayOutputStream; 010 import java.io.IOException; 011 import java.io.ObjectInputStream; 012 import java.io.ObjectOutputStream; 013 import java.io.StringReader; 014 import java.lang.reflect.InvocationTargetException; 015 016 import org.junit.Test; 017 import org.picocontainer.DefaultPicoContainer; 018 import org.picocontainer.MutablePicoContainer; 019 import org.picocontainer.behaviors.Caching; 020 import org.picocontainer.behaviors.Storing; 021 import org.picocontainer.parameters.ComponentParameter; 022 import org.picocontainer.script.testmodel.FredImpl; 023 import org.picocontainer.script.testmodel.ThingThatTakesParamsInConstructor; 024 import org.picocontainer.script.testmodel.Wilma; 025 import org.picocontainer.script.testmodel.WilmaImpl; 026 import org.picocontainer.script.xml.XMLContainerBuilder; 027 028 /** 029 * Test case to prove that the DefaultContainerRecorder can be replaced by use of Storing behaviours. 030 * 031 * @author Konstantin Pribluda 032 * @author Aslak Hellesøy 033 * @author Mauro Talevi 034 */ 035 public class StoringContainerTestCase { 036 037 @Test public void testInvocationsCanBeRecordedAndReplayedOnADifferentContainerInstance() throws Exception { 038 039 // This test case is not testing Storing. Its just testing that a Caching parent does so. 040 DefaultPicoContainer parent = new DefaultPicoContainer(new Caching()); 041 parent.addComponent("fruit", "apple"); 042 parent.addComponent("int", 239); 043 parent.addComponent("thing", 044 ThingThatTakesParamsInConstructor.class, 045 ComponentParameter.DEFAULT, 046 ComponentParameter.DEFAULT); 047 048 Storing storing1 = new Storing(); 049 DefaultPicoContainer child1 = new DefaultPicoContainer(storing1, parent); 050 assertEquals("store should be empty", 0, storing1.getCacheSize()); 051 Object a1 = child1.getComponent("fruit"); 052 assertEquals("store should still be empty: its not used", 0, storing1.getCacheSize()); 053 ThingThatTakesParamsInConstructor a2 = (ThingThatTakesParamsInConstructor) child1.getComponent("thing"); 054 assertEquals("apple", a1); 055 assertEquals("apple239", a2.getValue()); 056 057 // test that we can replay once more 058 Storing storing2 = new Storing(); 059 DefaultPicoContainer child2 = new DefaultPicoContainer(storing2, parent); 060 assertEquals("store should be empty", 0, storing2.getCacheSize()); 061 Object b1 = child2.getComponent("fruit"); 062 assertEquals("store should still be empty: its not used", 0, storing2.getCacheSize()); 063 ThingThatTakesParamsInConstructor b2 = (ThingThatTakesParamsInConstructor) child2.getComponent("thing"); 064 assertEquals("apple", b1); 065 assertEquals("apple239", b2.getValue()); 066 067 assertSame("cache of 'recording' parent container should be caching", a1,b1); 068 assertSame("cache of 'recording' parent container should be caching", a2,b2); 069 } 070 071 @Test public void testRecorderWorksAfterSerialization() throws IOException, ClassNotFoundException, IllegalAccessException, InvocationTargetException { 072 DefaultPicoContainer recorded = new DefaultPicoContainer(new Caching()); 073 recorded.addComponent("fruit", "apple"); 074 DefaultPicoContainer replayed = new DefaultPicoContainer(new Storing(), recorded); 075 DefaultPicoContainer serializedReplayed = (DefaultPicoContainer) serializeAndDeserialize(replayed); 076 assertEquals("apple", serializedReplayed.getComponent("fruit")); 077 } 078 079 private Object serializeAndDeserialize(Object o) throws IOException, ClassNotFoundException { 080 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 081 ObjectOutputStream oos = new ObjectOutputStream(baos); 082 083 oos.writeObject(o); 084 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); 085 086 return ois.readObject(); 087 } 088 089 090 @Test public void scriptedPopulationOfContainerHierarchy() { 091 092 MutablePicoContainer parent = new DefaultPicoContainer(new Caching()); 093 094 // parent has nothing populated in it 095 DefaultPicoContainer child = new DefaultPicoContainer(new Storing(), parent); 096 097 new XMLContainerBuilder(new StringReader("" 098 + "<container>" 099 + " <component-implementation key='wilma' class='"+WilmaImpl.class.getName()+"'/>" 100 + "</container>" 101 ), Thread.currentThread().getContextClassLoader()).populateContainer(child); 102 103 assertNull(child.getComponent("fred")); 104 assertNotNull(child.getComponent("wilma")); 105 106 DefaultPicoContainer grandchild = new DefaultPicoContainer(new Storing(), child); 107 108 new XMLContainerBuilder(new StringReader( 109 "<container>" 110 + " <component-implementation key='fred' class='"+FredImpl.class.getName()+"'>" 111 + " <parameter key='wilma'/>" 112 + " </component-implementation>" 113 + "</container>" 114 ), Thread.currentThread().getContextClassLoader()).populateContainer(grandchild); 115 116 assertNotNull(grandchild.getComponent("fred")); 117 assertNotNull(grandchild.getComponent("wilma")); 118 119 FredImpl fred = (FredImpl)grandchild.getComponent("fred"); 120 Wilma wilma = (Wilma)grandchild.getComponent("wilma"); 121 122 assertSame(wilma, fred.wilma()); 123 } 124 125 }