package org.prevayler.foundation.serialization;
import com.thoughtworks.xstream.XStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
/**
* Writes and reads objects using XML. This serializer can be used for snapshots, journals or both.
* <p>This implementation requires the <a href="http://xstream.codehaus.org/">XStream</a>
* Java and XML language binding framework which provides for Java object XML serialization.</p>
* <p>Note that XStream has some dependencies of its own. It requires the standard XML API's
* (xml-apis.jar from the <a href="http://xml.apache.org/xerces2-j/">Apache Xerces2-j</a> project or j2sdk1.4+)
* and an XML implementation (again, provided by Xerces2 or j2sdk1.4+).</p>
* <p>To make XStream up to 10x faster, add <a href="http://www.extreme.indiana.edu/xgws/xsoap/xpp/mxp1/">XPP3</a>
* to the classpath. XStream has the concept of a
* <a href="http://xstream.codehaus.org/javadoc/com/thoughtworks/xstream/io/HierarchicalStreamDriver.html">HierarchicalStreamDriver</a>
* and the default implementation for XStream is the highly performant XppDriver. However, XStream will fall back to the DomDriver if XPP3 is
* not found in the classpath making the XPP3 library entirely optional... well, not quite. See <a href="http://jira.codehaus.org/browse/XSTR-71">XSTR-71</a>.
* The current decision in that issue forces XPP3 to be a required runtime dependency when using XStream unless one specifically configures another driver, such as
* the DomDriver.</p>
*/
public class XStreamSerializer implements Serializer {
private ThreadLocal _xstreams=new ThreadLocal(){
protected Object initialValue(){
return createXStream();
}
}
;
private String _encoding;
/**
* Use the default character encoding for XML serialization.
*/
public XStreamSerializer(){
_encoding=null;
}
/**
* Use the specified character encoding for XML serialization.
*/
public XStreamSerializer( String encoding){
_encoding=encoding;
}
private XStream getXStream(){
return (XStream)_xstreams.get();
}
public void writeObject( OutputStream stream, Object object) throws IOException {
OutputStreamWriter writer=_encoding == null ? new OutputStreamWriter(stream) : new OutputStreamWriter(stream,_encoding);
getXStream().toXML(object,writer);
writer.flush();
}
public Object readObject( InputStream stream) throws IOException, ClassNotFoundException {
return getXStream().fromXML(_encoding == null ? new InputStreamReader(stream) : new InputStreamReader(stream,_encoding));
}
/**
* Create a new XStream instance. This must be a new instance because XStream instances are not threadsafe.
*/
protected XStream createXStream(){
return new XStream();
}
}