From e1e91e8329aa4f4f14dee491e18484ec0e7c9547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20RIUS?= Date: Thu, 10 Oct 2019 16:58:33 +0200 Subject: [PATCH] FIX/345 : Serializing enums as property or as Map key has different behavior in case of toString overriding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sébastien RIUS --- .../serializer/MapToObjectSerializer.java | 13 ++-- .../MapToObjectSerializerTest.java | 59 +++++++++++++++++++ 2 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java diff --git a/src/main/java/org/eclipse/yasson/internal/serializer/MapToObjectSerializer.java b/src/main/java/org/eclipse/yasson/internal/serializer/MapToObjectSerializer.java index f0f37269f..c6e3b8cad 100644 --- a/src/main/java/org/eclipse/yasson/internal/serializer/MapToObjectSerializer.java +++ b/src/main/java/org/eclipse/yasson/internal/serializer/MapToObjectSerializer.java @@ -12,10 +12,9 @@ ******************************************************************************/ package org.eclipse.yasson.internal.serializer; -import java.util.Map; - import javax.json.bind.serializer.SerializationContext; import javax.json.stream.JsonGenerator; +import java.util.Map; /** * Serialize {@link Map} with {@link String} keys as JSON Object: @@ -77,8 +76,14 @@ public void writeStart(String key, JsonGenerator generator) { */ @Override public void serializeContainer(Map obj, JsonGenerator generator, SerializationContext ctx) { - for (Map.Entry entry : obj.entrySet()) { - final String keyString = String.valueOf(entry.getKey()); + for (Map.Entry entry : obj.entrySet()) { + final String keyString; + K key = entry.getKey(); + if (key instanceof Enum) { + keyString = ((Enum) key).name(); + } else { + keyString = String.valueOf(key); + } final Object value = entry.getValue(); if (value == null) { if (serializer.isNullable()) { diff --git a/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java b/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java new file mode 100644 index 000000000..effee0cf9 --- /dev/null +++ b/src/test/java/org/eclipse/yasson/serializers/MapToObjectSerializerTest.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 + * which accompanies this distribution. + * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Sebastien Rius + ******************************************************************************/ +package org.eclipse.yasson.serializers; + +import org.junit.Assert; +import org.junit.Test; + +import javax.json.bind.Jsonb; +import javax.json.bind.JsonbBuilder; +import javax.json.bind.JsonbConfig; +import java.util.EnumMap; +import java.util.Map; + +/** + * Test various use-cases with {@code Map} serializer which + * stores Map as JSON object. + */ +public class MapToObjectSerializerTest { + + /** + * Enum used as key in maps during tests + */ + enum TestEnum { + ONE, TWO; + + @Override + /** + * Force to lower case to check toString is not used during serialization of maps + */ + public String toString() { + return this.name().toLowerCase(); + } + } + + /** + * Test serialization of Map with Number keys and String values. + */ + @Test + public void testSerializeEnumMapToObject() { + Map map = new EnumMap<>(TestEnum.class); + Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withFormatting(true)); + map.put(TestEnum.ONE, "value1"); + map.put(TestEnum.TWO, "value2"); + String json = jsonb.toJson(map); + for (TestEnum e : TestEnum.values()) { + Assert.assertTrue("Enumeration not well serialized", json.contains(e.name())); + } + } +}