Skip to content

Commit 615bf02

Browse files
committed
Backport fix for #1868 (for case of 2.8.10->2.8.11 regression) in 2.8 from 2.9 (where it's 2.9.2->2.9.3)
1 parent 755e3bc commit 615bf02

File tree

1 file changed

+32
-19
lines changed

1 file changed

+32
-19
lines changed

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

+32-19
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
public class ClassNameIdResolver
1717
extends TypeIdResolverBase
1818
{
19+
private final static String JAVA_UTIL_PKG = "java.util.";
20+
1921
public ClassNameIdResolver(JavaType baseType, TypeFactory typeFactory) {
2022
super(baseType, typeFactory);
2123
}
@@ -86,8 +88,8 @@ protected JavaType _typeFromId(String id, DatabindContext ctxt) throws IOExcepti
8688
/* Internal methods
8789
/**********************************************************
8890
*/
89-
90-
protected final String _idFrom(Object value, Class<?> cls, TypeFactory typeFactory)
91+
92+
protected String _idFrom(Object value, Class<?> cls, TypeFactory typeFactory)
9193
{
9294
// Need to ensure that "enum subtypes" work too
9395
if (Enum.class.isAssignableFrom(cls)) {
@@ -96,8 +98,8 @@ protected final String _idFrom(Object value, Class<?> cls, TypeFactory typeFacto
9698
}
9799
}
98100
String str = cls.getName();
99-
if (str.startsWith("java.util")) {
100-
// 25-Jan-2009, tatu: There are some internal classes that we can not access as is.
101+
if (str.startsWith(JAVA_UTIL_PKG)) {
102+
// 25-Jan-2009, tatu: There are some internal classes that we cannot access as is.
101103
// We need better mechanism; for now this has to do...
102104

103105
// Enum sets and maps are problematic since we MUST know type of
@@ -113,20 +115,20 @@ protected final String _idFrom(Object value, Class<?> cls, TypeFactory typeFacto
113115
// not optimal: but EnumMap is not a customizable type so this is sort of ok
114116
str = typeFactory.constructMapType(EnumMap.class, enumClass, valueClass).toCanonical();
115117
} else {
116-
String end = str.substring(9);
117-
if ((end.startsWith(".Arrays$") || end.startsWith(".Collections$"))
118-
&& str.indexOf("List") >= 0) {
119-
/* 17-Feb-2010, tatus: Another such case: result of
120-
* Arrays.asList() is named like so in Sun JDK...
121-
* Let's just plain old ArrayList in its place
122-
* NOTE: chances are there are plenty of similar cases
123-
* for other wrappers... (immutable, singleton, synced etc)
124-
*/
125-
str = "java.util.ArrayList";
118+
// 17-Feb-2010, tatus: Another such case: result of Arrays.asList() is
119+
// named like so in Sun JDK... Let's just plain old ArrayList in its place.
120+
// ... also, other similar cases exist...
121+
String suffix = str.substring(JAVA_UTIL_PKG.length());
122+
if (isJavaUtilCollectionClass(suffix, "List")) {
123+
str = ArrayList.class.getName();
124+
} else if (isJavaUtilCollectionClass(suffix, "Map")){
125+
str = HashMap.class.getName();
126+
} else if (isJavaUtilCollectionClass(suffix, "Set")){
127+
str = HashSet.class.getName();
126128
}
127129
}
128130
} else if (str.indexOf('$') >= 0) {
129-
/* Other special handling may be needed for inner classes, [JACKSON-584].
131+
/* Other special handling may be needed for inner classes,
130132
* The best way to handle would be to find 'hidden' constructor; pass parent
131133
* value etc (which is actually done for non-anonymous static classes!),
132134
* but that is just not possible due to various things. So, we will instead
@@ -135,10 +137,8 @@ protected final String _idFrom(Object value, Class<?> cls, TypeFactory typeFacto
135137
*/
136138
Class<?> outer = ClassUtil.getOuterClass(cls);
137139
if (outer != null) {
138-
/* one more check: let's actually not worry if the declared
139-
* static type is non-static as well; if so, deserializer does
140-
* have a chance at figuring it all out.
141-
*/
140+
// one more check: let's actually not worry if the declared static type is
141+
// non-static as well; if so, deserializer does have a chance at figuring it all out.
142142
Class<?> staticType = _baseType.getRawClass();
143143
if (ClassUtil.getOuterClass(staticType) == null) {
144144
// Is this always correct? Seems like it should be...
@@ -154,4 +154,17 @@ protected final String _idFrom(Object value, Class<?> cls, TypeFactory typeFacto
154154
public String getDescForKnownTypeIds() {
155155
return "class name used as type id";
156156
}
157+
158+
private static boolean isJavaUtilCollectionClass(String clz, String type)
159+
{
160+
if (clz.startsWith("Collections$")) {
161+
// 02-Jan-2017, tatu: As per [databind#1868], may need to leave Unmodifiable variants as is
162+
return (clz.indexOf(type) > 0)
163+
&& !clz.contains("Unmodifiable");
164+
}
165+
if (clz.startsWith("Arrays$")) {
166+
return (clz.indexOf(type) > 0);
167+
}
168+
return false;
169+
}
157170
}

0 commit comments

Comments
 (0)