32
32
import javax .xml .stream .XMLStreamReader ;
33
33
import javax .xml .stream .XMLStreamWriter ;
34
34
35
+ import com .thoughtworks .xstream .MarshallingStrategy ;
35
36
import com .thoughtworks .xstream .XStream ;
36
37
import com .thoughtworks .xstream .converters .ConversionException ;
37
38
import com .thoughtworks .xstream .converters .Converter ;
39
+ import com .thoughtworks .xstream .converters .ConverterLookup ;
38
40
import com .thoughtworks .xstream .converters .ConverterMatcher ;
41
+ import com .thoughtworks .xstream .converters .ConverterRegistry ;
39
42
import com .thoughtworks .xstream .converters .SingleValueConverter ;
43
+ import com .thoughtworks .xstream .converters .reflection .ReflectionProvider ;
44
+ import com .thoughtworks .xstream .core .DefaultConverterLookup ;
40
45
import com .thoughtworks .xstream .core .util .CompositeClassLoader ;
41
46
import com .thoughtworks .xstream .io .HierarchicalStreamDriver ;
42
47
import com .thoughtworks .xstream .io .HierarchicalStreamReader ;
@@ -110,16 +115,24 @@ public class XStreamMarshaller extends AbstractMarshaller implements Initializin
110
115
public static final String DEFAULT_ENCODING = "UTF-8" ;
111
116
112
117
118
+ private ReflectionProvider reflectionProvider ;
119
+
113
120
private HierarchicalStreamDriver streamDriver ;
114
121
115
122
private final XppDriver fallbackDriver = new XppDriver ();
116
123
117
124
private Mapper mapper ;
118
125
119
- private Integer mode ;
126
+ private ConverterLookup converterLookup = new DefaultConverterLookup ();
127
+
128
+ private ConverterRegistry converterRegistry ;
120
129
121
130
private ConverterMatcher [] converters ;
122
131
132
+ private MarshallingStrategy marshallingStrategy ;
133
+
134
+ private Integer mode ;
135
+
123
136
private Map <String , ?> aliases ;
124
137
125
138
private Map <String , ?> aliasesByType ;
@@ -128,7 +141,7 @@ public class XStreamMarshaller extends AbstractMarshaller implements Initializin
128
141
129
142
private Class <?>[] useAttributeForTypes ;
130
143
131
- private Map <?, ?> useAttributesFor ;
144
+ private Map <?, ?> useAttributeFor ;
132
145
133
146
private Map <Class <?>, String > implicitCollections ;
134
147
@@ -148,7 +161,15 @@ public class XStreamMarshaller extends AbstractMarshaller implements Initializin
148
161
149
162
150
163
/**
151
- * Set the XStream hierarchical stream driver to be used for readers and writers.
164
+ * Set a custom XStream {@link ReflectionProvider} to use.
165
+ * @since 4.0
166
+ */
167
+ public void setReflectionProvider (ReflectionProvider reflectionProvider ) {
168
+ this .reflectionProvider = reflectionProvider ;
169
+ }
170
+
171
+ /**
172
+ * Set a XStream {@link HierarchicalStreamDriver} to be used for readers and writers.
152
173
* <p>As of Spring 4.0, this stream driver will also be passed to the {@link XStream}
153
174
* constructor and therefore used by streaming-related native API methods themselves.
154
175
*/
@@ -157,20 +178,31 @@ public void setStreamDriver(HierarchicalStreamDriver streamDriver) {
157
178
}
158
179
159
180
/**
160
- * Set a custom XStream Mapper to use.
181
+ * Set a custom XStream {@link Mapper} to use.
161
182
* @since 4.0
162
183
*/
163
184
public void setMapper (Mapper mapper ) {
164
185
this .mapper = mapper ;
165
186
}
166
187
167
188
/**
168
- * Set the XStream mode to use.
169
- * @see XStream#ID_REFERENCES
170
- * @see XStream#NO_REFERENCES
189
+ * Set a custom XStream {@link ConverterLookup} to use.
190
+ * Also used as {@link ConverterRegistry} if the given reference implements it as well.
191
+ * @since 4.0
192
+ * @see DefaultConverterLookup
171
193
*/
172
- public void setMode (int mode ) {
173
- this .mode = mode ;
194
+ public void setConverterLookup (ConverterLookup converterLookup ) {
195
+ this .converterLookup = converterLookup ;
196
+ }
197
+
198
+ /**
199
+ * Set a custom XStream {@link ConverterRegistry} to use.
200
+ * @since 4.0
201
+ * @see #setConverterLookup
202
+ * @see DefaultConverterLookup
203
+ */
204
+ public void setConverterRegistry (ConverterRegistry converterRegistry ) {
205
+ this .converterRegistry = converterRegistry ;
174
206
}
175
207
176
208
/**
@@ -183,6 +215,23 @@ public void setConverters(ConverterMatcher... converters) {
183
215
this .converters = converters ;
184
216
}
185
217
218
+ /**
219
+ * Set a custom XStream {@link MarshallingStrategy} to use.
220
+ * @since 4.0
221
+ */
222
+ public void setMarshallingStrategy (MarshallingStrategy marshallingStrategy ) {
223
+ this .marshallingStrategy = marshallingStrategy ;
224
+ }
225
+
226
+ /**
227
+ * Set the XStream mode to use.
228
+ * @see XStream#ID_REFERENCES
229
+ * @see XStream#NO_REFERENCES
230
+ */
231
+ public void setMode (int mode ) {
232
+ this .mode = mode ;
233
+ }
234
+
186
235
/**
187
236
* Set an alias/type map, consisting of string aliases mapped to classes.
188
237
* <p>Keys are aliases; values are either {@code Class} instances, or String class names.
@@ -226,8 +275,8 @@ public void setUseAttributeForTypes(Class<?>... useAttributeForTypes) {
226
275
* or {@code <Class, List<String>>} pairs, which results
227
276
* in {@link XStream#useAttributeFor(Class, String)} calls.
228
277
*/
229
- public void setUseAttributeFor (Map <?, ?> useAttributesFor ) {
230
- this .useAttributesFor = useAttributesFor ;
278
+ public void setUseAttributeFor (Map <?, ?> useAttributeFor ) {
279
+ this .useAttributeFor = useAttributeFor ;
231
280
}
232
281
233
282
/**
@@ -298,10 +347,8 @@ public final void afterPropertiesSet() {
298
347
* Build the native XStream delegate to be used by this marshaller.
299
348
*/
300
349
protected XStream buildXStream () {
301
- XStream xstream = new XStream (null , this .streamDriver , this .beanClassLoader , this .mapper );
302
- if (this .mode != null ) {
303
- xstream .setMode (this .mode );
304
- }
350
+ XStream xstream = new XStream (this .reflectionProvider , this .streamDriver ,
351
+ this .beanClassLoader , this .mapper , this .converterLookup , this .converterRegistry );
305
352
306
353
if (this .converters != null ) {
307
354
for (int i = 0 ; i < this .converters .length ; i ++) {
@@ -317,6 +364,13 @@ else if (this.converters[i] instanceof SingleValueConverter) {
317
364
}
318
365
}
319
366
367
+ if (this .marshallingStrategy != null ) {
368
+ xstream .setMarshallingStrategy (this .marshallingStrategy );
369
+ }
370
+ if (this .mode != null ) {
371
+ xstream .setMode (this .mode );
372
+ }
373
+
320
374
try {
321
375
if (this .aliases != null ) {
322
376
Map <String , Class <?>> classMap = toClassMap (this .aliases );
@@ -356,8 +410,8 @@ else if (this.converters[i] instanceof SingleValueConverter) {
356
410
xstream .useAttributeFor (type );
357
411
}
358
412
}
359
- if (this .useAttributesFor != null ) {
360
- for (Map .Entry <?, ?> entry : this .useAttributesFor .entrySet ()) {
413
+ if (this .useAttributeFor != null ) {
414
+ for (Map .Entry <?, ?> entry : this .useAttributeFor .entrySet ()) {
361
415
if (entry .getKey () instanceof String ) {
362
416
if (entry .getValue () instanceof Class ) {
363
417
xstream .useAttributeFor ((String ) entry .getKey (), (Class ) entry .getValue ());
0 commit comments