//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.common.utils;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.tools.ant.util.ReaderInputStream;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXParseException;

/**
 * Utility class for processing XML documents.
 * 
 * @author Kelvin Low
 * @author Jinhua Xi
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class XMLUtil {

	/**
	 * XML declaration.
	 */
	public final static String XML_DECLARATION = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; //$NON-NLS-1$

	/**
	 * XML Escape characters.
	 */
	public final static String XML_AMP = "&amp;"; //$NON-NLS-1$

	public final static String XML_BACKSLASH = "&#92;"; //$NON-NLS-1$	

	public final static String XML_APOS = "&apos;"; //$NON-NLS-1$

	public final static String XML_CR = "&#13;"; //$NON-NLS-1$

	public final static String XML_GT = "&gt;"; //$NON-NLS-1$

	public final static String XML_LT = "&lt;"; //$NON-NLS-1$

	public final static String XML_LF = "&#10;"; //$NON-NLS-1$	

	public final static String XML_QUOT = "&quot;"; //$NON-NLS-1$

	public final static String XML_TAB = "&#9;"; //$NON-NLS-1$

	private static final String CRLF = "\r\n"; //$NON-NLS-1$

	private static final byte[] CRLF_BYTES = CRLF.getBytes();

	/**
	 * Private constructor to prevent this class from being instantiated. All
	 * methods in this class should be static.
	 */
	private XMLUtil() {
	}

	/**
	 * Clones the given DOM node into the given DOM document.
	 * 
	 * @param node
	 *            The DOM node to clone.
	 * @param doc
	 *            The target DOM document.
	 * @return The cloned node in the target DOM document.
	 */
	public static Node cloneNode(Node node, Document doc) {
		Node clone = null;
		switch (node.getNodeType()) {
		case Node.ELEMENT_NODE:
			clone = doc.createElement(node.getNodeName());
			NamedNodeMap attrs = node.getAttributes();
			for (int i = 0; i < attrs.getLength(); i++) {
				Node attrNode = attrs.item(i);
				Attr attrClone = doc.createAttribute(attrNode.getNodeName());
				attrClone.setNodeValue(attrNode.getNodeValue());
				((Element) clone).setAttributeNode(attrClone);
			}

			// Iterate through each child nodes.
			NodeList childNodes = node.getChildNodes();
			if (childNodes != null) {
				for (int i = 0; i < childNodes.getLength(); i++) {
					Node childNode = childNodes.item(i);
					Node childClone = cloneNode(childNode, doc);
					clone.appendChild(childClone);
				}
			}
			break;

		case Node.TEXT_NODE:
		case Node.CDATA_SECTION_NODE:
			clone = doc.createTextNode(node.getNodeName());
			clone.setNodeValue(node.getNodeValue());
			break;
		}
		return clone;
	}

	/**
	 * Escapes a XML attribute to make it XML parser friendly.
	 * 
	 * @param str
	 *            The XML attribute string.
	 * @return The escaped string.
	 */
	public static String escapeAttr(String str) {
		if (str == null || str.length() == 0)
			return ""; //$NON-NLS-1$
		StringBuffer sb = new StringBuffer();
		int len = str.length();
		for (int i = 0; i < len; i++) {
			char ch = str.charAt(i);
			switch (ch) {
			case '<':
				sb.append(XML_LT);
				break;
			case '&':
				sb.append(XML_AMP);
				break;
			case '"':
				sb.append(XML_QUOT);
				break;
			default:
				sb.append(ch);
				break;
			}
		}
		return sb.toString();
	}

	/**
	 * Escapes the given string to make it XML parser friendly.
	 * 
	 * @param str
	 *            The source string.
	 * @return The escaped string.
	 */
	public static String escape(String str) {
		if (str == null || str.length() == 0)
			return ""; //$NON-NLS-1$
		StringBuffer sb = new StringBuffer();
		int len = str.length();
		for (int i = 0; i < len; i++) {
			char ch = str.charAt(i);
			switch (ch) {
			case '<':
				sb.append(XML_LT);
				break;
			case '>':
				sb.append(XML_GT);
				break;
			case '&':
				sb.append(XML_AMP);
				break;
			case '"':
				sb.append(XML_QUOT);
				break;
			case '\'':
				sb.append(XML_APOS);
				break;
			case '\r':
				sb.append(XML_CR);
				break;
			case '\n':
				sb.append(XML_LF);
				break;
			case '\\':
				sb.append(XML_BACKSLASH);
				break;
			default:
				sb.append(ch);
				break;
			}
		}
		return sb.toString();
	}

	/**
	 * Escapes the given string to make it XML parser friendly.
	 * 
	 * @param str
	 *            The source string.
	 * @param ignoreCRLF
	 *            If true, do not escape the CR and LF characters.
	 * @return The escaped string.
	 */
	public static String escape(String str, boolean ignoreCRLF) {
		if (str == null || str.length() == 0)
			return ""; //$NON-NLS-1$
		StringBuffer sb = new StringBuffer();
		int len = str.length();
		for (int i = 0; i < len; i++) {
			char ch = str.charAt(i);
			switch (ch) {
			case '<':
				sb.append(XML_LT);
				break;
			case '>':
				sb.append(XML_GT);
				break;
			case '&':
				// This is to avoid the double escaping (see Bugzilla 179921)
				if (!str.startsWith(XML_LT+"p/", i) && !str.startsWith(XML_APOS, i) //$NON-NLS-1$ 
						&& !str.startsWith(XML_AMP, i))
					sb.append(XML_AMP);
				else
					sb.append(ch);
				break;
			case '"':
				sb.append(XML_QUOT);
				break;
			case '\'':
				sb.append(XML_APOS);
				break;
			case '\r':
				if (ignoreCRLF)
					sb.append(ch);
				else
					sb.append(XML_CR);
				break;
			case '\n':
				if (ignoreCRLF)
					sb.append(ch);
				else
					sb.append(XML_LF);
				break;
			default:
				sb.append(ch);
				break;
			}
		}
		return sb.toString();
	}

	/**
	 * Unescapes the given XML string.
	 * 
	 * @param str
	 *            The source string.
	 * @return The escaped string.
	 */
	public static String unescape(String str) {
		if (str == null || str.length() == 0)
			return ""; //$NON-NLS-1$
		StringBuffer sb = new StringBuffer();
		int len = str.length();
		for (int i = 0; i < len; i++) {
			char ch = str.charAt(i);
			switch (ch) {
			case '&':
				if (str.startsWith(XML_LT, i)) {
					sb.append('<');
					i += 3;
				} else if (str.startsWith(XML_GT, i)) {
					sb.append('>');
					i += 3;
				} else if (str.startsWith(XML_AMP, i)) {
					sb.append('&');
					i += 4;
				} else if (str.startsWith(XML_QUOT, i)) {
					sb.append('"');
					i += 5;
				} else if (str.startsWith(XML_APOS, i)) {
					sb.append("\'"); //$NON-NLS-1$
					i += 5;
				} else if (str.startsWith(XML_CR, i)) {
					sb.append('\r');
					i += 4;
				} else if (str.startsWith(XML_LF, i)) {
					sb.append('\n');
					i += 4;
				} else {
					sb.append(ch);
				}
				break;
			default:
				sb.append(ch);
				break;
			}
		}
		return sb.toString();
	}

	/**
	 * Writes the content of the given DOM document to the output stream.
	 * 
	 * @param xmlDoc
	 *            The DOM document.
	 * @param output
	 *            The output stream.
	 * @throws IOException
	 *             if an I/O error occur while accessing the output stream.
	 */
	public static void writeDocument(Document xmlDoc, OutputStream output)
			throws IOException {
		DataOutputStream out = new DataOutputStream(output);
		writeNode(xmlDoc, "", out); //$NON-NLS-1$
		out.flush();
	}

	/**
	 * Writes the content of the given DOM document to the PrintWriter.
	 * 
	 * @param xmlDoc
	 *            The DOM document.
	 * @param pw
	 *            The PrintWriter object.
	 * @throws IOException
	 *             if an I/O error occur while accessing the output stream.
	 */
	public static void writeDocument(Document xmlDoc, PrintWriter pw)
			throws IOException {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		DataOutputStream out = new DataOutputStream(os);
		writeNode(xmlDoc, "", out); //$NON-NLS-1$
		out.flush();
		// FIXME! Need to specify encoding?
		String s = os.toString();
		pw.write(s);
		pw.flush();
	}

	/**
	 * Saves the content of the given DOM document to file.
	 * 
	 * @param xmlDoc
	 *            The DOM document.
	 * @param xmlFile
	 *            The XML file.
	 * @throws IOException
	 *             if an I/O error occur while accessing the output stream.
	 */
	public static void saveDocument(Document xmlDoc, String xmlFile)
			throws IOException {
		DataOutputStream out = new DataOutputStream(new FileOutputStream(
				xmlFile));
		writeNode(xmlDoc, "", out); //$NON-NLS-1$
		out.flush();
		out.close();
	}

	/**
	 * Saves the given XML string to the given file.
	 * 
	 * @param xmlStr
	 *            The XML string.
	 * @param xmlFile
	 *            The XML file.
	 * @throws IOException
	 *             if an I/O error occur while accessing the output stream.
	 */
	public static void saveDocument(String xmlStr, String xmlFile)
			throws IOException {
		DataOutputStream out = new DataOutputStream(new FileOutputStream(
				xmlFile));
		out.write(xmlStr.getBytes());
		out.flush();
		out.close();
	}

	/**
	 * Writes the given DOM tree node to the given output stream.
	 * 
	 * @param node
	 *            The DOM node.
	 * @param indent
	 *            The string indentation (containing space characters).
	 * @param out
	 *            The output stream.
	 * @throws IOException
	 *             if an I/O error occur while accessing the output stream.
	 */
	private static void writeNode(Node node, String indent, DataOutputStream out)
			throws IOException {
		String text;

		switch (node.getNodeType()) {
		case Node.DOCUMENT_NODE:
			// Write the XML file signature.
			out.write(StrUtil.getUTF8Bytes(XML_DECLARATION));
			out.write(CRLF_BYTES);

			// Iterate through each child nodes.
			NodeList nodes = node.getChildNodes();
			if (nodes != null) {
				for (int i = 0; i < nodes.getLength(); i++) {
					writeNode(nodes.item(i), "", out); //$NON-NLS-1$
				}
			}
			break;

		case Node.ELEMENT_NODE:
			String name = node.getNodeName();
			out.write(StrUtil.getUTF8Bytes(indent + "<" + name)); //$NON-NLS-1$
			NamedNodeMap attrs = node.getAttributes();
			for (int i = 0; i < attrs.getLength(); i++) {
				Node attrNode = attrs.item(i);
				out.write(StrUtil.getUTF8Bytes(" " + attrNode.getNodeName() //$NON-NLS-1$
						+ "=\"" + escape(attrNode.getNodeValue()) + "\"")); //$NON-NLS-1$ //$NON-NLS-2$
			}
			out.write(StrUtil.getUTF8Bytes(">")); //$NON-NLS-1$
			out.write(CRLF_BYTES);

			// Iterate through each child nodes.
			NodeList childNodes = node.getChildNodes();
			if (childNodes != null) {
				for (int i = 0; i < childNodes.getLength(); i++) {
					writeNode(childNodes.item(i), indent, out);
				}
			}
			out.write(StrUtil.getUTF8Bytes(indent + "</" + name + ">")); //$NON-NLS-1$ //$NON-NLS-2$
			out.write(CRLF_BYTES);

			break;

		case Node.TEXT_NODE:
			text = StrUtil.removeWhiteSpaceChars(node.getNodeValue());
			if (text.length() > 0) {
				out.write(StrUtil.getUTF8Bytes(escape(text)));
			}
			break;

		case Node.CDATA_SECTION_NODE:
			text = StrUtil.removeWhiteSpaceChars(node.getNodeValue());
			if (text.length() > 0) {
				out.write(StrUtil.getUTF8Bytes("<![CDATA[")); //$NON-NLS-1$
				out.write(StrUtil.getUTF8Bytes(text));
				out.write(StrUtil.getUTF8Bytes("]]>")); //$NON-NLS-1$
				out.write(CRLF_BYTES);
			}
			break;

		case Node.PROCESSING_INSTRUCTION_NODE:
			out.write(StrUtil.getUTF8Bytes("<?" + node.getNodeName() //$NON-NLS-1$
					+ " " + node.getNodeValue() + "?>")); //$NON-NLS-1$ //$NON-NLS-2$
			out.write(CRLF_BYTES);
			break;

		case Node.ENTITY_REFERENCE_NODE:
			out.write(StrUtil.getUTF8Bytes("&" + node.getNodeName() + ";")); //$NON-NLS-1$ //$NON-NLS-2$
			break;
		}
	}

	/**
	 * Returns the file location where the given SAX exception occurred.
	 * 
	 * @param e
	 *            The SAX parse exception.
	 * @return A string containing the file location where the exception
	 *         occurred.
	 */
	public static String getLocationOfException(SAXParseException e) {
		StringBuffer sb = new StringBuffer();
		sb.append("row "); //$NON-NLS-1$
		sb.append(e.getLineNumber());
		sb.append(", col "); //$NON-NLS-1$
		sb.append(e.getColumnNumber());

		String systemId = e.getSystemId();
		if (systemId != null) {
			int index = systemId.lastIndexOf('/');
			if (index != -1) {
				systemId = systemId.substring(index + 1);
			}
			sb.append(" of XML document "); //$NON-NLS-1$
			sb.append(systemId);
		}

		return sb.toString();
	}

	public static Document loadXml(File file) throws Exception {
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory
				.newInstance();
		DocumentBuilder builder = builderFactory.newDocumentBuilder();

		return builder.parse(file);
	}

	public static Document loadXml(String xmlString) throws Exception {
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory
				.newInstance();
		DocumentBuilder builder = builderFactory.newDocumentBuilder();
		ReaderInputStream istrem = new ReaderInputStream(new StringReader(xmlString));
		
		return builder.parse(istrem);
	}
	
	public static Document createDocument() throws Exception {
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory
				.newInstance();
		DocumentBuilder builder = builderFactory.newDocumentBuilder();
		return builder.newDocument();
	}

	public static String toXmlString(Document doc) throws Exception {
		DOMSource domSource = new DOMSource(doc);
		StringWriter writer = new StringWriter();
		StreamResult result = new StreamResult(writer);
		TransformerFactory tf = TransformerFactory.newInstance();
		Transformer transformer = tf.newTransformer();
		transformer.transform(domSource, result);
		writer.flush();

		return writer.toString();
	}
	
	/**
	 * text of a leaf node, without child element
	 * 
	 * @param tag
	 * @return String
	 */
	public static String getNodeText(Element tag) {
		String text = tag.toString();
		int i = text.indexOf(">"); //$NON-NLS-1$
		int j = text.lastIndexOf("</"); //$NON-NLS-1$
		if (i < 0 || j < 0 || j < i) {
			return ""; //$NON-NLS-1$
		}

		return text.substring(i + 1, j);
	}

	public static String getChildText(Element tag, String childTagName) {
		Element child = getFirstChild(tag, childTagName);
		if (child != null) {
			return getNodeText(child);
		}

		return ""; //$NON-NLS-1$
	}

	public static Element getFirstChild(Element tag, String childTagName) {
		NodeList nodes = tag.getElementsByTagName(childTagName);
		if (nodes == null || nodes.getLength() == 0) {
			return null;
		}

		return (Element) nodes.item(0);
	}

	/**
	 * iterator of all the children of the element
	 * 
	 * @param tag
	 * @return Iterator
	 */
	public static Iterator childIterator(Element tag) {
		NodeList nodes = tag.getChildNodes();

		// NodeList contains no Element nodes such as text nodes, ignore those
		List<Node> elements = new ArrayList<Node>();
		if (nodes != null) {
			int size = nodes.getLength();
			for (int i = 0; i < size; i++) {
				Node node = nodes.item(i);
				if (node instanceof Element) {
					elements.add(node);
				}
			}
		}

		return elements.iterator();
	}

	private static class NodeIterator implements Iterator {
		int currentIndex = -1;

		int size = 0;

		NodeList nodes = null;

		public NodeIterator(NodeList nodes) {
			this.nodes = nodes;
			if (nodes != null)
				size = nodes.getLength();
		}

		public void remove() {
			// Do nothing, this is a readonly iterator.
		}

		public boolean hasNext() {
			return currentIndex + 1 < size;
		}

		public Object next() {
			if (hasNext()) {
				return nodes.item(++currentIndex);
			}

			return null;
		}
	}

	/**
	 * iterator of all the children of the element
	 * 
	 * @param tag
	 * @return Iterator
	 */
	public static Iterator childIterator(Element tag, String childTagName) {
		NodeList nodes = tag.getElementsByTagName(childTagName);
		return new NodeIterator(nodes);
	}

	/**
	 * Gets the list of immediate child elements with the given tag name.
	 * 
	 * @param element
	 * @param tagName
	 * @return list of {@link Element} objects
	 */
	public static List<Element> getChildElementsByTagName(Element element, String tagName) {	
		List<Element> elements = new ArrayList<Element>();
		NodeList list = element.getChildNodes();
		int size = list.getLength(); 
		if(size > 0) {
			for (int i = 0; i < size; i++) {
				Node node = list.item(i);
				if(node instanceof Element) {
					Element e = (Element) node;
					if(e.getTagName().equals(tagName)) {
						elements.add(e);
					}
				}
			}
		}
		return elements;
	}
	
	/**
	 * Gets the first element with the given tag name in the immediate child elements.
	 * 
	 * @param element
	 * @param tagName
	 * @return
	 */
	public static Element getFirstChildElementByTagName(Node element, String tagName) {
		NodeList list = element.getChildNodes();
		int size = list.getLength(); 
		if(size > 0) {
			for (int i = 0; i < size; i++) {
				Node node = list.item(i);
				if(node instanceof Element) {
					Element e = (Element) node;
					if(e.getTagName().equals(tagName)) {
						return e;
					}
				}
			}
		}
		return null;
	}
	
	public static String removeBOM(String xml) {
		return xml.trim().replaceFirst("^([\\W]+)<", "<"); //$NON-NLS-1$ //$NON-NLS-2$
	}
	
	public static String elementToString(Element element) throws IOException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		DataOutputStream dos = new DataOutputStream(baos);
		writeNode(element, " ", dos); //$NON-NLS-1$
		
		return baos.toString();
	}
	
}
