From e1e2ad18e3823ac0667a3b71f026e57093c28c1b Mon Sep 17 00:00:00 2001 From: Nate Mortensen Date: Thu, 24 Apr 2014 19:29:08 -0600 Subject: [PATCH] Add handling for Iterables to Serialization Currently any ConfigurationSerializable object that relies upon Iterables for its serialization will fail to serialize correctly, and, in turn, fail to deserialize properly. To correct this, special casing has been added for Iterables(and Maps in a few places) to ensure that all ConfigurationSerializable objects are serialized and deserialized correctly. --- .../vaultmanagement/Serialization.java | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/Serialization.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/Serialization.java index 721c667..ebc25cc 100644 --- a/src/main/java/com/drtshock/playervaults/vaultmanagement/Serialization.java +++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/Serialization.java @@ -109,21 +109,36 @@ public class Serialization { } public static Map serialize(ConfigurationSerializable cs) { - Map serialized = recreateMap(cs.serialize()); + Map returnVal = handleSerialization(cs.serialize()); + returnVal.put(ConfigurationSerialization.SERIALIZED_TYPE_KEY, ConfigurationSerialization.getAlias(cs.getClass())); + return returnVal; + } + + @SuppressWarnings("unchecked") + private static Map handleSerialization(Map map) { + Map serialized = recreateMap(map); for (Entry entry : serialized.entrySet()) { if (entry.getValue() instanceof ConfigurationSerializable) { entry.setValue(serialize((ConfigurationSerializable) entry.getValue())); + } else if (entry.getValue() instanceof Iterable) { + List newList = new ArrayList<>(); + for (Object object : ((Iterable) entry.getValue())) { + if (object instanceof ConfigurationSerializable) { + object = serialize((ConfigurationSerializable) object); + } + newList.add(object); + } + entry.setValue(newList); + } else if (entry.getValue() instanceof Map) { + // unchecked cast here. If you're serializing to a non-standard Map you deserve ClassCastExceptions + entry.setValue(handleSerialization((Map) entry.getValue())); } } - serialized.put(ConfigurationSerialization.SERIALIZED_TYPE_KEY, ConfigurationSerialization.getAlias(cs.getClass())); return serialized; } - public static Map recreateMap(Map original) { Map map = new HashMap(); - for (Entry entry : original.entrySet()) { - map.put(entry.getKey(), entry.getValue()); - } + map.putAll(original); return map; } @@ -132,8 +147,23 @@ public class Serialization { for (Entry entry : map.entrySet()) { if (entry.getValue() instanceof Map && ((Map) entry.getValue()).containsKey(ConfigurationSerialization.SERIALIZED_TYPE_KEY)) { entry.setValue(deserialize((Map) entry.getValue())); + } else if (entry.getValue() instanceof Iterable) { + entry.setValue(convertIterable((Iterable) entry.getValue())); } } return ConfigurationSerialization.deserializeObject(map); } + + private static List convertIterable(Iterable iterable) { + List newList = new ArrayList<>(); + for (Object object : iterable) { + if (object instanceof Map) { + object = deserialize((Map) object); + } else if (object instanceof List) { + object = convertIterable((Iterable) object); + } + newList.add(object); + } + return newList; + } } \ No newline at end of file