XML persist: fix serializing MutableSet
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/8aa09c50 Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/8aa09c50 Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/8aa09c50 Branch: refs/heads/0.6.0 Commit: 8aa09c50bbd35032b8ed01f812dfbec5c75246f4 Parents: c7ff592 Author: Aled Sage <[email protected]> Authored: Tue Nov 12 11:18:22 2013 +0000 Committer: Aled Sage <[email protected]> Committed: Tue Nov 12 21:53:10 2013 +0000 ---------------------------------------------------------------------- .../util/xstream/MutableSetConverter.java | 26 ++++++ .../brooklyn/util/xstream/XmlSerializer.java | 11 ++- .../persister/XmlMementoSerializerTest.java | 94 ++++++++++++++++++++ 3 files changed, 130 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8aa09c50/core/src/main/java/brooklyn/util/xstream/MutableSetConverter.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/util/xstream/MutableSetConverter.java b/core/src/main/java/brooklyn/util/xstream/MutableSetConverter.java new file mode 100644 index 0000000..10bb618 --- /dev/null +++ b/core/src/main/java/brooklyn/util/xstream/MutableSetConverter.java @@ -0,0 +1,26 @@ +package brooklyn.util.xstream; + +import brooklyn.util.collections.MutableSet; + +import com.thoughtworks.xstream.converters.collections.CollectionConverter; +import com.thoughtworks.xstream.mapper.Mapper; + +public class MutableSetConverter extends CollectionConverter { + + // Although this class seems pointless (!), without registering an explicit converter for MutableSet then the + // declaration for Set interferes, causing MutableSet.map field to be null on deserialization. + + public MutableSetConverter(Mapper mapper) { + super(mapper); + } + + @Override + public boolean canConvert(@SuppressWarnings("rawtypes") Class type) { + return MutableSet.class.isAssignableFrom(type); + } + + @Override + protected Object createCollection(Class type) { + return new MutableSet<Object>(); + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8aa09c50/core/src/main/java/brooklyn/util/xstream/XmlSerializer.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/util/xstream/XmlSerializer.java b/core/src/main/java/brooklyn/util/xstream/XmlSerializer.java index 55e68b4..b266259 100644 --- a/core/src/main/java/brooklyn/util/xstream/XmlSerializer.java +++ b/core/src/main/java/brooklyn/util/xstream/XmlSerializer.java @@ -9,7 +9,9 @@ import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; +import brooklyn.util.collections.MutableList; import brooklyn.util.collections.MutableMap; +import brooklyn.util.collections.MutableSet; import com.google.common.collect.ImmutableList; import com.thoughtworks.xstream.XStream; @@ -27,10 +29,17 @@ public class XmlSerializer<T> { xstream.registerConverter(new StringKeyMapConverter(xstream.getMapper()), /* priority */ 10); xstream.alias("MutableMap", MutableMap.class); + xstream.alias("MutableSet", MutableSet.class); + xstream.alias("MutableList", MutableList.class); + + // Needs an explicit MutableSet converter! + // Without it, the alias for "set" seems to interfere with the MutableSet.map field, so it gets + // a null field on deserialization. + xstream.registerConverter(new MutableSetConverter(xstream.getMapper())); xstream.aliasType("ImmutableList", ImmutableList.class); xstream.registerConverter(new ImmutableListConverter(xstream.getMapper())); - + xstream.registerConverter(new EnumCaseForgivingConverter()); xstream.registerConverter(new Inet4AddressConverter()); } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8aa09c50/core/src/test/java/brooklyn/entity/rebind/persister/XmlMementoSerializerTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/brooklyn/entity/rebind/persister/XmlMementoSerializerTest.java b/core/src/test/java/brooklyn/entity/rebind/persister/XmlMementoSerializerTest.java new file mode 100644 index 0000000..855de46 --- /dev/null +++ b/core/src/test/java/brooklyn/entity/rebind/persister/XmlMementoSerializerTest.java @@ -0,0 +1,94 @@ +package brooklyn.entity.rebind.persister; + +import static org.testng.Assert.assertEquals; + +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import brooklyn.util.collections.MutableList; +import brooklyn.util.collections.MutableMap; +import brooklyn.util.collections.MutableSet; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +public class XmlMementoSerializerTest { + + private XmlMementoSerializer<Object> serializer; + + @BeforeMethod(alwaysRun=true) + public void setUp() throws Exception { + serializer = new XmlMementoSerializer<Object>(XmlMementoSerializerTest.class.getClassLoader()); + } + + @Test + public void testMutableSet() throws Exception { + Set<?> obj = MutableSet.of("123"); + assertSerializeAndDeserialize(obj); + } + + @Test + public void testLinkedHashSet() throws Exception { + Set<String> obj = new LinkedHashSet<String>(); + obj.add("123"); + assertSerializeAndDeserialize(obj); + } + + @Test + public void testImmutableSet() throws Exception { + Set<String> obj = ImmutableSet.of("123"); + assertSerializeAndDeserialize(obj); + } + + @Test + public void testMutableList() throws Exception { + List<?> obj = MutableList.of("123"); + assertSerializeAndDeserialize(obj); + } + + @Test + public void testLinkedList() throws Exception { + List<String> obj = new LinkedList<String>(); + obj.add("123"); + assertSerializeAndDeserialize(obj); + } + + @Test + public void testImmutableList() throws Exception { + List<String> obj = ImmutableList.of("123"); + assertSerializeAndDeserialize(obj); + } + + @Test + public void testMutableMap() throws Exception { + Map<?,?> obj = MutableMap.of("mykey", "myval"); + assertSerializeAndDeserialize(obj); + } + + @Test + public void testLinkedHashMap() throws Exception { + Map<String,String> obj = new LinkedHashMap<String,String>(); + obj.put("mykey", "myval"); + assertSerializeAndDeserialize(obj); + } + + @Test + public void testImmutableMap() throws Exception { + Map<?,?> obj = ImmutableMap.of("mykey", "myval"); + assertSerializeAndDeserialize(obj); + } + + private void assertSerializeAndDeserialize(Object obj) throws Exception { + String serializedForm = serializer.toString(obj); + Object deserialized = serializer.fromString(serializedForm); + assertEquals(deserialized, obj); + } +}
