/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2004 Bull S.A.
 * Contact: jonas-team@objectweb.org
 *
 * This library 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 any later version.
 *
 * This library 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 library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */
package org.objectweb.jonas_lib.xml;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

import org.apache.xml.serialize.Method;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.Serializer;
import org.apache.xml.serialize.SerializerFactory;
import org.w3c.dom.Document;


/**
 * Serialize a given DOM Document.
 * Handle namespaces nicely.
 *
 * @author Guillaume Sauthier
 */
public class XMLSerializer {

    /**
     * Indent size (char)
     */
    private static final int DEF_INDENT_SIZE = 4;

    /**
     * Maximum Line Width (char)
     */
    private static final int DEF_LINE_WIDTH = 80;

    /**
     * Maximum Line Width (char)
     */
    private static final String DEF_LINE_SEP = "\n";

    /**
     * Document to be formated and serialized
     */
    private Document doc;

    /**
     * XML Format
     */
    private OutputFormat format;

    /**
     * Serializer Factory
     */
    private SerializerFactory factory;

    /**
     * Creates a new XMLSerializer object.
     * @param doc Document to be serialized
     */
    public XMLSerializer(Document doc) {
        this.doc = doc;
        // define the format for the xml document
        format = new OutputFormat();
        setIndent(DEF_INDENT_SIZE);
        setLineSeparator(DEF_LINE_SEP);
        setLineWidth(DEF_LINE_WIDTH);

        // document serialization and writing
        factory = SerializerFactory.getSerializerFactory(Method.XML);
    }

    /**
     * Set the format line separator character.
     * @param sep line separator character
     */
    public void setLineSeparator(String sep) {
        format.setLineSeparator(sep);
    }

    /**
     * Set the format line width value.
     * @param width line width value
     */
    public void setLineWidth(int width) {
        format.setLineWidth(width);
    }

    /**
     * Set the format line indent value.
     * @param indent line indent value
     */
    public void setIndent(int indent) {
        format.setIndent(indent);
    }

    /**
     * Serialize the encapsulated Document into the OutputStream
     *
     * @param os output stream
     *
     * @throws IOException When serialization fails
     */
    public void serialize(OutputStream os) throws IOException {
        serialize(new OutputStreamWriter(os));
    }

    /**
     * Serialize the encapsulated Document into the Writer
     *
     * @param writer writer
     *
     * @throws IOException When serialization fails
     */
    public void serialize(Writer writer) throws IOException {
        Serializer genericSerializer = factory.makeSerializer(writer, format);
        org.apache.xml.serialize.XMLSerializer domSerializer = (org.apache.xml.serialize.XMLSerializer) genericSerializer.asDOMSerializer();

        domSerializer.setNamespaces(true);

        domSerializer.serialize(doc);
    }
}
