2
2
3
3
import java .util .*;
4
4
5
- import com .fasterxml .jackson .databind .DeserializationContext ;
6
- import com .fasterxml .jackson .databind .JavaType ;
7
- import com .fasterxml .jackson .databind .JsonDeserializer ;
8
- import com .fasterxml .jackson .databind .JsonMappingException ;
5
+ import com .fasterxml .jackson .databind .*;
9
6
import com .fasterxml .jackson .databind .deser .std .StdDelegatingDeserializer ;
10
7
import com .fasterxml .jackson .databind .type .TypeFactory ;
11
8
import com .fasterxml .jackson .databind .util .Converter ;
@@ -28,7 +25,15 @@ public abstract class JavaUtilCollectionsDeserializers
28
25
private final static int TYPE_UNMODIFIABLE_LIST = 5 ;
29
26
private final static int TYPE_UNMODIFIABLE_MAP = 6 ;
30
27
31
- public final static int TYPE_AS_LIST = 7 ;
28
+ // 2.12.1
29
+ private final static int TYPE_SYNC_SET = 7 ;
30
+ private final static int TYPE_SYNC_COLLECTION = 8 ;
31
+ private final static int TYPE_SYNC_LIST = 9 ;
32
+ private final static int TYPE_SYNC_MAP = 10 ;
33
+
34
+ public final static int TYPE_AS_LIST = 11 ;
35
+
36
+ private final static String PREFIX_JAVA_UTIL_COLLECTIONS = "java.util.Collections$" ;
32
37
33
38
// 10-Jan-2018, tatu: There are a few "well-known" special containers in JDK too:
34
39
@@ -67,6 +72,7 @@ public static JsonDeserializer<?> findForCollection(DeserializationContext ctxt,
67
72
throws JsonMappingException
68
73
{
69
74
JavaUtilCollectionsConverter conv ;
75
+
70
76
// 10-Jan-2017, tatu: Some types from `java.util.Collections`/`java.util.Arrays` need bit of help...
71
77
if (type .hasRawClass (CLASS_AS_ARRAYS_LIST )) {
72
78
conv = converter (TYPE_AS_LIST , type , List .class );
@@ -80,7 +86,17 @@ public static JsonDeserializer<?> findForCollection(DeserializationContext ctxt,
80
86
} else if (type .hasRawClass (CLASS_UNMODIFIABLE_SET )) {
81
87
conv = converter (TYPE_UNMODIFIABLE_SET , type , Set .class );
82
88
} else {
83
- return null ;
89
+ final String utilName = _findUtilSyncTypeName (type .getRawClass ());
90
+ // [databind#3009]: synchronized, too
91
+ if (utilName .endsWith ("Set" )) {
92
+ conv = converter (TYPE_SYNC_SET , type , Set .class );
93
+ } else if (utilName .endsWith ("List" )) {
94
+ conv = converter (TYPE_SYNC_LIST , type , List .class );
95
+ } else if (utilName .endsWith ("Collection" )) {
96
+ conv = converter (TYPE_SYNC_COLLECTION , type , Collection .class );
97
+ } else {
98
+ return null ;
99
+ }
84
100
}
85
101
return new StdDelegatingDeserializer <Object >(conv );
86
102
}
@@ -97,7 +113,13 @@ public static JsonDeserializer<?> findForMap(DeserializationContext ctxt,
97
113
} else if (type .hasRawClass (CLASS_UNMODIFIABLE_MAP )) {
98
114
conv = converter (TYPE_UNMODIFIABLE_MAP , type , Map .class );
99
115
} else {
100
- return null ;
116
+ final String utilName = _findUtilSyncTypeName (type .getRawClass ());
117
+ // [databind#3009]: synchronized, too
118
+ if (utilName .endsWith ("Map" )) {
119
+ conv = converter (TYPE_SYNC_MAP , type , Map .class );
120
+ } else {
121
+ return null ;
122
+ }
101
123
}
102
124
return new StdDelegatingDeserializer <Object >(conv );
103
125
}
@@ -108,6 +130,24 @@ static JavaUtilCollectionsConverter converter(int kind,
108
130
return new JavaUtilCollectionsConverter (kind , concreteType .findSuperType (rawSuper ));
109
131
}
110
132
133
+ private static String _findUtilSyncTypeName (Class <?> raw ) {
134
+ String clsName = _findUtilCollectionsTypeName (raw );
135
+ if (clsName != null ) {
136
+ if (clsName .startsWith ("Synchronized" )) {
137
+ return clsName .substring (12 );
138
+ }
139
+ }
140
+ return "" ;
141
+ }
142
+
143
+ private static String _findUtilCollectionsTypeName (Class <?> raw ) {
144
+ final String clsName = raw .getName ();
145
+ if (clsName .startsWith (PREFIX_JAVA_UTIL_COLLECTIONS )) {
146
+ return clsName .substring (PREFIX_JAVA_UTIL_COLLECTIONS .length ());
147
+ }
148
+ return "" ;
149
+ }
150
+
111
151
/**
112
152
* Implementation used for converting from various generic container
113
153
* types ({@link java.util.Set}, {@link java.util.List}, {@link java.util.Map})
@@ -158,6 +198,15 @@ public Object convert(Object value) {
158
198
case TYPE_UNMODIFIABLE_MAP :
159
199
return Collections .unmodifiableMap ((Map <?,?>) value );
160
200
201
+ case TYPE_SYNC_SET :
202
+ return Collections .synchronizedSet ((Set <?>) value );
203
+ case TYPE_SYNC_LIST :
204
+ return Collections .synchronizedList ((List <?>) value );
205
+ case TYPE_SYNC_COLLECTION :
206
+ return Collections .synchronizedCollection ((Collection <?>) value );
207
+ case TYPE_SYNC_MAP :
208
+ return Collections .synchronizedMap ((Map <?,?>) value );
209
+
161
210
case TYPE_AS_LIST :
162
211
default :
163
212
// Here we do not actually care about impl type, just return List as-is:
0 commit comments