diff --git a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java index dfbe2ed44..957d0cd12 100755 --- a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java @@ -37,7 +37,8 @@ import net.openhft.lang.threadlocal.Provider; import net.openhft.lang.threadlocal.StatefulCopyable; import net.openhft.lang.threadlocal.ThreadLocalCopies; import net.openhft.xstreem.convertors.ByteBufferConverter; -import net.openhft.xstreem.convertors.ChronicleMapConvecter; +import net.openhft.xstreem.convertors.ChronicleMapConverter; +import net.openhft.xstreem.convertors.DataValueConverter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -662,9 +663,9 @@ class VanillaChronicleMap, xstream.setMode(XStream.NO_REFERENCES); xstream.alias("cmap", VanillaChronicleMap.EntrySet.class); - xstream.registerConverter(new ChronicleMapConvecter(this)); + xstream.registerConverter(new ChronicleMapConverter(this)); xstream.registerConverter(new ByteBufferConverter()); - + xstream.registerConverter(new DataValueConverter()); OutputStream outputStream = new FileOutputStream(toFile); if (toFile.getName().toLowerCase().endsWith(".gz")) outputStream = new GZIPOutputStream(outputStream); @@ -678,8 +679,9 @@ class VanillaChronicleMap, final XStream xstream = new XStream(new JettisonMappedXmlDriver()); xstream.setMode(XStream.NO_REFERENCES); xstream.alias("cmap", VanillaChronicleMap.EntrySet.class); - xstream.registerConverter(new ChronicleMapConvecter(this)); + xstream.registerConverter(new ChronicleMapConverter(this)); xstream.registerConverter(new ByteBufferConverter()); + xstream.registerConverter(new DataValueConverter()); InputStream inputStream = new FileInputStream(fromFile); if (fromFile.getName().toLowerCase().endsWith(".gz")) diff --git a/src/main/java/net/openhft/xstreem/convertors/ChronicleMapConverter.java b/src/main/java/net/openhft/xstreem/convertors/ChronicleMapConverter.java new file mode 100644 index 000000000..533c97b2e --- /dev/null +++ b/src/main/java/net/openhft/xstreem/convertors/ChronicleMapConverter.java @@ -0,0 +1,161 @@ +package net.openhft.xstreem.convertors; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import net.openhft.lang.model.DataValueClasses; +import net.openhft.lang.model.constraints.NotNull; + +import java.util.AbstractMap; +import java.util.Collections; +import java.util.Map; + +/** + * @author Rob Austin. + */ +public class ChronicleMapConverter implements Converter { + + private final Class entrySetClass; + private final Class writeThroughEntryClass; + private final Map map; + + public ChronicleMapConverter(@NotNull Map map) { + + final String vanillaChronicleMap = "net.openhft.chronicle.map.VanillaChronicleMap"; + + try { + this.entrySetClass = Class.forName(vanillaChronicleMap + "$EntrySet"); + this.writeThroughEntryClass = Class.forName(vanillaChronicleMap + "$WriteThroughEntry"); + } catch (ClassNotFoundException e) { + throw new ConversionException("", e); + } + + this.map = map; + } + + + @Override + public boolean canConvert(Class aClass) { + + //noinspection unchecked + return entrySetClass.isAssignableFrom(aClass) || + writeThroughEntryClass.isAssignableFrom(aClass); + + } + + @Override + public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext + marshallingContext) { + + if (entrySetClass.isAssignableFrom(o.getClass())) { + + for (Map.Entry e : (Iterable) o) { + writer.startNode("entry"); + marshallingContext.convertAnother(e); + writer.endNode(); + } + return; + } + + final AbstractMap.SimpleEntry e = (AbstractMap.SimpleEntry) o; + + final Object key = e.getKey(); + writer.startNode(key.getClass().getCanonicalName()); + marshallingContext.convertAnother(key); + writer.endNode(); + + Object value = e.getValue(); + writer.startNode(value.getClass().getCanonicalName()); + marshallingContext.convertAnother(value); + writer.endNode(); + + } + + @Override + public Object unmarshal(HierarchicalStreamReader reader, + UnmarshallingContext context) { + + final String nodeName = reader.getNodeName(); + + if (!"cmap".equals(nodeName)) + return null; + + while (reader.hasMoreChildren()) { + reader.moveDown(); + + final String nodeName0 = reader.getNodeName(); + + if (!nodeName0.equals("entry")) + throw new ConversionException("unable to convert node named=" + nodeName0); + + final K k; + final V v; + + reader.moveDown(); + k = deserialize(context, reader); + reader.moveUp(); + + reader.moveDown(); + v = deserialize(context, reader); + reader.moveUp(); + + if (k != null) + map.put(k, v); + + reader.moveUp(); + } + + return null; + } + + static E deserialize(@NotNull UnmarshallingContext unmarshallingContext, + @NotNull HierarchicalStreamReader reader) { + + final String clazz = reader.getNodeName(); + + switch (clazz) { + + case "java.util.Collections$EmptySet": + return (E) Collections.EMPTY_SET; + + case "java.util.Collections$EmptyList": + return (E) Collections.EMPTY_LIST; + + case "java.util.Collections$EmptyMap": + case "java.util.Collections.EmptyMap": + return (E) Collections.EMPTY_MAP; + + } + + return (E) unmarshallingContext.convertAnother(null, forName(clazz)); + } + + static Class forName(String clazz) { + + try { + return Class.forName(clazz); + } catch (ClassNotFoundException e) { + + boolean isNative = clazz.endsWith("$$Native"); + boolean isHeap = clazz.endsWith("$$Heap"); + + if (!isNative && !isHeap) + throw new ConversionException("class=" + clazz, e); + + final String nativeInterface = isNative ? clazz.substring(0, clazz.length() - + "$$Native".length()) : clazz.substring(0, clazz.length() - + "$$Heap".length()); + try { + DataValueClasses.newDirectInstance(Class.forName(clazz)); + return Class.forName(nativeInterface); + } catch (Exception e1) { + throw new ConversionException("class=" + clazz, e1); + } + + } + } + +} diff --git a/src/main/java/net/openhft/xstreem/convertors/ChronicleMapConvecter.java b/src/main/java/net/openhft/xstreem/convertors/DataValueConverter.java similarity index 57% rename from src/main/java/net/openhft/xstreem/convertors/ChronicleMapConvecter.java rename to src/main/java/net/openhft/xstreem/convertors/DataValueConverter.java index 75f2ec9fc..c2edf7a6b 100644 --- a/src/main/java/net/openhft/xstreem/convertors/ChronicleMapConvecter.java +++ b/src/main/java/net/openhft/xstreem/convertors/DataValueConverter.java @@ -7,7 +7,6 @@ import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import net.openhft.lang.model.DataValueClasses; -import net.openhft.lang.model.constraints.NotNull; import net.openhft.lang.values.StringValue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,81 +16,20 @@ import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; -import java.util.AbstractMap; -import java.util.Collections; -import java.util.Map; import static java.beans.Introspector.getBeanInfo; + /** * @author Rob Austin. */ -public class ChronicleMapConvecter implements Converter { +public class DataValueConverter implements Converter { - private static final Logger LOG = LoggerFactory.getLogger(ChronicleMapConvecter.class); - - private final Class entrySetClass; - private final Class writeThroughEntryClass; - private final Map map; - - public ChronicleMapConvecter(@NotNull Map map) { - - final String vanillaChronicleMap = "net.openhft.chronicle.map.VanillaChronicleMap"; - - try { - this.entrySetClass = Class.forName(vanillaChronicleMap + "$EntrySet"); - this.writeThroughEntryClass = Class.forName(vanillaChronicleMap + "$WriteThroughEntry"); - } catch (ClassNotFoundException e) { - throw new ConversionException("", e); - } - - this.map = map; - } + private static final Logger LOG = LoggerFactory.getLogger(DataValueConverter.class); @Override - public boolean canConvert(Class aClass) { - - //noinspection unchecked - if (entrySetClass.isAssignableFrom(aClass) || - writeThroughEntryClass.isAssignableFrom(aClass)) - return true; - - final String canonicalName = aClass.getCanonicalName(); - - return canonicalName.startsWith("net.openhft.lang.values") || - canonicalName.endsWith("$$Native") || - canonicalName.endsWith("$$Heap"); - } - - @Override - public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext - marshallingContext) { - - //noinspection unchecked - if (writeThroughEntryClass.isAssignableFrom(o.getClass())) { - - final AbstractMap.SimpleEntry e = (AbstractMap.SimpleEntry) o; - - final Object key = e.getKey(); - writer.startNode(key.getClass().getCanonicalName()); - marshallingContext.convertAnother(key); - writer.endNode(); - - Object value = e.getValue(); - writer.startNode(value.getClass().getCanonicalName()); - marshallingContext.convertAnother(value); - writer.endNode(); - - } else if (entrySetClass.isAssignableFrom(o.getClass())) { - - for (Map.Entry e : (Iterable) o) { - writer.startNode("entry"); - marshallingContext.convertAnother(e); - writer.endNode(); - } - - } + public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext context) { final String canonicalName = o.getClass().getCanonicalName(); @@ -113,7 +51,7 @@ public class ChronicleMapConvecter implements Converter { } try { - marshallingContext.convertAnother(method.invoke(o)); + context.convertAnother(method.invoke(o)); return; } catch (Exception e) { throw new ConversionException("class=" + canonicalName, e); @@ -144,7 +82,7 @@ public class ChronicleMapConvecter implements Converter { return; writer.startNode(p.getDisplayName()); - marshallingContext.convertAnother(value); + context.convertAnother(value); writer.endNode(); } catch (Exception e) { @@ -160,40 +98,7 @@ public class ChronicleMapConvecter implements Converter { } @Override - public Object unmarshal(HierarchicalStreamReader reader, - UnmarshallingContext context) { - - - if ("cmap".equals(reader.getNodeName())) { - - while (reader.hasMoreChildren()) { - reader.moveDown(); - final String name = reader.getNodeName(); - - if (!name.equals("entry")) - throw new ConversionException("unable to convert node " + - "named=" + name); - final K k; - final V v; - - reader.moveDown(); - k = deserialize(context, reader); - reader.moveUp(); - - reader.moveDown(); - v = deserialize(context, reader); - reader.moveUp(); - - if (k != null) - map.put(k, v); - - reader.moveUp(); - } - - return null; - - } - + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { final String canonicalName = context.getRequiredType().getCanonicalName(); boolean isNative = canonicalName.endsWith("$$Native"); @@ -264,56 +169,6 @@ public class ChronicleMapConvecter implements Converter { } - static E deserialize(@NotNull UnmarshallingContext unmarshallingContext, - @NotNull HierarchicalStreamReader reader) { - - final String clazz = reader.getNodeName(); - - switch (clazz) { - - case "java.util.Collections$EmptySet": - return (E) Collections.EMPTY_SET; - - case "java.util.Collections$EmptyList": - return (E) Collections.EMPTY_LIST; - - case "java.util.Collections$EmptyMap": - case "java.util.Collections.EmptyMap": - return (E) Collections.EMPTY_MAP; - - } - - return (E) unmarshallingContext.convertAnother(null, forName(clazz)); - } - - static Class forName(String clazz) { - - try { - - return Class.forName(clazz); - - } catch (ClassNotFoundException e) { - - boolean isNative = clazz.endsWith("$$Native"); - boolean isHeap = clazz.endsWith("$$Heap"); - - if (!isNative && !isHeap) - throw new ConversionException("class=" + clazz, e); - - final String nativeInterface = isNative ? clazz.substring(0, clazz.length() - - "$$Native".length()) : clazz.substring(0, clazz.length() - - "$$Heap".length()); - try { - DataValueClasses.newDirectInstance(Class.forName(clazz)); - return Class.forName(nativeInterface); - } catch (Exception e1) { - throw new ConversionException("class=" + clazz, e1); - } - - } - } - - static Object toNativeValueObjects(HierarchicalStreamReader reader, final Class aClass, UnmarshallingContext context) { @@ -353,4 +208,13 @@ public class ChronicleMapConvecter implements Converter { aClass.getCanonicalName()); } + + @Override + public boolean canConvert(Class clazz) { + final String canonicalName = clazz.getCanonicalName(); + + return canonicalName.startsWith("net.openhft.lang.values") || + canonicalName.endsWith("$$Native") || + canonicalName.endsWith("$$Heap"); + } }