diff --git a/commons-serialize-databind/src/main/java/io/gitlab/jfronny/commons/serialize/databind/impl/adapter/MapTypeAdapterFactory.java b/commons-serialize-databind/src/main/java/io/gitlab/jfronny/commons/serialize/databind/impl/adapter/MapTypeAdapterFactory.java index 7e23afc..ce88690 100644 --- a/commons-serialize-databind/src/main/java/io/gitlab/jfronny/commons/serialize/databind/impl/adapter/MapTypeAdapterFactory.java +++ b/commons-serialize-databind/src/main/java/io/gitlab/jfronny/commons/serialize/databind/impl/adapter/MapTypeAdapterFactory.java @@ -32,23 +32,25 @@ public class MapTypeAdapterFactory implements TypeAdapterFactory { @SuppressWarnings({"unchecked", "rawtypes"}) // we don't define a type parameter for the key or value types - TypeAdapter result = new MapTypeAdapter(mapper, keyAndValueTypes[0], keyAdapter, keyAndValueTypes[1], valueAdapter); + TypeAdapter result = new MapTypeAdapter(mapper, keyAndValueTypes[0], keyAdapter, keyAndValueTypes[1], valueAdapter, rawType); return result; } private static class MapTypeAdapter extends TypeAdapter> { private final TypeAdapter keyTypeAdapter; private final TypeAdapter valueTypeAdapter; + private final Class implClass; public MapTypeAdapter( ObjectMapper context, Type keyType, TypeAdapter keyTypeAdapter, Type valueType, - TypeAdapter valueTypeAdapter) { + TypeAdapter valueTypeAdapter, + Class implClass) { this.keyTypeAdapter = new TypeAdapterRuntimeTypeWrapper<>(context, keyTypeAdapter, keyType); - this.valueTypeAdapter = - new TypeAdapterRuntimeTypeWrapper<>(context, valueTypeAdapter, valueType); + this.valueTypeAdapter = new TypeAdapterRuntimeTypeWrapper<>(context, valueTypeAdapter, valueType); + this.implClass = implClass.equals(Map.class) ? LinkedHashMap.class : implClass; } @Override @@ -102,7 +104,7 @@ public class MapTypeAdapterFactory implements TypeAdapterFactory { @Override public > Map deserialize(Reader reader) throws TEx, MalformedDataException { Token peek = reader.peek(); - Map map = new HashMap<>(); + Map map = (Map) TypeUtils.instantiate(implClass).orElseThrow(() -> new MalformedDataException("Could not instantiate map")); if (peek == Token.BEGIN_ARRAY) { reader.beginArray(); while (reader.hasNext()) { diff --git a/commons-serialize-databind/src/test/java/io/gitlab/jfronny/commons/serialize/databind/test/MapAdapterTest.java b/commons-serialize-databind/src/test/java/io/gitlab/jfronny/commons/serialize/databind/test/MapAdapterTest.java index a144085..61df2d5 100644 --- a/commons-serialize-databind/src/test/java/io/gitlab/jfronny/commons/serialize/databind/test/MapAdapterTest.java +++ b/commons-serialize-databind/src/test/java/io/gitlab/jfronny/commons/serialize/databind/test/MapAdapterTest.java @@ -1,5 +1,6 @@ package io.gitlab.jfronny.commons.serialize.databind.test; +import io.gitlab.jfronny.commons.data.String2ObjectMap; import io.gitlab.jfronny.commons.serialize.MalformedDataException; import io.gitlab.jfronny.commons.serialize.databind.ObjectMapper; import io.gitlab.jfronny.commons.serialize.databind.api.TypeAdapter; @@ -35,4 +36,26 @@ public class MapAdapterTest { assertEquals(de, ew.get()); } } + + @Test + public void testS2OMap() throws MalformedDataException { + DataElement.Object de = new DataElement.Object(); + de.members().put("key", new DataElement.Primitive.String("value")); + de.members().put("key2", new DataElement.Primitive.String("value2")); + de.members().put("key3", new DataElement.Primitive.String("value3")); + ObjectMapper om = new ObjectMapper(); + TypeAdapter> adapter = om.getAdapter(new TypeToken<>() {}); + String2ObjectMap map; + try (EmulatedReader er = new EmulatedReader(de)) { + map = adapter.deserialize(er); + } + assertEquals(3, map.size()); + assertEquals("value", map.get("key")); + assertEquals("value2", map.get("key2")); + assertEquals("value3", map.get("key3")); + try (EmulatedWriter ew = new EmulatedWriter()) { + adapter.serialize(map, ew); + assertEquals(de, ew.get()); + } + } }