// Licensed to the Apache Software Foundation (ASF) under one or more contributor
// license agreements.  See the NOTICE.txt file distributed with this work for
// additional information regarding copyright ownership.  The ASF licenses this
// file to you under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License.  You may obtain a copy of
// the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
// License for the specific language governing permissions and limitations under
// the License.
//
// Portions of this code come from the Apache XML Project's Xerces 1.0.3 XML Parser
// (specifically, the functions escape and getEntityRef).  Apache license applies:
//
// The Apache Software License, Version 1.1
//
// Copyright (c) 1999 The Apache Software Foundation.  All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
//     conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
//    of conditions and the following disclaimer in the documentation and/or other materials
//    provided with the distribution.
//
// 3. The end-user documentation included with the redistribution, if any, must include
//    the following acknowledgment:
//
//    "This product includes software developed by the Apache Software Foundation (http://www.apache.org/)."
//
//    Alternately, this acknowledgment may appear in the software itself,
//    if and wherever such third-party acknowledgments normally appear.
//
// 4. The names "Xerces" and "Apache Software Foundation" must not be used to endorse or
//    promote products derived from this software without prior written permission. For
//    written permission, please contact apache@apache.org.
//
// 5. Products derived from this software may not be called "Apache", nor may "Apache"
//    appear in their name, without prior written permission of the Apache Software
//    Foundation.
//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
// ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// $Id: XML.java,v 1.2 2005-05-01 22:49:55 cmattmann Exp $

package org.apache.oodt.commons.util;

import java.io.*;
import java.util.*;
import org.w3c.dom.*;
import org.xml.sax.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.TransformerException;
import javax.xml.transform.OutputKeys;

/** XML services.
 *
 * This class provides several XML convenience services and encapsulates the underlying
 * XML implementation, allowing it to vary without impacting developers.
 *
 * @author Kelly
 */
public class XML {
	private static DocumentBuilder getStandardDocumentBuilder() {
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			factory.setCoalescing(false);
			factory.setExpandEntityReferences(false);
			factory.setIgnoringComments(false);
			factory.setIgnoringElementContentWhitespace(true);
			factory.setNamespaceAware(true);
			factory.setValidating(true);
			return factory.newDocumentBuilder();
		} catch (ParserConfigurationException ex) {
			throw new IllegalStateException("Unexpected ParserConfigurationException: " + ex.getMessage());
		}
	}

	/** Get the DOM implementation.
	 *
	 * @return The DOM implementation.
	 */
	public static DOMImplementation getDOMImplementation() {
		return getStandardDocumentBuilder().getDOMImplementation();
	}

	/** Create a DOM document.
	 *
	 * @return A new DOM document.
	 */
	public static Document createDocument() {
		return getStandardDocumentBuilder().newDocument();
	}

	/** Create a DOM parser.
	 *
	 * This method creates a new DOM parser that has validation turned on and
	 * ignorable whitespace not included, and has a default error handler that prints
	 * error messages and warnings to the standard error stream.
	 *
	 * @return A new DOM parser.
	 */
	public static DOMParser createDOMParser() {
		DocumentBuilder builder = getStandardDocumentBuilder();
		builder.setEntityResolver(ENTERPRISE_ENTITY_RESOLVER);
		builder.setErrorHandler(new ErrorHandler() {
			public void error(SAXParseException ex) {
				System.err.println("Parse error: " + ex.getMessage());
				ex.printStackTrace();
			}
			public void warning(SAXParseException ex) {
				System.err.println("Parse warning: " + ex.getMessage());
			}
			public void fatalError(SAXParseException ex) {
				System.err.println("Fatal parse error: " + ex.getMessage());
				ex.printStackTrace();
			}
		});
		return new DOMParser(builder);
	}

	/** Create a SAX parser.
	 *
	 * This method creates a new, default SAX parser.  It's set up with a default
	 * error handler that just prints messages to the standard error stream.
	 *
	 * @return A new SAX parser.
	 */
	public static SAXParser createSAXParser() {
		try {
			SAXParserFactory factory = SAXParserFactory.newInstance();
			factory.setNamespaceAware(false);
			factory.setValidating(false);
			javax.xml.parsers.SAXParser saxParser = factory.newSAXParser();
			saxParser.getXMLReader().setEntityResolver(ENTERPRISE_ENTITY_RESOLVER);
			saxParser.getXMLReader().setErrorHandler(new ErrorHandler() {
				public void error(SAXParseException ex) {
					System.err.println("Parse error: " + ex.getMessage());
				}
				public void warning(SAXParseException ex) {
					System.err.println("Parse warning: " + ex.getMessage());
				}
				public void fatalError(SAXParseException ex) {
					System.err.println("Fatal parse error: " + ex.getMessage());
				}
			});
			SAXParser p = new SAXParser(saxParser);
			return p;
		} catch (ParserConfigurationException ex) {
			throw new IllegalStateException("Unexpected ParserConfigurationException: " + ex.getMessage());
		} catch (SAXException ex) {
			throw new IllegalStateException("Unexpected SAXException: " + ex.getMessage());
		}
	}

	/** Serialize an XML DOM document into a String.
	 *
	 * This method takes a DOM document and pretty-prints (or pretty-serializes, in
	 * XML parlance) it into a string.
	 *
	 * @param doc The document.
	 * @param omitXMLDeclaration True if we should omit the XML declaration, false to keep the XML declaration.
	 * @return The pretty-serialized, stringified, document.
	 */
	public static String serialize(Document doc, boolean omitXMLDeclaration) {
		StringWriter writer = new StringWriter();
		try {
			serialize(doc, writer, omitXMLDeclaration);
		} catch (IOException cantHappen) {}
		return writer.getBuffer().toString();
	}

	/** Serialize an XML DOM document into a String.
	 *
	 * This method takes a DOM document and pretty-prints (or pretty-serializes, in
	 * XML parlance) it into a string.
	 *
	 * @param doc The document.
	 * @return The pretty-serialized, stringified, document.
	 */
	public static String serialize(Document doc) {
		return serialize(doc, /*omitXMLDeclaration*/false);
	}

	/** Serialize an XML DOM document into a writer.
	 *
	 * This method takes a DOM document and pretty-prints (or pretty-serializes, in
	 * XML parlance) it into a writer.
	 *
	 * @param doc The document.
	 * @param writer Where to write it.
	 * @param omitXMLDeclaration True if we should omit the XML declaration, false to keep the XML declaration.
	 * @throws IOException If an I/O error occurs.
	 */
	public static void serialize(Document doc, Writer writer, boolean omitXMLDeclaration) throws IOException {
		try {
			TransformerFactory factory = TransformerFactory.newInstance();
			Transformer transformer = factory.newTransformer();
			
			//update 05/01/2005
			//author: Chris Mattmann
			//set properties to pretty print
			//and also to include the DOCTYPE when serializing the XML
			
			//only set this if it's not null else we get a nice NullPointerException
			if(doc.getDoctype().getPublicId() != null){
				transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doc.getDoctype().getPublicId());			    
			}

			//only set this if it's not null else we get a nice NullPointerException
			if(doc.getDoctype().getSystemId() != null){
				transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());			    
			}

			transformer.setOutputProperty(OutputKeys.INDENT,"yes");
			
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(writer);
			transformer.transform(source, result);
		} catch (TransformerConfigurationException ex) {
			throw new IllegalStateException("Unexpected TransformerConfigurationException: " + ex.getMessage());
		} catch (TransformerException ex) {
			throw new IllegalStateException("Unexpected TransformerException: " + ex.getMessage());
		}
	}

	/** Serialize an XML DOM document into a writer.
	 *
	 * This method takes a DOM document and pretty-prints (or pretty-serializes, in
	 * XML parlance) it into a writer.
	 *
	 * @param doc The document.
	 * @param writer Where to write it.
	 * @throws IOException If an I/O error occurs.
	 */
	public static void serialize(Document doc, Writer writer) throws IOException {
		serialize(doc, writer, /*omitXMLDeclaration*/false);
	}

	/** Parse the given XML document into a DOM tree.
	 *
	 * @param inputSource The XML document to parse.
	 * @return A DOM tree for the given XML document.
	 * @throws SAXException If a parse error occurs.
	 * @throws IOException If an I/O error occurs.
	 */
	public static Document parse(InputSource inputSource) throws SAXException, IOException {
		DOMParser parser = XML.createDOMParser();
		parser.parse(inputSource);
		return parser.getDocument();
	}

	/** Parse the given XML document into a DOM tree.
	 *
	 * @param string The XML document to parse.
	 * @return A DOM tree for the given XML document.
	 * @throws SAXException If a parse error occurs.
	 */
	public static Document parse(String string) throws SAXException {
		Document doc = null;
		try {
			DOMParser parser = XML.createDOMParser();
			StringReader reader = new StringReader(string);
			InputSource inputSource = new InputSource(reader);
			doc = parse(inputSource);
			reader.close();
		} catch (IOException cantHappen) {
			cantHappen.printStackTrace();
			throw new RuntimeException("I/O exception " + cantHappen.getClass().getName()
				+ " can NOT have happened, yet it did!  Message: " + cantHappen.getMessage());
		}
		return doc;
	}

	/** Parse the given XML document into a DOM tree.
	 *
	 * @param reader The XML document to parse.
	 * @return A DOM tree for the given XML document.
	 * @throws SAXException If a parse error occurs.
	 * @throws IOException If an I/O error occurs.
	 */
	public static Document parse(Reader reader) throws SAXException, IOException {
		return parse(new InputSource(reader));
	}

	/** Parse the given XML document into a DOM tree.
	 *
	 * @param inputStream The XML document to parse.
	 * @return A DOM tree for the given XML document.
	 * @throws SAXException If a parse error occurs.
	 * @throws IOException If an I/O error occurs.
	 */
	public static Document parse(InputStream inputStream) throws SAXException, IOException {
		return parse(new InputStreamReader(inputStream));
	}

	/** Add a repeating child element with text from the given collection to the given node.
	 *
	 * For example, if <var>values</var> is a {@link java.util.List} with strings items
	 * "a", "b", and "c", and <var>name</var> is "value", then the XML document will
	 * have
	 * <pre>&lt;value&gt;a&lt;/value&gt;
	 * &lt;value&gt;b&lt;/value&gt;
	 * &lt;value&gt;c&lt;/value&gt;</pre>
	 * appended to <var>node</var>.
	 *
	 * @param node Node to which to add child elements.
	 * @param name Name to give each child element.
	 * @param values Collection of values to assign to each child element, in iterator order.
	 * @throws DOMException If a DOM error occurs.
	 */
	public static void add(Node node, String name, Collection values) throws DOMException {
		for (Iterator i = values.iterator(); i.hasNext();)
			add(node, name, i.next());
	}

	/** Add a child element with the given text to the given element.
	 *
	 * This method modifies your DOM tree so that
	 * <pre>&lt;node&gt;
	 *   ...
	 * &lt;/node&gt;</pre>
	 * becomes
	 * <pre>&lt;node&gt;
	 *   ...
	 *   &lt;name&gt;text&gt;/name&gt;
	 * &lt;/node&gt;</pre>
	 *
	 * Adding a null <var>name</var> does nothing.  Adding null <var>text</var>
	 * won't add the element.
	 *
	 * @param node Node to which to add a child element.
	 * @param name Name of the child element to add to <var>node</var>.
	 * @param text What text the text-node child the child element named <var>name</var> should have.  If null,
	 * nothing happens.
	 * @throws DOMException If a DOM error occurs.
	 */
	public static void addNonNull(Node node, String name, String text) throws DOMException {
		if (text == null) return;
		add(node, name, text);
	}

	/** Add a child element with the given text to the given element.
	 *
	 * This method modifies your DOM tree so that
	 * <pre>&lt;node&gt;
	 *   ...
	 * &lt;/node&gt;</pre>
	 * becomes
	 * <pre>&lt;node&gt;
	 *   ...
	 *   &lt;name&gt;text&gt;/name&gt;
	 * &lt;/node&gt;</pre>
	 *
	 * Adding a null <var>name</var> does nothing.  Adding null <var>text</var>
	 * results in an empty <var>name</var> tag.
	 *
	 * @param node Node to which to add a child element.
	 * @param name Name of the child element to add to <var>node</var>.
	 * @param text What text the text-node child the child element named <var>name</var> should have.
	 * @throws DOMException If a DOM error occurs.
	 */
	public static void add(Node node, String name, String text) throws DOMException {
		if (name == null) return;
		if (node == null) throw new IllegalArgumentException("Can't add to a null node");
		Document doc = node.getOwnerDocument();
		Element element = doc.createElement(name);
		if (text != null) element.appendChild(doc.createTextNode(text));
		node.appendChild(element);
	}

	/** Add a child element with the string representation of the given
	 * <var>object</var> to the given <var>node</var>.
	 *
	 * This method modifies your DOM tree so that
	 * <pre>&lt;node&gt;
	 *   ...
	 * &lt;/node&gt;</pre>
	 * becomes
	 * <pre>&lt;node&gt;
	 *   ...
	 *   &lt;name&gt;string-rep&gt;/name&gt;
	 * &lt;/node&gt;</pre>
	 *
	 * Adding a null <var>name</var> does nothing.  Adding null <var>object</var>
	 * results in an empty <var>name</var> tag.
	 *
	 * @param node Node to which to add a child element.
	 * @param name Name of the child element to add to <var>node</var>.
	 * @param object The string representation of the object to have as the text-node
	 * child the child element named <var>name</var>.
	 * @throws DOMException If a DOM error occurs.
	 */
	public static void add(Node node, String name, Object object) throws DOMException {
		add(node, name, object == null? null : object.toString());
	}

	/** Get unwrapped text from the given DOM node
	 *
	 * This method unwraps any wrapped text.  For example, if the document contains
	 * <pre>&lt;node&gt;Hello, world.  This is
	 *    my first document.
         * &lt;/node&gt;</pre>
	 * then the node's unwrapped text is
	 * <pre>Hello, world.  This is my first document.</pre>
	 * while the {@link #text} method would return the wrapped value
	 * <pre>Hello, world.  This is
	 *    my first document.</pre>
	 *
	 * <p>In other words, it collects the text nodes under the given node and replaces
	 * strings of newlines and spaces with a single space.  Unwrapping a null node
	 * returns a null string.
	 *
	 * @param node The node.
	 * @return The text in its children, unwrapped.
	 */
	public static String unwrappedText(Node node) {
		if (node == null) return null;
		StringBuffer buffer = new StringBuffer();
		StringBuffer wrapped = new StringBuffer(text1(node, buffer));
		boolean newline = false;
		for (int i = 0; i < wrapped.length(); ++i) {
			if (newline == false) {
				if (wrapped.charAt(i) == '\n') {
					newline = true;
					wrapped.setCharAt(i, ' ');
				}
			} else {
				if (Character.isWhitespace(wrapped.charAt(i))) {
					wrapped.deleteCharAt(i);
					--i;
				} else
					newline = false;
			}
		}
		return wrapped.toString().trim();
	}

	/** Get the text from the given DOM node.
	 *
	 * Getting text from a null node gives you a null string.
	 *
	 * @param node The node.
	 * @return The text in its children.
	 */
	public static String text(Node node) {
		// [ return text(node) ]
		StringBuffer buffer = new StringBuffer();
		return text1(node, buffer);
	}

	/** Dump the structure of the DOM tree rooted at the given node to the given writer.
	 *
	 * This outputs the tree structure including the type of each node, its name, and
	 * its value.  Note that for many nodes, the name isn't useful (the name of text
	 * nodes, for example, is <code>#text</code>), and for many nodes, the value is
	 * null.
	 *
	 * @param writer The writer to which write the tree structure.
	 * @param node The tree to output.
	 */
	public static void dump(PrintWriter writer, Node node) {
		dump(writer, node, 0);
	}

	/** Remove all comments from the given document node's subtree.
	 *
	 * @param node Node from which to search for comments to nuke.
	 */
	public static void removeComments(Node node) {
		List commentNodes = new ArrayList();
		findCommentNodes(commentNodes, node);
		for (Iterator i = commentNodes.iterator(); i.hasNext();) {
			Node commentNode = (Node) i.next();
			commentNode.getParentNode().removeChild(commentNode);
		}
	}

	/** The resolver for entities for the JPL enterprise. */
	public static final EntityResolver ENTERPRISE_ENTITY_RESOLVER = new EnterpriseEntityResolver();

	/** An empty XML DOM document.  This is handy for some basic operations, and for
	 * fetching the DOM implementation.
	 */
	public static final Document EMPTY_DOCUMENT = org.apache.oodt.commons.util.XML.createDocument();

	/** Identifies the last printable character in the Unicode range that is supported
	 * by the encoding used with this serializer.  For 8-bit encodings this will be either
	 * 0x7E or 0xFF.  For 16-bit encodings this will be 0xFFFF. Characters that are not
	 * printable will be escaped using character references.
	 *
	 * <p>Taken from Xerces 1.0.3.  Apache license applies; see source code for
	 * license.
	 *
	 */
	private static int LAST_PRINTABLE = 0x7E;

	/** Escapes a string so it may be printed as text content or attribute value. Non
	 * printable characters are escaped using character references.  Where the format
	 * specifies a deault entity reference, that reference is used
	 * (e.g. <code>&amp;lt;</code>).
	 *
	 * <p>Taken from Xerces 1.0.3.  Apache license applies; see source code for
	 * license.
	 *
	 * @param source The string to escape
	 * @return The escaped string
	 */
	public static String escape(String source) {
		StringBuffer    result;
		int             i;
		char            ch;
		String          charRef;
        
		result = new StringBuffer(source.length());
		for (i = 0; i < source.length(); ++i) {
			ch = source.charAt(i);
			// If the character is not printable, print as character
			// reference.  Non printables are below ASCII space but not tab or
			// line terminator, ASCII delete, or above a certain Unicode
			// threshold.
			if ((ch < ' ' && ch != '\t' && ch != '\n' && ch != '\r') || ch > LAST_PRINTABLE || ch == 0xF7)
				result.append("&#").append(Integer.toString(ch)).append(';');
			else {
				// If there is a suitable entity reference for this
				// character, print it. The list of available entity
				// references is almost but not identical between XML and
				// HTML.
				charRef = getEntityRef(ch);
				if (charRef == null) result.append(ch);
				else                 result.append('&').append(charRef).append(';');
			}
		}
		return result.toString();
	}

	/** Find all comment nodes under the given node and add them to the given list.
	 *
	 * @param list List to add to.
	 * @param node Node to search.
	 */
	private static void findCommentNodes(List list, Node node) {
		if (node.getNodeType() == Node.COMMENT_NODE)
			list.add(node);
		else {
			NodeList children = node.getChildNodes();
			for (int i = 0; i < children.getLength(); ++i) {
				findCommentNodes(list, children.item(i));
			}
		}
	}

	/** Get the entity reference for the given character.
	 *
	 * Taken from Xerces 1.0.3; see source code for license.
	 */
	private static String getEntityRef(char ch) {
		// Encode special XML characters into the equivalent character references.
		// These five are defined by default for all XML documents.
		switch (ch) {
			case '<':  return "lt";
			case '>':  return "gt";
			case '"':  return "quot";
			case '\'': return "apos";
			case '&':  return "amp";
		}
		return null;
	}

	/** Get the text from the child node using the given buffer.
	 *
	 * @param node The node.
	 * @param buffer The buffer to use.
	 * @return The text.
	 */
	private static String text1(Node node, StringBuffer buffer) {
		for (Node ch = node.getFirstChild(); ch != null; ch = ch.getNextSibling()) {
			if (ch.getNodeType() == Node.ELEMENT_NODE || ch.getNodeType() == Node.ENTITY_REFERENCE_NODE)
				buffer.append(text(ch));
			else if (ch.getNodeType() == Node.TEXT_NODE)
				buffer.append(ch.getNodeValue());
		}
		return buffer.toString();
	}

	/** Dump the structure of the DOM tree rooted at the given node to the given writer,
	 * indenting the contents.
	 *
	 * @param indentAmt The number of spaces to indent the output of this node;
	 * children are indented two more than this amount.
	 * @param writer The writer to which write the tree structure.
	 * @param node The tree to output.
	 */
	private static void dump(PrintWriter writer, Node node, int indentAmt) {
		for (int i = 0; i < indentAmt; ++i)
			writer.print(' ');
		writer.println(typeOf(node) + "(" + node.getNodeName() + ", " + node.getNodeValue() + ")");
		NodeList children = node.getChildNodes();
		for (int i = 0; i < children.getLength(); ++i)
			dump(writer, children.item(i), indentAmt + 2);
	}

	/** Return a human-readable representation of the type of the given node.
	 *
	 * For example, an attribute node returns <code>Attribute</code>, while an element
	 * node returns <code>Element</code>.
	 *
	 * @param node The node.
	 * @return The name of the node's type.
	 */
	private static String typeOf(Node node) {
		switch (node.getNodeType()) {
			case Node.ATTRIBUTE_NODE:              return "Attribute";
			case Node.CDATA_SECTION_NODE:          return "CDATA-Section";
			case Node.COMMENT_NODE:                return "Comment";
			case Node.DOCUMENT_FRAGMENT_NODE:      return "Document-Fragment";
			case Node.DOCUMENT_NODE:               return "Document";
			case Node.DOCUMENT_TYPE_NODE:          return "Document-Type";
			case Node.ELEMENT_NODE:                return "Element";
			case Node.ENTITY_NODE:                 return "Entity";
			case Node.ENTITY_REFERENCE_NODE:       return "Entity-Ref";
			case Node.NOTATION_NODE:               return "Notation";
			case Node.PROCESSING_INSTRUCTION_NODE: return "Proc-Instr";
			case Node.TEXT_NODE:                   return "Text";
			default:                               return "Unknown!";
		}
	}
}
