From 02a49f6b4117d5271951757696b906c249e40992 Mon Sep 17 00:00:00 2001 From: Kevin Turner <83819+keturn@users.noreply.github.com> Date: Tue, 14 Jun 2022 14:10:45 -0700 Subject: [PATCH] fix(TypeHandlerLibrary): fix error-during-error-logging in GenericMap --- .../coreTypes/GenericMapTypeHandler.java | 18 +++-- .../coreTypes/ObjectFieldMapTypeHandler.java | 11 ++- .../RuntimeDelegatingTypeHandler.java | 18 +++-- .../typeHandling/inMemory/PersistedMap.java | 10 ++- .../inMemory/PersistedString.java | 12 ++- .../reflect/ConstructorLibrary.java | 10 ++- .../coreTypes/GenericMapTypeHandlerTest.java | 78 +++++++++++++++++++ 7 files changed, 139 insertions(+), 18 deletions(-) create mode 100644 subsystems/TypeHandlerLibrary/src/test/java/org/terasology/persistence/typeHandling/coreTypes/GenericMapTypeHandlerTest.java diff --git a/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/coreTypes/GenericMapTypeHandler.java b/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/coreTypes/GenericMapTypeHandler.java index 92b789e388b..c6e47c58ae7 100644 --- a/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/coreTypes/GenericMapTypeHandler.java +++ b/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/coreTypes/GenericMapTypeHandler.java @@ -1,4 +1,4 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.persistence.typeHandling.coreTypes; @@ -8,6 +8,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.terasology.persistence.typeHandling.PersistedData; +import org.terasology.persistence.typeHandling.PersistedDataMap; import org.terasology.persistence.typeHandling.PersistedDataSerializer; import org.terasology.persistence.typeHandling.TypeHandler; @@ -25,10 +26,10 @@ */ public class GenericMapTypeHandler extends TypeHandler> { - private static final Logger logger = LoggerFactory.getLogger(GenericMapTypeHandler.class); + static final String KEY = "key"; + static final String VALUE = "value"; - private static final String KEY = "key"; - private static final String VALUE = "value"; + private static final Logger logger = LoggerFactory.getLogger(GenericMapTypeHandler.class); private final TypeHandler keyHandler; private final TypeHandler valueHandler; @@ -67,17 +68,18 @@ public Optional> deserialize(PersistedData data) { Map result = Maps.newLinkedHashMap(); for (PersistedData entry : data.getAsArray()) { - final Optional key = keyHandler.deserialize(entry.getAsValueMap().get(KEY)); - final Optional value = valueHandler.deserialize(entry.getAsValueMap().get(VALUE)); + PersistedDataMap kvEntry = entry.getAsValueMap(); + final Optional key = keyHandler.deserialize(kvEntry.get(KEY)); if (key.isPresent()) { + final Optional value = valueHandler.deserialize(kvEntry.get(VALUE)); if (value.isPresent()) { result.put(key.get(), value.get()); } else { - logger.warn("Missing field '{}' for entry '{}'", VALUE, data.getAsString()); + logger.warn("Missing value for key '{}' with {} given entry '{}'", key.get(), valueHandler, kvEntry.get(VALUE)); } } else { - logger.warn("Missing field '{}' for entry '{}'", KEY, data.getAsString()); + logger.warn("Missing field '{}' for entry '{}'", KEY, kvEntry); } } diff --git a/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/coreTypes/ObjectFieldMapTypeHandler.java b/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/coreTypes/ObjectFieldMapTypeHandler.java index 08301be9197..519ed719f0d 100644 --- a/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/coreTypes/ObjectFieldMapTypeHandler.java +++ b/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/coreTypes/ObjectFieldMapTypeHandler.java @@ -1,8 +1,9 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.persistence.typeHandling.coreTypes; import com.google.common.base.Defaults; +import com.google.common.base.MoreObjects; import com.google.common.collect.Maps; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -111,4 +112,12 @@ public Optional deserialize(PersistedData data) { } return Optional.empty(); } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("fields", fieldByName.keySet()) + .add("constructor", constructor) + .toString(); + } } diff --git a/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/coreTypes/RuntimeDelegatingTypeHandler.java b/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/coreTypes/RuntimeDelegatingTypeHandler.java index 76ec4debce9..db5099d9167 100644 --- a/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/coreTypes/RuntimeDelegatingTypeHandler.java +++ b/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/coreTypes/RuntimeDelegatingTypeHandler.java @@ -1,7 +1,8 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.persistence.typeHandling.coreTypes; +import com.google.common.base.MoreObjects; import com.google.common.collect.Maps; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,10 +35,10 @@ public class RuntimeDelegatingTypeHandler extends TypeHandler { private static final Logger LOGGER = LoggerFactory.getLogger(RuntimeDelegatingTypeHandler.class); - private TypeHandler delegateHandler; - private TypeInfo typeInfo; - private TypeHandlerLibrary typeHandlerLibrary; - private SerializationSandbox sandbox; + private final TypeHandler delegateHandler; + private final TypeInfo typeInfo; + private final TypeHandlerLibrary typeHandlerLibrary; + private final SerializationSandbox sandbox; public RuntimeDelegatingTypeHandler(TypeHandler delegateHandler, TypeInfo typeInfo, TypeHandlerContext context) { this.delegateHandler = delegateHandler; @@ -242,4 +243,11 @@ private Optional findSubtypeWithName(String runtimeTypeName) { ); } + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("delegate", delegateHandler) + .add("type", typeInfo) + .toString(); + } } diff --git a/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/inMemory/PersistedMap.java b/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/inMemory/PersistedMap.java index f114b3320e1..828308d864a 100644 --- a/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/inMemory/PersistedMap.java +++ b/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/inMemory/PersistedMap.java @@ -1,7 +1,8 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.persistence.typeHandling.inMemory; +import com.google.common.base.MoreObjects; import org.terasology.persistence.typeHandling.PersistedData; import org.terasology.persistence.typeHandling.PersistedDataArray; import org.terasology.persistence.typeHandling.PersistedDataMap; @@ -80,4 +81,11 @@ public PersistedDataArray getAsArray(String name) { public Set> entrySet() { return map.entrySet(); } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .addValue(map) + .toString(); + } } diff --git a/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/inMemory/PersistedString.java b/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/inMemory/PersistedString.java index 8a33b8cc7c7..a4f81cc056c 100644 --- a/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/inMemory/PersistedString.java +++ b/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/persistence/typeHandling/inMemory/PersistedString.java @@ -1,10 +1,12 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.persistence.typeHandling.inMemory; +import com.google.common.base.MoreObjects; + public class PersistedString extends AbstractPersistedData { - private String data; + private final String data; public PersistedString(String data) { this.data = data; @@ -20,4 +22,10 @@ public boolean isString() { return true; } + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .addValue(data) + .toString(); + } } diff --git a/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/reflection/reflect/ConstructorLibrary.java b/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/reflection/reflect/ConstructorLibrary.java index fe03f54d252..b58844119f5 100644 --- a/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/reflection/reflect/ConstructorLibrary.java +++ b/subsystems/TypeHandlerLibrary/src/main/java/org/terasology/reflection/reflect/ConstructorLibrary.java @@ -1,7 +1,8 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.reflection.reflect; +import com.google.common.base.MoreObjects; import com.google.common.collect.HashMultiset; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMultiset; @@ -65,6 +66,13 @@ public T construct() { "Register an InstanceCreator for this type to fix this problem.", e); } } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("type", typeInfo) + .toString(); + } }; } diff --git a/subsystems/TypeHandlerLibrary/src/test/java/org/terasology/persistence/typeHandling/coreTypes/GenericMapTypeHandlerTest.java b/subsystems/TypeHandlerLibrary/src/test/java/org/terasology/persistence/typeHandling/coreTypes/GenericMapTypeHandlerTest.java new file mode 100644 index 00000000000..0419524eab8 --- /dev/null +++ b/subsystems/TypeHandlerLibrary/src/test/java/org/terasology/persistence/typeHandling/coreTypes/GenericMapTypeHandlerTest.java @@ -0,0 +1,78 @@ +// Copyright 2022 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 + +package org.terasology.persistence.typeHandling.coreTypes; + +import org.junit.jupiter.api.Test; +import org.terasology.persistence.typeHandling.PersistedData; +import org.terasology.persistence.typeHandling.PersistedDataSerializer; +import org.terasology.persistence.typeHandling.TypeHandler; +import org.terasology.persistence.typeHandling.inMemory.PersistedLong; +import org.terasology.persistence.typeHandling.inMemory.PersistedMap; +import org.terasology.persistence.typeHandling.inMemory.PersistedString; +import org.terasology.persistence.typeHandling.inMemory.arrays.PersistedValueArray; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; + +class GenericMapTypeHandlerTest { + + private static final String TEST_KEY = "health:baseRegen"; + private static final long TEST_VALUE = -1; + + private final PersistedData testData = new PersistedValueArray(List.of( + new PersistedMap(Map.of( + GenericMapTypeHandler.KEY, new PersistedString(TEST_KEY), + GenericMapTypeHandler.VALUE, new PersistedLong(TEST_VALUE) + )) + )); + + @Test + void testDeserialize() { + var th = new GenericMapTypeHandler<>( + new StringTypeHandler(), + new LongTypeHandler() + ); + + assertThat(th.deserialize(testData)).isPresent(); + assertThat(th.deserialize(testData).get()).containsExactly(TEST_KEY, TEST_VALUE); + } + + @Test + void testDeserializeWithMismatchedValueHandler() { + var th = new GenericMapTypeHandler<>( + new StringTypeHandler(), + new UselessTypeHandler<>() + ); + + assertThat(th.deserialize(testData)).hasValue(Collections.emptyMap()); + } + + @Test + void testDeserializeWithMismatchedKeyHandler() { + var th = new GenericMapTypeHandler<>( + new UselessTypeHandler<>(), + new LongTypeHandler() + ); + + assertThat(th.deserialize(testData)).hasValue(Collections.emptyMap()); + } + + /** Never returns a value. */ + private static class UselessTypeHandler extends TypeHandler { + @Override + protected PersistedData serializeNonNull(Object value, PersistedDataSerializer serializer) { + return null; + } + + @Override + public Optional deserialize(PersistedData data) { + return Optional.empty(); + } + } +}