/* * RapidMiner * * Copyright (C) 2001-2008 by Rapid-I and the contributors * * Complete list of developers available at our web site: * * http://rapid-i.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.tools; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.lang.reflect.Constructor; import com.rapidminer.example.AttributeRole; import com.rapidminer.example.NominalStatistics; import com.rapidminer.example.NumericalStatistics; import com.rapidminer.example.SimpleAttributes; import com.rapidminer.example.UnknownStatistics; import com.rapidminer.example.table.BinominalAttribute; import com.rapidminer.example.table.BinominalMapping; import com.rapidminer.example.table.NumericalAttribute; import com.rapidminer.example.table.PolynominalAttribute; import com.rapidminer.example.table.PolynominalMapping; import com.rapidminer.operator.IOContainer; /** * This class handles all kinds in- and output write processes for all kinds of objects * into and from XML. This class must use object streams since memory consumption is too * big otherwise. Hence, string based methods are no longer supported. * * @author Ingo Mierswa * @version $Id: XMLSerialization.java,v 1.5 2008/05/09 19:22:55 ingomierswa Exp $ */ public class XMLSerialization { private static XMLSerialization singleton; private com.thoughtworks.xstream.XStream xStream; public XMLSerialization(ClassLoader classLoader) { try { Class<?> xStreamClass = Class.forName("com.thoughtworks.xstream.XStream"); Class generalDriverClass = Class.forName("com.thoughtworks.xstream.io.HierarchicalStreamDriver"); Constructor constructor = xStreamClass.getConstructor(new Class[] { generalDriverClass }); Class driverClass = Class.forName("com.thoughtworks.xstream.io.xml.XppDriver"); xStream = (com.thoughtworks.xstream.XStream)constructor.newInstance(driverClass.newInstance()); xStream.setMode(com.thoughtworks.xstream.XStream.ID_REFERENCES); // define default aliases here addAlias("IOContainer", IOContainer.class); addAlias("PolynominalAttribute", PolynominalAttribute.class); addAlias("BinominalAttribute", BinominalAttribute.class); addAlias("NumericalAttribute", NumericalAttribute.class); addAlias("PolynominalMapping", PolynominalMapping.class); addAlias("BinominalMapping", BinominalMapping.class); addAlias("NumericalStatistics", NumericalStatistics.class); addAlias("NominalStatistics", NominalStatistics.class); addAlias("UnknownStatistics", UnknownStatistics.class); addAlias("SimpleAttributes", SimpleAttributes.class); addAlias("AttributeRole", AttributeRole.class); xStream.setClassLoader(classLoader); } catch (Throwable e) { LogService.getGlobal().log("Cannot initialize XML serialization. Probably the libraries 'xstream.jar' and 'xpp.jar' were not provided. XML serialization will not work!", LogService.ERROR); } } public static void init(ClassLoader classLoader) { singleton = new XMLSerialization(classLoader); } public void addAlias(String name, Class clazz) { if (xStream != null) { xStream.alias(name, clazz); } } public void writeXML(Object object, OutputStream out) throws IOException { if (xStream != null) { ObjectOutputStream xOut = xStream.createObjectOutputStream(new OutputStreamWriter(out)); xOut.writeObject(object); // flush is necessary since close is only invoked on the underlying stream... xOut.flush(); // XXX: leak of resources here since no close is invoked? } else { LogService.getGlobal().log("Cannot write XML serialization. Probably the libraries 'xstream.jar' and 'xpp.jar' were not provided...", LogService.ERROR); throw new IOException("Cannot write object with XML serialization."); } } public Object fromXML(InputStream in) throws IOException { if (xStream != null) { try { ObjectInputStream xIn = xStream.createObjectInputStream(new InputStreamReader(in)); Object result = null; try { result = xIn.readObject(); } catch (ClassNotFoundException e) { throw new IOException("Class not found: " + e.getMessage()); } // XXX: leak of resources here since no close is invoked? return result; } catch (Throwable e) { throw new IOException("Cannot read from XML stream, wrong format: " + e.getMessage()); } } else { LogService.getGlobal().log("Cannot read object from XML serialization. Probably the libraries 'xstream.jar' and 'xpp.jar' were not provided...", LogService.ERROR); throw new IOException("Cannot read object from XML serialization."); } } /** Returns the singleton instance. */ public static XMLSerialization getXMLSerialization() { return singleton; } }