diff --git a/oxm/pom.xml b/oxm/pom.xml
index 42e28aae..73eea56b 100644
--- a/oxm/pom.xml
+++ b/oxm/pom.xml
@@ -180,5 +180,11 @@
1.2_Java1.3
test
+
+ org.codehaus.jettison
+ jettison
+ 1.0-RC2
+ test
+
diff --git a/oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java b/oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java
index 714fd99a..34e34884 100644
--- a/oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java
+++ b/oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java
@@ -35,6 +35,7 @@ import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.ConverterMatcher;
import com.thoughtworks.xstream.converters.SingleValueConverter;
+import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.CompactWriter;
@@ -45,12 +46,6 @@ import com.thoughtworks.xstream.io.xml.SaxWriter;
import com.thoughtworks.xstream.io.xml.StaxReader;
import com.thoughtworks.xstream.io.xml.StaxWriter;
import com.thoughtworks.xstream.io.xml.XppReader;
-import org.springframework.beans.propertyeditors.ClassEditor;
-import org.springframework.oxm.AbstractMarshaller;
-import org.springframework.oxm.XmlMappingException;
-import org.springframework.util.ObjectUtils;
-import org.springframework.xml.stream.StaxEventContentHandler;
-import org.springframework.xml.stream.XmlEventStreamReader;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -59,6 +54,13 @@ import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;
+import org.springframework.beans.propertyeditors.ClassEditor;
+import org.springframework.oxm.AbstractMarshaller;
+import org.springframework.oxm.XmlMappingException;
+import org.springframework.util.ObjectUtils;
+import org.springframework.xml.stream.StaxEventContentHandler;
+import org.springframework.xml.stream.XmlEventStreamReader;
+
/**
* Implementation of the Marshaller interface for XStream. By default, XStream does not require any further
* configuration, though class aliases can be used to have more control over the behavior of XStream.
@@ -88,6 +90,9 @@ public class XStreamMarshaller extends AbstractMarshaller {
private Class[] supportedClasses;
+ /** Specialized driver to be used with stream readers and writers */
+ private HierarchicalStreamDriver streamDriver;
+
/**
* Returns the encoding to be used for stream access. If this property is not set, the default encoding is used.
*
@@ -153,6 +158,11 @@ public class XStreamMarshaller extends AbstractMarshaller {
}
}
+ /** Sets the XStream hierarchical stream driver to be used with stream readers and writers */
+ public void setStreamDriver(HierarchicalStreamDriver streamDriver) {
+ this.streamDriver = streamDriver;
+ }
+
/**
* Set a alias/type map, consisting of string aliases mapped to Class instances (or Strings to be
* converted to Class instances).
@@ -302,7 +312,12 @@ public class XStreamMarshaller extends AbstractMarshaller {
}
protected void marshalWriter(Object graph, Writer writer) throws XmlMappingException, IOException {
- marshal(graph, new CompactWriter(writer));
+ if (streamDriver != null) {
+ marshal(graph, streamDriver.createWriter(writer));
+ }
+ else {
+ marshal(graph, new CompactWriter(writer));
+ }
}
private Object unmarshal(HierarchicalStreamReader streamReader) {
@@ -347,7 +362,12 @@ public class XStreamMarshaller extends AbstractMarshaller {
}
protected Object unmarshalReader(Reader reader) throws XmlMappingException, IOException {
- return unmarshal(new XppReader(reader));
+ if (streamDriver != null) {
+ return unmarshal(streamDriver.createReader(reader));
+ }
+ else {
+ return unmarshal(new XppReader(reader));
+ }
}
protected Object unmarshalSaxReader(XMLReader xmlReader, InputSource inputSource)
@@ -355,4 +375,6 @@ public class XStreamMarshaller extends AbstractMarshaller {
throw new UnsupportedOperationException(
"XStreamMarshaller does not support unmarshalling using SAX XMLReaders");
}
+
+
}
diff --git a/oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTest.java b/oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTest.java
index e42b86ee..fba1597a 100644
--- a/oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTest.java
+++ b/oxm/src/test/java/org/springframework/oxm/xstream/XStreamMarshallerTest.java
@@ -32,16 +32,18 @@ import javax.xml.transform.stream.StreamResult;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.extended.EncodedByteArrayConverter;
+import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
import org.custommonkey.xmlunit.XMLTestCase;
import org.easymock.MockControl;
-import org.springframework.xml.transform.StaxResult;
-import org.springframework.xml.transform.StringResult;
-import org.springframework.xml.transform.StringSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import org.xml.sax.ContentHandler;
+import org.springframework.xml.transform.StaxResult;
+import org.springframework.xml.transform.StringResult;
+import org.springframework.xml.transform.StringSource;
+
public class XStreamMarshallerTest extends XMLTestCase {
private static final String EXPECTED_STRING = "42";
@@ -161,5 +163,16 @@ public class XStreamMarshallerTest extends XMLTestCase {
assertXMLEqual("Marshaller does not use attributes", expected, result.toString());
}
+ public void testDriver() throws Exception {
+ marshaller.setStreamDriver(new JettisonMappedXmlDriver());
+ StringResult result = new StringResult();
+ marshaller.marshal(flight, result);
+ assertEquals("Invalid result", "{\"flight\":{\"flightNumber\":\"42\"}}", result.toString());
+ Object o = marshaller.unmarshal(new StringSource(result.toString()));
+ assertTrue("Unmarshalled object is not Flights", o instanceof Flight);
+ Flight unflight = (Flight) o;
+ assertNotNull("Flight is null", unflight);
+ assertEquals("Number is invalid", 42L, unflight.getFlightNumber());
+ }
}