/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2004 Bull S.A.
 * Contact: jonas-team@ow2.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.ow2.jonas.lib.util;

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

import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSSerializer;


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

    /**
     * Default Line separator (unix).
     */
    private static final String DEF_LINE_SEP = "\n";

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

    /**
     * DOM L3 Serializer.
     */
    private LSSerializer serializer;

    /**
     * DOM L3 output.
     */
    private LSOutput output;

    /**
     * Creates a new XMLSerializer object.
     * @param doc Document to be serialized
     */
    public XMLSerializer(Document doc) {
        // Store the ref
        this.doc = doc;

        // Create the LSSerializer and LSOutput instances
        DOMImplementationRegistry registry;
        try {
            registry = DOMImplementationRegistry.newInstance();
        } catch (Exception e) {
            throw new RuntimeException("Cannot get the system DOMImplementationRegistry", e);
        }
        DOMImplementation impl = registry.getDOMImplementation("LS 3.0");
        DOMImplementationLS factory = (DOMImplementationLS) impl;

        // Define the format for the xml document
        serializer = factory.createLSSerializer();
        serializer.setNewLine(DEF_LINE_SEP);
        output = factory.createLSOutput();
        output.setEncoding("UTF-8");

        //DOMConfiguration dc = serializer.getDomConfig();
        //dc.setParameter("format-pretty-print", Boolean.TRUE);
        //dc.setParameter("schema-type", "http://www.w3.org/2001/XMLSchema");

    }

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

    /**
     * Serialize the encapsulated Document into the Writer
     *
     * @param writer writer
     *
     * @throws IOException When serialization fails
     */
    public void serialize(Writer writer) throws IOException {
        output.setCharacterStream(writer);
        serialize();
    }

    /**
     * Serialize the wrapped Document.
     */
    private void serialize() {
        serializer.write(doc, output);
    }
}
