Skip to content

Commit 3cd2eb8

Browse files
committed
Exposed all of XStream 1.4's configurable strategies as XStreamMarshaller bean properties
Issue: SPR-10421
1 parent cc2e7bb commit 3cd2eb8

File tree

1 file changed

+71
-17
lines changed

1 file changed

+71
-17
lines changed

spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java

Lines changed: 71 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,16 @@
3232
import javax.xml.stream.XMLStreamReader;
3333
import javax.xml.stream.XMLStreamWriter;
3434

35+
import com.thoughtworks.xstream.MarshallingStrategy;
3536
import com.thoughtworks.xstream.XStream;
3637
import com.thoughtworks.xstream.converters.ConversionException;
3738
import com.thoughtworks.xstream.converters.Converter;
39+
import com.thoughtworks.xstream.converters.ConverterLookup;
3840
import com.thoughtworks.xstream.converters.ConverterMatcher;
41+
import com.thoughtworks.xstream.converters.ConverterRegistry;
3942
import com.thoughtworks.xstream.converters.SingleValueConverter;
43+
import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
44+
import com.thoughtworks.xstream.core.DefaultConverterLookup;
4045
import com.thoughtworks.xstream.core.util.CompositeClassLoader;
4146
import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
4247
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
@@ -110,16 +115,24 @@ public class XStreamMarshaller extends AbstractMarshaller implements Initializin
110115
public static final String DEFAULT_ENCODING = "UTF-8";
111116

112117

118+
private ReflectionProvider reflectionProvider;
119+
113120
private HierarchicalStreamDriver streamDriver;
114121

115122
private final XppDriver fallbackDriver = new XppDriver();
116123

117124
private Mapper mapper;
118125

119-
private Integer mode;
126+
private ConverterLookup converterLookup = new DefaultConverterLookup();
127+
128+
private ConverterRegistry converterRegistry;
120129

121130
private ConverterMatcher[] converters;
122131

132+
private MarshallingStrategy marshallingStrategy;
133+
134+
private Integer mode;
135+
123136
private Map<String, ?> aliases;
124137

125138
private Map<String, ?> aliasesByType;
@@ -128,7 +141,7 @@ public class XStreamMarshaller extends AbstractMarshaller implements Initializin
128141

129142
private Class<?>[] useAttributeForTypes;
130143

131-
private Map<?, ?> useAttributesFor;
144+
private Map<?, ?> useAttributeFor;
132145

133146
private Map<Class<?>, String> implicitCollections;
134147

@@ -148,7 +161,15 @@ public class XStreamMarshaller extends AbstractMarshaller implements Initializin
148161

149162

150163
/**
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.
152173
* <p>As of Spring 4.0, this stream driver will also be passed to the {@link XStream}
153174
* constructor and therefore used by streaming-related native API methods themselves.
154175
*/
@@ -157,20 +178,31 @@ public void setStreamDriver(HierarchicalStreamDriver streamDriver) {
157178
}
158179

159180
/**
160-
* Set a custom XStream Mapper to use.
181+
* Set a custom XStream {@link Mapper} to use.
161182
* @since 4.0
162183
*/
163184
public void setMapper(Mapper mapper) {
164185
this.mapper = mapper;
165186
}
166187

167188
/**
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
171193
*/
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;
174206
}
175207

176208
/**
@@ -183,6 +215,23 @@ public void setConverters(ConverterMatcher... converters) {
183215
this.converters = converters;
184216
}
185217

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+
186235
/**
187236
* Set an alias/type map, consisting of string aliases mapped to classes.
188237
* <p>Keys are aliases; values are either {@code Class} instances, or String class names.
@@ -226,8 +275,8 @@ public void setUseAttributeForTypes(Class<?>... useAttributeForTypes) {
226275
* or {@code &lt;Class, List&lt;String&gt;&gt;} pairs, which results
227276
* in {@link XStream#useAttributeFor(Class, String)} calls.
228277
*/
229-
public void setUseAttributeFor(Map<?, ?> useAttributesFor) {
230-
this.useAttributesFor = useAttributesFor;
278+
public void setUseAttributeFor(Map<?, ?> useAttributeFor) {
279+
this.useAttributeFor = useAttributeFor;
231280
}
232281

233282
/**
@@ -298,10 +347,8 @@ public final void afterPropertiesSet() {
298347
* Build the native XStream delegate to be used by this marshaller.
299348
*/
300349
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);
305352

306353
if (this.converters != null) {
307354
for (int i = 0; i < this.converters.length; i++) {
@@ -317,6 +364,13 @@ else if (this.converters[i] instanceof SingleValueConverter) {
317364
}
318365
}
319366

367+
if (this.marshallingStrategy != null) {
368+
xstream.setMarshallingStrategy(this.marshallingStrategy);
369+
}
370+
if (this.mode != null) {
371+
xstream.setMode(this.mode);
372+
}
373+
320374
try {
321375
if (this.aliases != null) {
322376
Map<String, Class<?>> classMap = toClassMap(this.aliases);
@@ -356,8 +410,8 @@ else if (this.converters[i] instanceof SingleValueConverter) {
356410
xstream.useAttributeFor(type);
357411
}
358412
}
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()) {
361415
if (entry.getKey() instanceof String) {
362416
if (entry.getValue() instanceof Class) {
363417
xstream.useAttributeFor((String) entry.getKey(), (Class) entry.getValue());

0 commit comments

Comments
 (0)