All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.enhydra.xml.io.DOMFormatter Maven / Gradle / Ivy

The newest version!
/*
 * Enhydra Java Application Server Project
 * 
 * The contents of this file are subject to the Enhydra Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License on
 * the Enhydra web site ( http://www.enhydra.org/ ).
 * 
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 
 * the License for the specific terms governing rights and limitations
 * under the License.
 * 
 * The Initial Developer of the Enhydra Application Server is Lutris
 * Technologies, Inc. The Enhydra Application Server and portions created
 * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
 * All Rights Reserved.
 * 
 * Contributor(s):
 * 
 * $Id: DOMFormatter.java,v 1.3 2005/01/26 08:29:24 jkjome Exp $
 */

package org.enhydra.xml.io;

import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;

import org.enhydra.xml.dom.DOMAccess;
import org.enhydra.xml.dom.DOMOps;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.html.HTMLDocument;

//FIXME: could cache type-specific formatters...

//FIXME: Do we really need to create a DOMformatter per output options?
//why not make this a cache of fromatters.

//FIXME: Need ability to output XHTML DOM as HTML and HTML DOM as XHTML

/**
 * Class for formatting DOMs into a documents.  The class handles XML and
 * HTML pages, looking up the approriate formatting routines based on the
 * document type.  It has an associated OutputOptions object that controls the
 * formatting.  Instances are reusable and multithreaded.
 */
public class DOMFormatter {
    /**
     * XHTML Namespace
     */
    private static final String XHTML_NAMESPACE_URI
        = "http://www.w3.org/1999/xhtml";

    /**
     * Output options.
     */
    private OutputOptions fOptions;

    /**
     * Construct a new XML formatter with the specified
     * output options.
     * @param outputOptions The OutputOptions to use for formatters
     *  obtained from this object.
     */
    public DOMFormatter(OutputOptions outputOptions) {
        fOptions = outputOptions;
        if (fOptions == null) {
            fOptions = new OutputOptions();
        }
    }
    
    /**
     * Construct a new XML formatter with default output options.
     */
    public DOMFormatter() {
        this(null);
    }

    /**
     * Get the output options.
     */
    public OutputOptions getOutputOptions() {
        return fOptions;
    }
    
    /**
     * Set the output options.
     */
    public void setOutputOptions(OutputOptions outputOptions) {
        fOptions = outputOptions;
    }

    /**
     * Get the default OutputOptions for a document.  The encoding will
     * not be set, which signals to use the default encoding.
     */
    public static OutputOptions getDefaultOutputOptions(Document doc) {
        if ((doc instanceof HTMLDocument) && !isXHTMLDocument(doc)) {
            return HTMLFormatter.getDefaultOutputOptions();
        } else {
            return XMLFormatter.getDefaultOutputOptions();
        }
    }

    /**
     * Determine if a document implementing HTMLDocument is an
     * XHTML document.
     */
    private static boolean isXHTMLDocument(Document document) {
        // Must get element with out expanding if a LazyDOM.
        Element docElement =  DOMAccess.accessDocumentElement(document);

        // Coded this way since URI can be null.
        return (docElement != null)
            && XHTML_NAMESPACE_URI.equals(docElement.getNamespaceURI());
    }

    /**
     * Determine the type of the formatter to use.
     */
    private static OutputOptions.Format determineFormat(OutputOptions outputOptions,
                                                        Node node) {
        OutputOptions.Format format = outputOptions.getFormat();
        if (format == OutputOptions.FORMAT_AUTO) {
            // XHTML DOM is optional and it implements HTMLDocument, so
            // we need to check the namespace
            Document doc = DOMOps.getDocument(node);
            if ((doc instanceof HTMLDocument) && !isXHTMLDocument(doc)) {
                format = OutputOptions.FORMAT_HTML;
            } else {
                format = OutputOptions.FORMAT_XML;
            }
        }
        return format;
    }
    
    /*
     * Factory for Formatter objects base on the document type.
     * This is currently used only my XMLC, this interface may change in the
     * future.
     */
    public static Formatter getFormatter(Node node,
                                         OutputOptions outputOptions,
                                         boolean forPreFormatting) {
        OutputOptions.Format format = determineFormat(outputOptions, node);
        if (format == OutputOptions.FORMAT_HTML) {
            return new HTMLFormatter(node, outputOptions, forPreFormatting);
        } else {
            return new XMLFormatter(node, outputOptions, forPreFormatting);
        }
    }

    /**
     * Format a document or any node and its children into a string.
     */
    public String toString(Node node) {
        Formatter formatter = getFormatter(node, fOptions, false);
        StringWriter writer = new StringWriter();
        try {
            formatter.write(node, writer);
        } catch (IOException except) {
            // Should never happen on String output
            throw new XMLIOError(except);
        }
        return writer.toString();
    }

    /**
     * Format a document or any node and its children into a byte array using
     * the current encoding.
     */
    public byte[] toBytes(Node node) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        write(node, out);
        return out.toByteArray();
    }

    /**
     * Output a document or any node and its children to a Writer.
     */
    public void write(Node node,
                      Writer writer) throws IOException {
        Formatter formatter = getFormatter(node, fOptions, false);
        formatter.write(node, writer);
    }

    /**
     * Output a document or any node and its children to a OutputStream.
     */
    public void write(Node node,
                      OutputStream out) throws IOException {
        Formatter formatter = getFormatter(node, fOptions, false);
        Writer writer = new BufferedWriter(new OutputStreamWriter(out, 
                                               formatter.getMIMEEncoding()));
        formatter.write(node, writer);
        writer.flush();
    }

    /**
     * Output a document or any node and its children to a File.
     */
    public void write(Node node,
                      File out) throws IOException {
        OutputStream outStream
            = new BufferedOutputStream(new FileOutputStream(out));
        try {
            write(node, outStream);
        } finally {
            outStream.close();
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy