From 3cd2eb83c5937de7d6636f9b410947ee9c8cde99 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 5 Aug 2013 22:13:04 +0200 Subject: [PATCH] Exposed all of XStream 1.4's configurable strategies as XStreamMarshaller bean properties Issue: SPR-10421 --- .../oxm/xstream/XStreamMarshaller.java | 88 +++++++++++++++---- 1 file changed, 71 insertions(+), 17 deletions(-) diff --git a/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java index 48df330efb..75a8b493c4 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java @@ -32,11 +32,16 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; +import com.thoughtworks.xstream.MarshallingStrategy; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.converters.ConversionException; import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.ConverterLookup; import com.thoughtworks.xstream.converters.ConverterMatcher; +import com.thoughtworks.xstream.converters.ConverterRegistry; import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; +import com.thoughtworks.xstream.core.DefaultConverterLookup; import com.thoughtworks.xstream.core.util.CompositeClassLoader; import com.thoughtworks.xstream.io.HierarchicalStreamDriver; import com.thoughtworks.xstream.io.HierarchicalStreamReader; @@ -110,16 +115,24 @@ public class XStreamMarshaller extends AbstractMarshaller implements Initializin public static final String DEFAULT_ENCODING = "UTF-8"; + private ReflectionProvider reflectionProvider; + private HierarchicalStreamDriver streamDriver; private final XppDriver fallbackDriver = new XppDriver(); private Mapper mapper; - private Integer mode; + private ConverterLookup converterLookup = new DefaultConverterLookup(); + + private ConverterRegistry converterRegistry; private ConverterMatcher[] converters; + private MarshallingStrategy marshallingStrategy; + + private Integer mode; + private Map aliases; private Map aliasesByType; @@ -128,7 +141,7 @@ public class XStreamMarshaller extends AbstractMarshaller implements Initializin private Class[] useAttributeForTypes; - private Map useAttributesFor; + private Map useAttributeFor; private Map, String> implicitCollections; @@ -148,7 +161,15 @@ public class XStreamMarshaller extends AbstractMarshaller implements Initializin /** - * Set the XStream hierarchical stream driver to be used for readers and writers. + * Set a custom XStream {@link ReflectionProvider} to use. + * @since 4.0 + */ + public void setReflectionProvider(ReflectionProvider reflectionProvider) { + this.reflectionProvider = reflectionProvider; + } + + /** + * Set a XStream {@link HierarchicalStreamDriver} to be used for readers and writers. *

As of Spring 4.0, this stream driver will also be passed to the {@link XStream} * constructor and therefore used by streaming-related native API methods themselves. */ @@ -157,7 +178,7 @@ public class XStreamMarshaller extends AbstractMarshaller implements Initializin } /** - * Set a custom XStream Mapper to use. + * Set a custom XStream {@link Mapper} to use. * @since 4.0 */ public void setMapper(Mapper mapper) { @@ -165,12 +186,23 @@ public class XStreamMarshaller extends AbstractMarshaller implements Initializin } /** - * Set the XStream mode to use. - * @see XStream#ID_REFERENCES - * @see XStream#NO_REFERENCES + * Set a custom XStream {@link ConverterLookup} to use. + * Also used as {@link ConverterRegistry} if the given reference implements it as well. + * @since 4.0 + * @see DefaultConverterLookup */ - public void setMode(int mode) { - this.mode = mode; + public void setConverterLookup(ConverterLookup converterLookup) { + this.converterLookup = converterLookup; + } + + /** + * Set a custom XStream {@link ConverterRegistry} to use. + * @since 4.0 + * @see #setConverterLookup + * @see DefaultConverterLookup + */ + public void setConverterRegistry(ConverterRegistry converterRegistry) { + this.converterRegistry = converterRegistry; } /** @@ -183,6 +215,23 @@ public class XStreamMarshaller extends AbstractMarshaller implements Initializin this.converters = converters; } + /** + * Set a custom XStream {@link MarshallingStrategy} to use. + * @since 4.0 + */ + public void setMarshallingStrategy(MarshallingStrategy marshallingStrategy) { + this.marshallingStrategy = marshallingStrategy; + } + + /** + * Set the XStream mode to use. + * @see XStream#ID_REFERENCES + * @see XStream#NO_REFERENCES + */ + public void setMode(int mode) { + this.mode = mode; + } + /** * Set an alias/type map, consisting of string aliases mapped to classes. *

Keys are aliases; values are either {@code Class} instances, or String class names. @@ -226,8 +275,8 @@ public class XStreamMarshaller extends AbstractMarshaller implements Initializin * or {@code <Class, List<String>>} pairs, which results * in {@link XStream#useAttributeFor(Class, String)} calls. */ - public void setUseAttributeFor(Map useAttributesFor) { - this.useAttributesFor = useAttributesFor; + public void setUseAttributeFor(Map useAttributeFor) { + this.useAttributeFor = useAttributeFor; } /** @@ -298,10 +347,8 @@ public class XStreamMarshaller extends AbstractMarshaller implements Initializin * Build the native XStream delegate to be used by this marshaller. */ protected XStream buildXStream() { - XStream xstream = new XStream(null, this.streamDriver, this.beanClassLoader, this.mapper); - if (this.mode != null) { - xstream.setMode(this.mode); - } + XStream xstream = new XStream(this.reflectionProvider, this.streamDriver, + this.beanClassLoader, this.mapper, this.converterLookup, this.converterRegistry); if (this.converters != null) { for (int i = 0; i < this.converters.length; i++) { @@ -317,6 +364,13 @@ public class XStreamMarshaller extends AbstractMarshaller implements Initializin } } + if (this.marshallingStrategy != null) { + xstream.setMarshallingStrategy(this.marshallingStrategy); + } + if (this.mode != null) { + xstream.setMode(this.mode); + } + try { if (this.aliases != null) { Map> classMap = toClassMap(this.aliases); @@ -356,8 +410,8 @@ public class XStreamMarshaller extends AbstractMarshaller implements Initializin xstream.useAttributeFor(type); } } - if (this.useAttributesFor != null) { - for (Map.Entry entry : this.useAttributesFor.entrySet()) { + if (this.useAttributeFor != null) { + for (Map.Entry entry : this.useAttributeFor.entrySet()) { if (entry.getKey() instanceof String) { if (entry.getValue() instanceof Class) { xstream.useAttributeFor((String) entry.getKey(), (Class) entry.getValue());