From c896e829d0311a08c110bdfc69ba70f970a352b7 Mon Sep 17 00:00:00 2001 From: Artyom Dubinin Date: Fri, 17 Feb 2023 15:53:21 +0300 Subject: [PATCH] Add deep copy instead of shallow copy in mappers Closes #166 --- CHANGELOG.md | 2 ++ .../mappers/DefaultMessagePackMapper.java | 8 +++--- .../mappers/DefaultMessagePackMapperTest.java | 26 +++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f6bbc53..672e3c96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] - Close public access to TarantoolResult*Impl ([#326](https://github.com/tarantool/cartridge-java/issues/326)) +- Add deep copy instead of shallow copy in default message pack mapper + ## [0.10.1] - 2023-01-13 ### Internal and API changes diff --git a/src/main/java/io/tarantool/driver/mappers/DefaultMessagePackMapper.java b/src/main/java/io/tarantool/driver/mappers/DefaultMessagePackMapper.java index 3bb8c389..c7b19880 100644 --- a/src/main/java/io/tarantool/driver/mappers/DefaultMessagePackMapper.java +++ b/src/main/java/io/tarantool/driver/mappers/DefaultMessagePackMapper.java @@ -22,6 +22,7 @@ import java.util.Map; import java.util.Optional; import java.util.function.Function; +import java.util.stream.Collectors; import static io.tarantool.driver.mappers.MapperReflectionUtils.getInterfaceParameterClass; @@ -54,9 +55,10 @@ public DefaultMessagePackMapper() { * @param mapper another mapper instance */ public DefaultMessagePackMapper(DefaultMessagePackMapper mapper) { - this(); - this.valueConverters.putAll(mapper.valueConverters); - this.objectConverters.putAll(mapper.objectConverters); + this.valueConverters = mapper.valueConverters.entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, e -> new ArrayList<>(e.getValue()))); + this.objectConverters = mapper.objectConverters.entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, e -> new ArrayList<>(e.getValue()))); } @SuppressWarnings("unchecked") diff --git a/src/test/java/io/tarantool/driver/mappers/DefaultMessagePackMapperTest.java b/src/test/java/io/tarantool/driver/mappers/DefaultMessagePackMapperTest.java index b34cf989..accece74 100644 --- a/src/test/java/io/tarantool/driver/mappers/DefaultMessagePackMapperTest.java +++ b/src/test/java/io/tarantool/driver/mappers/DefaultMessagePackMapperTest.java @@ -16,6 +16,7 @@ import org.msgpack.value.impl.ImmutableLongValueImpl; import org.msgpack.value.impl.ImmutableStringValueImpl; +import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.Arrays; import java.util.HashMap; @@ -186,6 +187,31 @@ void registerObjectConverter() throws MessagePackObjectMapperException { assertEquals(testValue, mapper.toValue(testTuple).asMapValue().map()); } + @Test + void test_defaultMessagePackMapperCopy_shouldWorkFine() throws MessagePackValueMapperException, + NoSuchFieldException, IllegalAccessException { + DefaultMessagePackMapper mapper = DefaultMessagePackMapperFactory.getInstance().defaultComplexTypesMapper(); + MessagePackMapper copiedMapper = mapper.copy(); + MessagePackMapper copiedOfMapper = DefaultMessagePackMapperFactory.getInstance().copyOf(mapper); + + Field privateField + = DefaultMessagePackMapper.class.getDeclaredField("valueConverters"); + // Set the accessibility as true + privateField.setAccessible(true); + + assertEquals(1, ((List) ((Map) privateField.get(mapper)).get(ValueType.MAP)).size()); + assertEquals(1, ((List) ((Map) privateField.get(copiedMapper)).get(ValueType.MAP)).size()); + + mapper.registerValueConverter(ValueType.MAP, CustomTuple.class, + (ValueConverter) v -> null); + + assertEquals(2, ((List) ((Map) privateField.get(mapper)).get(ValueType.MAP)).size()); + assertEquals(1, ((List) ((Map) privateField.get(copiedMapper)).get(ValueType.MAP)).size()); + assertEquals(1, ((List) ((Map) privateField.get(copiedOfMapper)).get(ValueType.MAP)).size()); + + mapper.copy(); + } + //TODO: add this test when will it be resolved https://github.com/tarantool/cartridge-java/issues/118 // @Test // void should_getObject_returnShort_ifParameterObjectClassIsShort() {