    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&oslash;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    }