/* * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.xwiki.store.serialization.xml.internal; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.xml.sax.SAXException; import org.xwiki.component.annotation.ComponentRole; import org.xwiki.store.serialization.xml.XMLSerializer; /** * A Serializer which converts objects into XML Elements and back. * * @param <R> The class of object which the serializer can serialize (what it requires). * @param <P> The class of object which will be provided by this serializer when it parses data. * @version $Id: 9190cbe2d0953b5785682045b78dec1980c9bd98 $ * @since 3.0M2 */ // Note: We cannot replace @ComponentRole with @Role ATM since @Role supports generics and we have // AbstractXMLSerializer<R, P extends R>. Changing it will thus break all code looking up components implementing this // role. @ComponentRole public abstract class AbstractXMLSerializer<R, P extends R> implements XMLSerializer<R, P> { @Override public InputStream serialize(final R object) throws IOException { // This puts everything on the heap for now. // if size becomes a major problem, the alternitive is to fork over another thread // and use a PipedInputStream. final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final XMLWriter writer; try { // This should always be UTF-8 because it is a property of the serializer. final OutputFormat of = new OutputFormat(" ", true, "UTF-8"); writer = new XMLWriter(baos, of); writer.startDocument(); } catch (SAXException e) { throw new IOException("Could not open the XML writer."); } this.serialize(object, writer); try { writer.endDocument(); } catch (SAXException e) { throw new IOException("Could not close the XML writer."); } return new ByteArrayInputStream(baos.toByteArray()); } @Override public P parse(final InputStream stream) throws IOException { final SAXReader reader = new SAXReader(); // Remove nodes generated by indentation. reader.setStripWhitespaceText(true); reader.setMergeAdjacentText(true); final Document domdoc; try { domdoc = reader.read(stream); } catch (DocumentException e) { throw new IOException("Failed to parse XML, probably malformed input."); } return this.parse(domdoc.getRootElement()); } }