mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
HCOLL-268 refactored out the DataValueConverter
This commit is contained in:
@@ -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<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
|
||||
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<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
|
||||
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"))
|
||||
|
||||
@@ -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<K, V> implements Converter {
|
||||
|
||||
private final Class entrySetClass;
|
||||
private final Class writeThroughEntryClass;
|
||||
private final Map<K, V> map;
|
||||
|
||||
public ChronicleMapConverter(@NotNull Map<K, V> 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<Map.Entry>) 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> 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+16
-152
@@ -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<K, V> 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<K, V> 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<Map.Entry>) 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<K, V> 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<K, V> 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<K, V> 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<K, V> implements Converter {
|
||||
}
|
||||
|
||||
|
||||
static <E> 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<K, V> 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");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user