diff --git a/src/main/java/net/openhft/xstreem/convertors/DataValueConverter.java b/src/main/java/net/openhft/xstreem/convertors/DataValueConverter.java index b470b1e0d..b072f9ada 100644 --- a/src/main/java/net/openhft/xstreem/convertors/DataValueConverter.java +++ b/src/main/java/net/openhft/xstreem/convertors/DataValueConverter.java @@ -24,15 +24,22 @@ 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.DataValueModel; +import net.openhft.lang.model.DataValueModels; +import net.openhft.lang.model.FieldModel; import net.openhft.lang.values.StringValue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.beans.*; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Iterator; +import java.util.Map; import static java.beans.Introspector.getBeanInfo; @@ -80,28 +87,27 @@ public class DataValueConverter implements Converter { try { + DataValueModel dataValueModel = DataValueModels.acquireModel(interfaceClass(o.getClass())); - final BeanInfo info = getBeanInfo(o.getClass()); // new BeanGenerator + for (Map.Entry p : dataValueModel.fieldMap().entrySet()) { - for (PropertyDescriptor p : info.getPropertyDescriptors()) { + final FieldModel fileModel = p.getValue(); - if (p instanceof IndexedPropertyDescriptor) { + if (fileModel.indexedGetter() != null) { try { - final IndexedPropertyDescriptor indexedPropertyDescriptor = (IndexedPropertyDescriptor) p; - final Method indexedReadMethod = indexedPropertyDescriptor.getIndexedReadMethod(); + // final IndexedPropertyDescriptor indexedPropertyDescriptor = (IndexedPropertyDescriptor) p; + final Method indexedReadMethod = fileModel.indexedGetter(); if (indexedReadMethod == null) continue; - Class returnType = indexedReadMethod.getReturnType(); + final Class returnType = indexedReadMethod.getReturnType(); - if (returnType == null) { + if (returnType == null) continue; - } - final String simpleName = returnType.getSimpleName(); - final String fieldName = "_" + toCamelCase(simpleName); + final String fieldName = "_" + fileModel.name(); Field field = o.getClass().getDeclaredField(fieldName); field.setAccessible(true); @@ -110,8 +116,7 @@ public class DataValueConverter implements Converter { if (o1 == null) continue; - - writer.startNode(p.getName()); + writer.startNode(fileModel.name()); int i = 0; for (Object f : o1) { if (f == null) { @@ -126,50 +131,59 @@ public class DataValueConverter implements Converter { } catch (NoSuchFieldException | IllegalAccessException e1) { LOG.error("", e1); } + + continue; } - if (p.getName().equals("Class") || - p.getReadMethod() == null || - p.getWriteMethod() == null) - continue; try { - final Method readMethod = p.getReadMethod(); + final Method readMethod = fileModel.getter(); + + + if (readMethod == null) + continue; + + readMethod.setAccessible(true); + final Object value = readMethod.invoke(o); if (value == null) return; - writer.startNode(p.getDisplayName()); + writer.startNode(fileModel.name()); context.convertAnother(value); writer.endNode(); } catch (Exception e) { - LOG.error("class=" + p.getName(), e); + LOG.error("class=" + fileModel.name(), e); } } - } catch (IntrospectionException e) { + } catch (ClassNotFoundException e) { throw new ConversionException("class=" + canonicalName, e); } } + private Class interfaceClass(Class clazz) throws ClassNotFoundException { + String className = clazz.getName(); + boolean isNative = className.endsWith("$$Native"); + boolean isHeap = className.endsWith("$$Heap"); - static String toCamelCase(String s) { + if (!isNative && !isHeap) + throw new ClassNotFoundException(); - final StringBuilder b = new StringBuilder(); + final String nodeName = isNative ? - if (s.length() > 0) - b.append(Character.toLowerCase(s.charAt(0))); + className.substring(0, className.length() - + "$$Native".length()) : - if (s.length() > 0) - b.append(s.substring(1)); - - return b.toString(); + className.substring(0, className.length() - + "$$Heap".length()); + return Class.forName(nodeName); } @@ -177,7 +191,7 @@ public class DataValueConverter implements Converter { public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - final String canonicalName = context.getRequiredType().getCanonicalName(); + final String canonicalName = context.getRequiredType().getName(); boolean isNative = canonicalName.endsWith("$$Native"); boolean isHeap = canonicalName.endsWith("$$Heap"); @@ -215,58 +229,58 @@ public class DataValueConverter implements Converter { } - private void fillInObject(HierarchicalStreamReader reader, UnmarshallingContext context, Object using) throws IntrospectionException { - final BeanInfo beanInfo = getBeanInfo(using.getClass()); + private void fillInObject(HierarchicalStreamReader reader, UnmarshallingContext context, Object using) throws IntrospectionException, ClassNotFoundException { while (reader.hasMoreChildren()) { reader.moveDown(); final String name = reader.getNodeName(); - for (PropertyDescriptor descriptor : beanInfo.getPropertyDescriptors()) { + DataValueModel dataValueModel = DataValueModels.acquireModel(interfaceClass(using.getClass())); - if (!descriptor.getName().equals(name)) - continue; + FieldModel fieldModel = dataValueModel.fieldMap().get(name); - if ((descriptor instanceof IndexedPropertyDescriptor)) { - IndexedPropertyDescriptor indexedPropertyDescriptor = (IndexedPropertyDescriptor) descriptor; - while (reader.hasMoreChildren()) { + if (fieldModel.indexedGetter() != null) { - reader.moveDown(); - try { - String index = reader.getNodeName(); - int i = Integer.parseInt(index); - Method writeMethod = indexedPropertyDescriptor.getIndexedWriteMethod(); - Class[] parameterTypes = writeMethod.getParameterTypes(); + while (reader.hasMoreChildren()) { - if (parameterTypes.length == 2) { - final Method indexedReadMethod = indexedPropertyDescriptor.getIndexedReadMethod(); - final Object instance = indexedReadMethod.invoke(using, i); - fillInObject(reader, context, instance); - } - } catch (IllegalAccessException | InvocationTargetException e) { - LOG.error("", e); + reader.moveDown(); + try { + String index = reader.getNodeName(); + int i = Integer.parseInt(index); + Method writeMethod = fieldModel.indexedSetter(); + Class[] parameterTypes = writeMethod.getParameterTypes(); + + if (parameterTypes.length == 2) { + final Method indexedReadMethod = fieldModel.indexedGetter(); + indexedReadMethod.setAccessible(true); + final Object instance = indexedReadMethod.invoke(using, i); + fillInObject(reader, context, instance); } - - reader.moveUp(); + } catch (IllegalAccessException | InvocationTargetException e) { + LOG.error("", e); } - continue; + + reader.moveUp(); } + reader.moveUp(); + continue; + } - final Class[] parameterTypes = descriptor.getWriteMethod().getParameterTypes(); + Method setter = fieldModel.setter(); + setter.setAccessible(true); - if (parameterTypes.length != 1) - continue; + final Class[] parameterTypes = setter.getParameterTypes(); - final Object object = context.convertAnother(null, parameterTypes[0]); + if (parameterTypes.length != 1) + continue; - try { - descriptor.getWriteMethod().invoke(using, object); - } catch (Exception e) { - LOG.error("", e); - } + final Object object = context.convertAnother(null, parameterTypes[0]); - break; + try { + setter.invoke(using, object); + } catch (Exception e) { + LOG.error("", e); } reader.moveUp(); @@ -274,54 +288,6 @@ public class DataValueConverter implements Converter { } - void convertUsing(final UnmarshallingContext context, final Object using, HierarchicalStreamReader reader) throws IllegalAccessException, IntrospectionException, InvocationTargetException { - UnmarshallingContext context1 = new UnmarshallingContext() { - - @Override - public Object get(Object o) { - return context.get(o); - } - - @Override - public void put(Object o, Object o1) { - context.put(o, o1); - } - - @Override - public Iterator keys() { - return context.keys(); - } - - @Override - public Object convertAnother(Object o, Class aClass) { - return context.convertAnother(o, aClass); - } - - @Override - public Object convertAnother(Object o, Class aClass, Converter converter) { - return context.convertAnother(o, aClass, converter); - } - - @Override - public Object currentObject() { - return using; - } - - @Override - public Class getRequiredType() { - return using.getClass(); - } - - @Override - public void addCompletionCallback(Runnable runnable, int i) { - context.addCompletionCallback(runnable, i); - } - }; - - fillInObject(reader, context1, using); - - } - static Object toNativeValueObjects(HierarchicalStreamReader reader, final Class aClass, UnmarshallingContext context) { diff --git a/src/test/java/net/openhft/chronicle/map/ChronicleMapImportExportTest.java b/src/test/java/net/openhft/chronicle/map/ChronicleMapImportExportTest.java index 414328c94..0f49892e9 100644 --- a/src/test/java/net/openhft/chronicle/map/ChronicleMapImportExportTest.java +++ b/src/test/java/net/openhft/chronicle/map/ChronicleMapImportExportTest.java @@ -159,7 +159,6 @@ public class ChronicleMapImportExportTest { } - @Test public void testFromHashMap() throws IOException, InterruptedException { @@ -267,7 +266,7 @@ public class ChronicleMapImportExportTest { public void testBondVOInterface() throws IOException, InterruptedException { File file = new File(TMP + "/chronicle-map-" + System.nanoTime() + ".json"); - // file.deleteOnExit(); + file.deleteOnExit(); System.out.println(file.getAbsolutePath()); try (ChronicleMap expected = @@ -278,6 +277,10 @@ public class ChronicleMapImportExportTest { // this will add the entry try (WriteContext context = expected.acquireUsingLocked("one", value)) { value.setCoupon(8.98); + BondVOInterface.MarketPx marketPxIntraDayHistoryAt = value.getMarketPxIntraDayHistoryAt(1); + + marketPxIntraDayHistoryAt.setAskPx(12.0); + assert value == context.value(); } @@ -292,7 +295,7 @@ public class ChronicleMapImportExportTest { Assert.assertEquals(expected.get("one").getCoupon(), actual.get("one").getCoupon(), 0); } } finally { - // file.delete(); + file.delete(); } } }