Skip to content

Commit

Permalink
Fix #2457 (enum subtypes not working as map keys)
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Sep 29, 2019
1 parent d132efa commit d1959f8
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 2 deletions.
4 changes: 4 additions & 0 deletions release-notes/CREDITS-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -971,3 +971,7 @@ Martín Coll (colltoaction@github)
* Contributed #2467: Accept `JsonTypeInfo.As.WRAPPER_ARRAY` with no second argument to
deserialize as "null value"
(2.10.0)
Andrey Kulikov (ankulikov@github)
* Reported #2457: Extended enum values are not handled as enums when used as Map keys
(2.10.1)
5 changes: 5 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Project: jackson-databind
=== Releases ===
------------------------------------------------------------------------

2.10.1 (not yet released)

#2457: Extended enum values are not handled as enums when used as Map keys
(reported by Andrey K)

2.10.0 (26-Sep-2019)

#18: Make `JsonNode` serializable
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/com/fasterxml/jackson/databind/JavaType.java
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,12 @@ public boolean isConcrete() {
public boolean isArrayType() { return false; }

@Override
public final boolean isEnumType() { return _class.isEnum(); }
public final boolean isEnumType() {
// 29-Sep-2019, tatu: `Class.isEnum()` not enough to detect custom subtypes,
// use this instead
// return Enum.class.isAssignableFrom(_class);
return _class.isEnum();
}

@Override
public final boolean isInterface() { return _class.isInterface(); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ public static JsonSerializer<Object> getFallbackKeySerializer(SerializationConfi
if (rawKeyType == Enum.class) {
return new Dynamic();
}
if (rawKeyType.isEnum()) {
// 29-Sep-2019, tatu: [databind#2457] can not use 'rawKeyType.isEnum()`, won't work
// for subtypes.
if (Enum.class.isAssignableFrom(rawKeyType)) {
return EnumKeySerializer.construct(rawKeyType,
EnumValues.constructFromName(config, (Class<Enum<?>>) rawKeyType));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.fasterxml.jackson.databind.deser.jdk;

import java.util.EnumMap;
import java.util.LinkedHashMap;
import java.util.Map;

import com.fasterxml.jackson.annotation.*;
Expand Down Expand Up @@ -77,6 +78,22 @@ public Pojo1859(EnumMap<Enum1859, String> v) {
}
}

// [databind#2457]
enum MyEnum2457 {
A,
B() {
// just to ensure subclass construction
@Override
public void foo() { }
};

// needed to force subclassing
public void foo() { }

@Override
public String toString() { return name() + " as string"; }
}

/*
/**********************************************************
/* Test methods, basic
Expand Down Expand Up @@ -224,4 +241,21 @@ public void testUnknownKeyAsNull() throws Exception
assertEquals(1, value2.size());
assertEquals("value", value2.get(null));
}

// [databind#2457]
public void testCustomEnumAsRootMapKey() throws Exception
{
final ObjectMapper mapper = newJsonMapper();
final Map<MyEnum2457, String> map = new LinkedHashMap<>();
map.put(MyEnum2457.A, "1");
map.put(MyEnum2457.B, "2");
assertEquals(aposToQuotes("{'A':'1','B':'2'}"),
mapper.writeValueAsString(map));

// But should be able to override
assertEquals(aposToQuotes("{'"+MyEnum2457.A.toString()+"':'1','"+MyEnum2457.B.toString()+"':'2'}"),
mapper.writer()
.with(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)
.writeValueAsString(map));
}
}

0 comments on commit d1959f8

Please sign in to comment.