Skip to content

Commit 8d6c35d

Browse files
peterjurkoviccowtowncoder
authored andcommitted
ClassNameIdResolver doesn't handle resolve Collections$SingletonMap & Collections$SingletonSet (#1823)
Fix ClassNameIdResolver - support for Set and Map collections
1 parent fb2d03c commit 8d6c35d

File tree

2 files changed

+91
-10
lines changed

2 files changed

+91
-10
lines changed

src/main/java/com/fasterxml/jackson/databind/jsontype/impl/ClassNameIdResolver.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ protected JavaType _typeFromId(String id, DatabindContext ctxt) throws IOExcepti
6161
/**********************************************************
6262
*/
6363

64-
protected final String _idFrom(Object value, Class<?> cls, TypeFactory typeFactory)
64+
protected String _idFrom(Object value, Class<?> cls, TypeFactory typeFactory)
6565
{
6666
// Need to ensure that "enum subtypes" work too
6767
if (Enum.class.isAssignableFrom(cls)) {
@@ -87,16 +87,18 @@ protected final String _idFrom(Object value, Class<?> cls, TypeFactory typeFacto
8787
// not optimal: but EnumMap is not a customizable type so this is sort of ok
8888
str = typeFactory.constructMapType(EnumMap.class, enumClass, valueClass).toCanonical();
8989
} else {
90-
String end = str.substring(9);
91-
if ((end.startsWith(".Arrays$") || end.startsWith(".Collections$"))
92-
&& str.indexOf("List") >= 0) {
93-
/* 17-Feb-2010, tatus: Another such case: result of
94-
* Arrays.asList() is named like so in Sun JDK...
95-
* Let's just plain old ArrayList in its place
96-
* NOTE: chances are there are plenty of similar cases
97-
* for other wrappers... (immutable, singleton, synced etc)
98-
*/
90+
/* 17-Feb-2010, tatus: Another such case: result of
91+
* Arrays.asList() is named like so in Sun JDK...
92+
* Let's just plain old ArrayList in its place
93+
* NOTE: chances are there are plenty of similar cases
94+
* for other wrappers... (immutable, singleton, synced etc)
95+
*/
96+
if (isJavaUtilCollectionClass(str, "List")) {
9997
str = "java.util.ArrayList";
98+
}else if(isJavaUtilCollectionClass(str, "Map")){
99+
str = "java.util.HashMap";
100+
}else if(isJavaUtilCollectionClass(str, "Set")){
101+
str = "java.util.HashSet";
100102
}
101103
}
102104
} else if (str.indexOf('$') >= 0) {
@@ -128,4 +130,9 @@ protected final String _idFrom(Object value, Class<?> cls, TypeFactory typeFacto
128130
public String getDescForKnownTypeIds() {
129131
return "class name used as type id";
130132
}
133+
134+
private static boolean isJavaUtilCollectionClass(String clazzName, String type){
135+
String end = clazzName.substring(9);
136+
return (end.startsWith(".Collections$") || end.startsWith(".Arrays$")) && clazzName.indexOf(type) > 0;
137+
}
131138
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package com.fasterxml.jackson.databind.jsontype.impl;
2+
3+
import static org.junit.Assert.assertEquals;
4+
5+
import java.util.Arrays;
6+
import java.util.Collections;
7+
import java.util.List;
8+
import java.util.Map;
9+
import java.util.Set;
10+
11+
import org.junit.Before;
12+
import org.junit.Test;
13+
import org.junit.runner.RunWith;
14+
import org.mockito.Mock;
15+
import org.powermock.core.classloader.annotations.PrepareForTest;
16+
import org.powermock.modules.junit4.PowerMockRunner;
17+
import com.fasterxml.jackson.databind.type.TypeFactory;
18+
19+
import com.fasterxml.jackson.databind.JavaType;
20+
21+
@RunWith(PowerMockRunner.class)
22+
@PrepareForTest(TypeFactory.class)
23+
public class ClassNameIdResolverTest {
24+
25+
@Mock
26+
private JavaType javaType;
27+
28+
@Mock
29+
private TypeFactory typeFactory;
30+
31+
32+
private ClassNameIdResolver classNameIdResolver;
33+
34+
@Before
35+
public void setup(){
36+
this.classNameIdResolver = new ClassNameIdResolver(javaType, typeFactory);
37+
}
38+
39+
@Test
40+
public void testIdFromValue_shouldUseJavaUtilHashMapForSingletonMap(){
41+
Map<String, String> singletonMap = Collections.singletonMap("ANY_KEY", "ANY_VALUE");
42+
43+
String clazz = classNameIdResolver.idFromValue( singletonMap );
44+
45+
assertEquals(clazz, "java.util.HashMap");
46+
}
47+
48+
@Test
49+
public void testIdFromValue_shouldUseJavaUtilHashSetForSingletonSet(){
50+
Set<String> singletonSet = Collections.singleton("ANY_VALUE");
51+
52+
String clazz = classNameIdResolver.idFromValue( singletonSet );
53+
54+
assertEquals(clazz, "java.util.HashSet");
55+
}
56+
57+
@Test
58+
public void testIdFromValue_shouldUseJavaUtilArrayListForSingletonList(){
59+
List<String> singletonList = Collections.singletonList("ANY_VALUE");
60+
61+
String clazz = classNameIdResolver.idFromValue( singletonList );
62+
63+
assertEquals(clazz, "java.util.ArrayList");
64+
}
65+
66+
@Test
67+
public void testIdFromValue_shouldUseJavaUtilArrayListForArrays$List(){
68+
List<String> utilList = Arrays.asList("ANY_VALUE");
69+
70+
String clazz = classNameIdResolver.idFromValue( utilList );
71+
72+
assertEquals(clazz, "java.util.ArrayList");
73+
}
74+
}

0 commit comments

Comments
 (0)