Hi,
a small piece of code that I would like to share. Below is the implementation of a XStream Converter that wraps all EncogPersistableObjects. Thus, it is straight-forward to use encog's native persistance features with XStream.
Just annotate the respective field with @XStreamConverter(EncogPersistableXMLConverter.class) and make sure that the following class is in your class-path.
THE CODE:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringReader;
import org.encog.parse.tags.read.ReadXML;
import org.encog.parse.tags.write.WriteXML;
import org.encog.persist.EncogPersistedObject;
import org.encog.persist.Persistor;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import com.thoughtworks.xstream.XStreamException;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
/**
* This is a wrapper for the native persistent framework of ENCOG. It
* encapsulates the storage mechanism of {@link EncogPersistedObject}
* for {@link XStream}.
*
* @author kramer_d
*
*/
public class EncogPersistableXMLConverter implements Converter {
private final static String DEFAULT_NAME = "xstream-persisted";
private final static String PERSISTOR_PARAM = "persistor";
public void marshal(Object source, HierarchicalStreamWriter writer,
MarshallingContext context) {
EncogPersistedObject object = (EncogPersistedObject) source;
// Use a StringWriter as buffer for the network data
Persistor persistor = object.createPersistor();
ByteArrayOutputStream out = new ByteArrayOutputStream();
// Write persistor class for unmarshalling
writer.addAttribute(PERSISTOR_PARAM, persistor.getClass().getName());
// Catch the silly name exception of ENCOG
if ( object.getName() == null )
object.setName(DEFAULT_NAME);
persistor.save(object, new WriteXML(out));
try {
marshalXML(out.toString(),writer);
} catch ( Exception e ) {
throw new RuntimeException(e);
}
}
private void marshalXML(String xml, HierarchicalStreamWriter writer) throws XmlPullParserException, IOException {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance(
System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null);
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput ( new StringReader(xml) );
int eventType = xpp.getEventType();
do {
if(eventType == XmlPullParser.START_DOCUMENT) {
} else if(eventType == XmlPullParser.END_DOCUMENT) {
} else if(eventType == XmlPullParser.START_TAG) {
writer.startNode(xpp.getName());
for ( int j =0 ; j < xpp.getAttributeCount() ; ++j ) {
writer.addAttribute(xpp.getAttributeName(j), xpp.getAttributeValue(j));
}
} else if(eventType == XmlPullParser.END_TAG) {
writer.endNode();
} else if(eventType == XmlPullParser.TEXT) {
writer.setValue(xpp.getText());
}
eventType = xpp.next();
} while (eventType != XmlPullParser.END_DOCUMENT);
}
private String unmarshalXML(HierarchicalStreamReader reader) {
StringBuffer buffer = new StringBuffer();
writeTagToBuffer(buffer,reader);
return buffer.toString();
}
private void writeTagToBuffer(StringBuffer buffer, HierarchicalStreamReader reader) {
buffer.append("<" + reader.getNodeName());
for ( int j = 0 ; j < reader.getAttributeCount() ; ++j ) {
buffer.append(" " + reader.getAttributeName(j) + "=\""+ reader.getAttribute(j) + "\"");
}
buffer.append(">");
while ( reader.hasMoreChildren() ) {
reader.moveDown();
writeTagToBuffer(buffer,reader);
reader.moveUp();
}
buffer.append(reader.getValue());
buffer.append("");
}
public Object unmarshal(HierarchicalStreamReader reader,
UnmarshallingContext context) {
String persClass = reader.getAttribute(PERSISTOR_PARAM);
reader.moveDown();
String in = unmarshalXML(reader);
reader.moveUp();
ByteArrayInputStream is = new ByteArrayInputStream(in.getBytes());
Persistor persistor;
try {
persistor = (Persistor) Class.forName(persClass).newInstance();
} catch (Exception e) { throw new XStreamException(e); }
EncogPersistedObject object = (EncogPersistedObject) persistor.load(new ReadXML(is));
return object;
}
@SuppressWarnings("unchecked")
public boolean canConvert(Class type) {
return (EncogPersistedObject.class.isAssignableFrom(type));
}
}
Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer
Thanks
That is very helpful. I've been considering using something like xstream to replace the current persistence model used in Encog. Xstream is available for .Net as well, it looks like, so this could be very useful. Thanks for posting this!