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(); } }