11
11
*/
12
12
package com .thoughtworks .xstream .core ;
13
13
14
- import java .util .Collections ;
15
- import java .util .Iterator ;
14
+ import java .util .HashMap ;
16
15
import java .util .LinkedHashMap ;
17
16
import java .util .Map ;
18
- import java .util .WeakHashMap ;
19
17
20
18
import com .thoughtworks .xstream .converters .ConversionException ;
21
19
import com .thoughtworks .xstream .converters .Converter ;
22
20
import com .thoughtworks .xstream .converters .ConverterLookup ;
23
21
import com .thoughtworks .xstream .converters .ConverterRegistry ;
22
+ import com .thoughtworks .xstream .core .util .Cloneables ;
24
23
import com .thoughtworks .xstream .core .util .PrioritizedList ;
25
24
26
25
34
33
public class DefaultConverterLookup implements ConverterLookup , ConverterRegistry , Caching {
35
34
36
35
private final PrioritizedList <Converter > converters = new PrioritizedList <>();
37
- private transient Map <Class <?>, Converter > typeToConverterMap ;
36
+ private transient Map <String , Converter > typeToConverterMap ;
37
+ private Map <String , Converter > serializationMap = null ;
38
38
39
39
public DefaultConverterLookup () {
40
- readResolve ();
40
+ this (new HashMap <>());
41
+ }
42
+
43
+ /**
44
+ * Constructs a DefaultConverterLookup with a provided map.
45
+ *
46
+ * @param map the map to use
47
+ * @throws NullPointerException if map is null
48
+ * @since upcoming
49
+ */
50
+ public DefaultConverterLookup (final Map <String , Converter > map ) {
51
+ typeToConverterMap = map ;
52
+ typeToConverterMap .clear ();
41
53
}
42
54
43
55
@ Override
44
56
public Converter lookupConverterForType (final Class <?> type ) {
45
- final Converter cachedConverter = typeToConverterMap .get (type ) ;
57
+ final Converter cachedConverter = type != null ? typeToConverterMap .get (type . getName ()) : null ;
46
58
if (cachedConverter != null ) {
47
59
return cachedConverter ;
48
60
}
@@ -51,6 +63,9 @@ public Converter lookupConverterForType(final Class<?> type) {
51
63
for (final Converter converter : converters ) {
52
64
try {
53
65
if (converter .canConvert (type )) {
66
+ if (type != null ) {
67
+ typeToConverterMap .put (type .getName (), converter );
68
+ }
54
69
return converter ;
55
70
}
56
71
} catch (final RuntimeException | LinkageError e ) {
@@ -71,17 +86,8 @@ public Converter lookupConverterForType(final Class<?> type) {
71
86
72
87
@ Override
73
88
public void registerConverter (final Converter converter , final int priority ) {
89
+ typeToConverterMap .clear ();
74
90
converters .add (converter , priority );
75
- for (final Iterator <Class <?>> iter = typeToConverterMap .keySet ().iterator (); iter .hasNext ();) {
76
- final Class <?> type = iter .next ();
77
- try {
78
- if (converter .canConvert (type )) {
79
- iter .remove ();
80
- }
81
- } catch (final RuntimeException | LinkageError e ) {
82
- // ignore
83
- }
84
- }
85
91
}
86
92
87
93
@ Override
@@ -94,9 +100,15 @@ public void flushCache() {
94
100
}
95
101
}
96
102
103
+ private Object writeReplace () {
104
+ serializationMap = Cloneables .cloneIfPossible (typeToConverterMap );
105
+ serializationMap .clear ();
106
+ return this ;
107
+ }
108
+
97
109
private Object readResolve () {
98
- // TODO: Use ConcurrentMap
99
- typeToConverterMap = Collections . synchronizedMap ( new WeakHashMap < Class <?>, Converter >()) ;
110
+ typeToConverterMap = serializationMap == null ? new HashMap <>() : serializationMap ;
111
+ serializationMap = null ;
100
112
return this ;
101
113
}
102
114
}
0 commit comments