001 package org.nanocontainer.reflection; 002 003 import java.io.ByteArrayInputStream; 004 import java.io.ByteArrayOutputStream; 005 import java.io.IOException; 006 import java.io.ObjectInputStream; 007 import java.io.ObjectOutputStream; 008 import java.io.Reader; 009 import java.io.StringReader; 010 import java.lang.reflect.InvocationTargetException; 011 012 import junit.framework.TestCase; 013 014 import org.nanocontainer.integrationkit.ContainerPopulator; 015 import org.nanocontainer.integrationkit.ContainerRecorder; 016 import org.nanocontainer.script.xml.XMLContainerBuilder; 017 import org.nanocontainer.testmodel.FredImpl; 018 import org.nanocontainer.testmodel.ThingThatTakesParamsInConstructor; 019 import org.nanocontainer.testmodel.Wilma; 020 import org.nanocontainer.testmodel.WilmaImpl; 021 import org.picocontainer.MutablePicoContainer; 022 import org.picocontainer.Parameter; 023 import org.picocontainer.defaults.ComponentParameter; 024 import org.picocontainer.defaults.DefaultPicoContainer; 025 026 /** 027 * @author Konstantin Pribluda ( konstantin.pribluda(at)infodesire.com ) 028 * @author Aslak Hellesøy 029 */ 030 public class DefaultContainerRecorderTestCase extends TestCase { 031 public void testInvocationsCanBeRecordedAndReplayedOnADifferentContainerInstance() throws Exception { 032 ContainerRecorder recorder = new DefaultContainerRecorder(new DefaultNanoPicoContainer()); 033 MutablePicoContainer recorded = recorder.getContainerProxy(); 034 035 recorded.registerComponentInstance("fruit", "apple"); 036 recorded.registerComponentInstance("int", new Integer(239)); 037 recorded.registerComponentImplementation("thing", 038 ThingThatTakesParamsInConstructor.class, 039 new Parameter[]{ 040 ComponentParameter.DEFAULT, 041 ComponentParameter.DEFAULT, 042 }); 043 044 MutablePicoContainer slave = new DefaultPicoContainer(); 045 recorder.replay(slave); 046 assertEquals("apple", slave.getComponentInstance("fruit")); 047 assertEquals("apple239", ((ThingThatTakesParamsInConstructor) slave.getComponentInstance("thing")).getValue()); 048 049 // test that we can replay once more 050 MutablePicoContainer anotherSlave = new DefaultPicoContainer(); 051 recorder.replay(anotherSlave); 052 assertEquals("apple", anotherSlave.getComponentInstance("fruit")); 053 assertEquals("apple239", ((ThingThatTakesParamsInConstructor) anotherSlave.getComponentInstance("thing")).getValue()); 054 } 055 056 public void testRecorderWorksAfterSerialization() throws IOException, ClassNotFoundException, IllegalAccessException, InvocationTargetException { 057 ContainerRecorder recorder = new DefaultContainerRecorder(new DefaultPicoContainer()); 058 MutablePicoContainer recorded = recorder.getContainerProxy(); 059 recorded.registerComponentInstance("fruit", "apple"); 060 061 ContainerRecorder serializedRecorder = (ContainerRecorder) serializeAndDeserialize(recorder); 062 MutablePicoContainer slave = new DefaultPicoContainer(); 063 serializedRecorder.replay(slave); 064 assertEquals("apple", slave.getComponentInstance("fruit")); 065 } 066 067 private Object serializeAndDeserialize(Object o) throws IOException, ClassNotFoundException { 068 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 069 ObjectOutputStream oos = new ObjectOutputStream(baos); 070 071 oos.writeObject(o); 072 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); 073 074 return ois.readObject(); 075 } 076 077 078 public void testXMLRecorderHierarchy() throws ClassNotFoundException { 079 MutablePicoContainer parentPrototype = new DefaultPicoContainer(); 080 DefaultContainerRecorder parentRecorder = new DefaultContainerRecorder(parentPrototype); 081 StringReader parentResource = new StringReader("" 082 + "<container>" 083 + " <component-implementation key='wilma' class='"+WilmaImpl.class.getName()+"'/>" 084 + "</container>" 085 ); 086 087 populateXMLContainer(parentRecorder, parentResource); 088 MutablePicoContainer parentContainer = parentRecorder.getContainerProxy(); 089 assertNull(parentContainer.getComponentInstance("fred")); 090 assertNotNull(parentContainer.getComponentInstance("wilma")); 091 092 MutablePicoContainer childPrototype = new DefaultPicoContainer(parentPrototype); 093 DefaultContainerRecorder childRecorder = new DefaultContainerRecorder(childPrototype); 094 StringReader childResource = new StringReader("" 095 + "<container>" 096 + " <component-implementation key='fred' class='"+FredImpl.class.getName()+"'>" 097 + " <parameter key='wilma'/>" 098 + " </component-implementation>" 099 + "</container>" 100 ); 101 populateXMLContainer(childRecorder, childResource); 102 MutablePicoContainer childContainer = childRecorder.getContainerProxy(); 103 assertNotNull(childContainer.getComponentInstance("fred")); 104 assertNotNull(childContainer.getComponentInstance("wilma")); 105 FredImpl fred = (FredImpl)childContainer.getComponentInstance("fred"); 106 Wilma wilma = (Wilma)childContainer.getComponentInstance("wilma"); 107 assertSame(wilma, fred.wilma()); 108 } 109 110 private void populateXMLContainer(ContainerRecorder recorder, Reader resource) { 111 ContainerPopulator populator = new XMLContainerBuilder(resource, Thread.currentThread().getContextClassLoader()); 112 populator.populateContainer(recorder.getContainerProxy()); 113 } 114 }