package org.hivedb.versioning; import org.hivedb.serialization.Serializer; import org.hivedb.serialization.XmlXStreamSerializationProvider; import org.hivedb.serialization.XmlXStreamSerializer; import org.hivedb.util.classgen.GenerateInstance; import org.hivedb.util.classgen.ReflectionTools; import org.hivedb.util.functional.Pair; import org.hivedb.util.functional.Transform; import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import java.io.InputStream; import java.util.Arrays; import java.util.Collection; public class TestXmlVersioning { @BeforeClass public void beforeClass() { XmlXStreamSerializationProvider.initialize(Arrays.asList(new Class[] {NewFoo.class}), Transform.toMap((Pair<Class<?>, XmlModernizationPaver<?>>[]) new Pair[] { new Pair<Class<?>, XmlModernizationPaver<?>>(NewFoo.class, new NewFooXmlModernizationPaver(NewFooXmlModernizationPaver.NEW_FOO_XML_VERSION)), new Pair<Class<?>, XmlModernizationPaver<?>>(NewBar.class, new NewBarXmlModernizationPaver(NewFooXmlModernizationPaver.NEW_FOO_XML_VERSION)) })); } @Test public void testBlobVersioning() { OldFoo foo = new GenerateInstance<OldFoo>(OldFoo.class).generate(); NewFoo newFoo = serializeAndDeserializeAsNewFoo(foo); Collection<NewBar> newBars = newFoo.getBars(); // Make sure our deserialized instance notes that it came from the OldFoo version, not the NewFoo version Assert.assertEquals(newFoo.getBlobVersion(), (Integer)0); // We deleted the OrientationId from the new XML version so it shouldn't be deserialized Assert.assertEquals(newFoo.getOrientationId(), null); // We deleted Bar.Border also for (NewBar newBar : newBars) Assert.assertEquals(newBar.getBorder(), null); // We flipped the value of Active Assert.assertEquals(newFoo.getActive(), (Boolean)!foo.getActive()); // We added a new color Assert.assertTrue(newFoo.getColors().contains(71)); // We set a new field in NewFoo Assert.assertEquals(newFoo.getGluttony(), "glutton"); // We also set a new field in NewBar for (NewBar newBar : newBars) Assert.assertEquals(((NewBar)newBar).getShininess(), "shininess"); // Reserialize to upgrade the "stored" version to the NewFoo version // When we deserialize, no modernizer should be called, since it's already at the newest version Serializer<Object, InputStream> newFooSerializer = getNewFooSerializer(); NewFoo deserializedNewFoo = (NewFoo) newFooSerializer.deserialize( newFooSerializer.serialize(newFoo)); // upgrade the version of the original to make them equal newFoo.setBlobVersion(NewFooXmlModernizationPaver.NEW_FOO_XML_VERSION); Assert.assertEquals(deserializedNewFoo, newFoo, ReflectionTools.getDifferingFields(newFoo, deserializedNewFoo, NewFoo.class).toString()); } private NewFoo serializeAndDeserializeAsNewFoo(OldFoo oldFoo) { Serializer<OldFoo,InputStream> productSerializer = getOldFooSerializer(); InputStream xmlInputStream = productSerializer.serialize(oldFoo); Serializer<Object,InputStream> newFooSerializer = getNewFooSerializer(); return (NewFoo) newFooSerializer.deserialize(xmlInputStream); } private Serializer<OldFoo,InputStream> getOldFooSerializer() { return new XmlXStreamSerializer<OldFoo>( OldFoo.class, Transform.toMap((Pair<Class<?>, XmlModernizationPaver<?>>[])new Pair[] {})); } private Serializer<Object,InputStream> getNewFooSerializer() { return XmlXStreamSerializationProvider.getInstance().getSerializer(NewFoo.class); } }