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 }