/* * This file is part of Alida, a Java library for * Advanced Library for Integrated Development of Data Analysis Applications. * * Copyright (C) 2010 - @YEAR@ * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Fore more information on Alida, visit * * http://www.informatik.uni-halle.de/alida/ * */ /* * Most recent change(s): * * $Rev$ * $Date$ * $Author$ * */ package de.unihalle.informatik.Alida.dataio; import de.unihalle.informatik.Alida.dataio.ALDDataIOManagerXmlbeans; import de.unihalle.informatik.Alida.dataio.provider.ALDDataIOXmlbeans; import de.unihalle.informatik.Alida.exceptions.ALDDataIOManagerException; import de.unihalle.informatik.Alida.exceptions.ALDDataIOProviderException; import de.unihalle.informatik.Alida.exceptions.ALDDataIOProviderException.ALDDataIOProviderExceptionType; import de.unihalle.informatik.Alida_xml.ALDXMLDocument; import de.unihalle.informatik.Alida_xml.ALDXMLObjectType; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.lang.reflect.Field; import org.apache.xmlbeans.XmlException; /** * This class implements a DataIO manager for reading/writing from xml using xmlbeans. * For reading and writing, it essentially looks up the correct provider for xml * using the method of its super class and invokes its method. * <p> * It does its work in collaboration with {@link de.unihalle.informatik.Alida.dataio.provider.ALDDataIOXmlbeans}. * * @author posch * */ public class ALDDataIOManagerXmlbeans extends ALDDataIOManager { /** * If true writeData should try to write the history to file * if the object itself is written to a file */ private boolean doHistory = false; /** * If true additional fields/variables and so on should be tolerated by providers */ private boolean allowAdditionalFields = false; /** The singleton instance of this class */ static final ALDDataIOManagerXmlbeans instance; static { instance = new ALDDataIOManagerXmlbeans(); } /** private constructor */ private ALDDataIOManagerXmlbeans() { this.mapTable = initMapTable(ALDDataIOXmlbeans.class); } /** Return the single instance of this class * @return single instance */ public static ALDDataIOManagerXmlbeans getInstance() { return instance; } /** * Reads data of given class from a specified source. * If both <code>field</code> and <code>cl</code> are non-null, the class defined in <code>field</code> is used * and <code>cl</code> ignored. * * If one of <code>field or</code> <code>cl</code> is null, the other non null argument will be used. * Some objects can only be read if <code>field</code> is supplied, e.g. Collections. * <p> * The <code>aldXmlObject</code> is used to actually read the data. The interpretation is * specific to the class to be read and defined by the corresponding provider class. * As a minimum this xml object contains the class name of the object represented. * * @param field field of object to be returned. * @param cl Class of data to be read. * @param aldXmlObject xml object to read data from. * @return Read data object * @throws ALDDataIOManagerException * @throws ALDDataIOProviderException */ public Object readData(Field field, Class<?> cl, ALDXMLObjectType aldXmlObject) throws ALDDataIOManagerException, ALDDataIOProviderException { if ( field != null ) cl = field.getType(); if ( cl == null ) { throw new ALDDataIOProviderException( ALDDataIOProviderExceptionType.OBJECT_TYPE_ERROR, "ALDDataIOManagerXmlbeans::readData cannot read object if class equals null"); } ALDDataIOXmlbeans provider = (ALDDataIOXmlbeans)getProvider( cl, ALDDataIOXmlbeans.class); return provider.readData( field, cl, aldXmlObject); } /** * Writes data to the specified location. * This method returns a xml object with a representation of parameters value. * * @param obj Object to write. * @return ALDXMLObjectType representing the <code>obj</code> * @throws ALDDataIOManagerException * @throws ALDDataIOProviderException */ public ALDXMLObjectType writeData(Object obj) throws ALDDataIOManagerException, ALDDataIOProviderException { if ( obj == null ) { return null; } Class cl = obj.getClass(); ALDDataIOXmlbeans provider = (ALDDataIOXmlbeans)getProvider( cl, ALDDataIOXmlbeans.class); return provider.writeData(obj); } /** * @return the writeHistory */ public boolean isDoHistory() { return this.doHistory; } /** * @param doHistory the writeHistory to set */ public void setDoHistory(boolean doHistory) { this.doHistory = doHistory; } /** * @return the allowAdditionalFields */ public boolean isAllowAdditionalFields() { return this.allowAdditionalFields; } /** * @param allowAdditionalFields the allowAdditionalFields to set */ public void setAllowAdditionalFields(boolean allowAdditionalFields) { this.allowAdditionalFields = allowAdditionalFields; } /** * Write to object to a file using xmlbeans providers * * @param filename * @param obj * @throws ALDDataIOProviderException * @throws ALDDataIOManagerException */ public static void writeXml( String filename, Object obj) throws ALDDataIOProviderException, ALDDataIOManagerException { ALDDataIOManagerXmlbeans.writeXml(new File( filename), obj); } /** * Write the object to a file using xmlbeans providers * * @param file * @param obj * @throws ALDDataIOProviderException * @throws ALDDataIOManagerException */ public static void writeXml( File file, Object obj) throws ALDDataIOProviderException, ALDDataIOManagerException { ALDDataIOXmlbeans provider; // we need to get class load of the object to write to find the .xsb files in the jar ClassLoader mainLoader = Thread.currentThread().getContextClassLoader(); ClassLoader objLoader = obj.getClass().getClassLoader(); if (objLoader != null ) { Thread.currentThread().setContextClassLoader(objLoader); } if ( debug ) { System.out.println("ALDDataIOManagerXmlbeans::writeXml: new classloader = " + Thread.currentThread().getContextClassLoader() + ", old: " + mainLoader); } provider = (ALDDataIOXmlbeans)ALDDataIOManagerXmlbeans.getInstance(). getProvider(obj.getClass(), ALDDataIOXmlbeans.class); ALDXMLObjectType xmlObj = provider.writeData(obj); BufferedWriter bufWriter = null; try { bufWriter = new BufferedWriter(new FileWriter( file)); } catch (IOException e) { throw new ALDDataIOProviderException( ALDDataIOProviderExceptionType.FILE_IO_ERROR, "ALDDataIOManagerXmlbeans::writeXml cannot open writer for filename <" + file.getAbsolutePath() + ">"); } try { try { ALDXMLDocument doc = ALDXMLDocument.Factory.newInstance(); doc.setALDXML(xmlObj); doc.save(bufWriter); bufWriter.flush(); bufWriter.close(); } catch (IOException e1) { throw new ALDDataIOProviderException( ALDDataIOProviderExceptionType.FILE_IO_ERROR, "ALDDataIOManagerXmlbeans::writeXml error writing to file <" + file.getAbsolutePath() + ">"); } } finally { Thread.currentThread().setContextClassLoader(mainLoader); } } /** * Read Object from a file using xmlbeans providers * * @param filename * @param clazz * @return Object read from XML file. * @throws XmlException * @throws IOException * @throws ALDDataIOManagerException * @throws ALDDataIOProviderException */ public static Object readXml( String filename, Class<?> clazz) throws XmlException, ALDDataIOManagerException, ALDDataIOProviderException { return ALDDataIOManagerXmlbeans.readXml(new File( filename), clazz); } /** * Read Object from a file using xmlbeans providers * * @param file * @param clazz * @return Object read from XML file. * @throws XmlException * @throws IOException * @throws ALDDataIOManagerException * @throws ALDDataIOProviderException */ public static Object readXml( File file, Class<?> clazz) throws XmlException, ALDDataIOManagerException, ALDDataIOProviderException { ALDDataIOXmlbeans provider; BufferedReader reader; ALDXMLDocument document; Object obj; try { reader = new BufferedReader( new FileReader(file)); } catch (FileNotFoundException e) { throw new ALDDataIOProviderException( ALDDataIOProviderExceptionType.FILE_IO_ERROR, "ALDDataIOManagerXmlbeans::readXml error reading from file <" + file.getAbsolutePath() + ">"); } // we need to get the class loader of the class to read to find the .xsb files in the jar ClassLoader mainLoader = Thread.currentThread().getContextClassLoader(); ClassLoader objLoader = clazz.getClassLoader(); if (objLoader != null ) { Thread.currentThread().setContextClassLoader(objLoader); } if ( debug ) { System.out.println("ALDDataIOManagerXmlbeans::readXml new classloader = " + Thread.currentThread().getContextClassLoader() + ", old: " + mainLoader); } try { try { document = ALDXMLDocument.Factory.parse(reader); } catch (IOException e) { throw new ALDDataIOProviderException( ALDDataIOProviderExceptionType.SYNTAX_ERROR, "ALDDataIOManagerXmlbeans::readXml cannot read xml form file <" + file.getAbsolutePath() + ">"); } ALDXMLObjectType xmlObj = document.getALDXML(); provider = (ALDDataIOXmlbeans)(ALDDataIOManagerXmlbeans.getInstance(). getProvider( clazz, ALDDataIOXmlbeans.class)); obj = provider.readData( null, clazz, xmlObj); } finally { Thread.currentThread().setContextClassLoader(mainLoader); } return obj; } }