/*******************************************************************************
 * Copyright (c) 2003, 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 API and implementation
 *******************************************************************************/
package org.eclipse.jst.server.tomcat.core.internal.xml;

import java.io.*;
import java.util.*;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.jst.server.tomcat.core.internal.Trace;
import org.w3c.dom.*;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
 * Utility class to create and read XML documents.
 */
public class XMLUtil {
	private static DocumentBuilder documentBuilder;

	/**
	 * XMLUtil constructor comment.
	 */
	public XMLUtil() {
		super();
	}
	
	public static DocumentBuilder getDocumentBuilder() {
		if (documentBuilder == null)
			try {
				DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
				factory.setValidating(false);
				factory.setNamespaceAware(false);
				factory.setExpandEntityReferences(false);
				//factory.setAttribute("http://apache.org/xml/features/nonvalidating/load-external-dtd", new Boolean(false));
				documentBuilder = factory.newDocumentBuilder();
				documentBuilder.setEntityResolver(new EntityResolver() {
					public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
						return new InputSource(new ByteArrayInputStream(new byte[0]));
					}
				});
			} catch (Exception e) {
				Trace.trace(Trace.SEVERE, "Rrror creating document builder");
			}

		return documentBuilder;
	}

	/**
	 * Create a child of the given node at the given index.
	 *
	 * @param doc a document
	 * @param element an element
	 * @param index an index
	 * @param nodeName a node name
	 * @return org.w3c.dom.Element
	 */
	public static Element createChildElement(Document doc, Element element, int index, String nodeName) {
		Element element2 = doc.createElement(nodeName);
		try {
			NodeList childList = element.getElementsByTagName(nodeName);
			Node child = childList.item(index);
			element.insertBefore(element2, child);
		} catch (Exception e) {
			element.appendChild(element2);
		}
		return element2;
	}

	/**
	 * Create a child of the given node.
	 *
	 * @param doc a document
	 * @param node a node
	 * @param nodeName a node name
	 * @return org.w3c.dom.Element
	 */
	public static Element createChildElement(Document doc, Node node, String nodeName) {
		Element element = doc.createElement(nodeName);
		node.appendChild(element);
		return element;
	}

	/*
	 * Set the value of the given node to the given text.
	 */
	public static void createTextChildElement(Document doc, Node node, String name, String value) {
		Element element = createChildElement(doc, node, name);
		element.appendChild(doc.createTextNode(value));
	}

	/**
	 * Return the attribute value.
	 * @return java.lang.String
	 * @param element org.w3c.dom.Element
	 * @param attr java.lang.String
	 */
	public static String getAttributeValue(Element element, String attr) {
		return element.getAttributeNode(attr).getValue();
	}

	public static byte[] getContents(Document document) throws IOException {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			print(new PrintStream(out, true, "UTF-8"), document);
			return out.toByteArray();
		} catch (Exception ex) {
			throw new IOException(ex.getLocalizedMessage());
		} finally {
			if (out != null)
				try {
					out.close();
				} catch (Exception e) {
					// ignore
				}
		}
	}

	protected static String getDocumentTypeData(DocumentType doctype) {
		String data = doctype.getName();
		if (doctype.getPublicId() != null) {
			data += " PUBLIC \"" + doctype.getPublicId() + "\"";
			String systemId = doctype.getSystemId();
			if (systemId == null)
				systemId = "";
			data += " \"" + systemId + "\"";
		} else
			data += " SYSTEM \"" + doctype.getSystemId() + "\"";
	
		return data;
	}

	/**
	 * Return an iterator for the subelements.
	 * @return java.util.Iterator
	 * @param element org.w3c.dom.Element
	 * @param name java.lang.String
	 */
	public static Iterator getNodeIterator(Element element, String name) {
		List list = new ArrayList();
		NodeList nodeList = element.getElementsByTagName(name);
	
		int length = nodeList.getLength();
		for (int i = 0; i < length; i++)
			list.add(nodeList.item(i));
	
		return list.iterator();
	}

	/**
	 * Get the value of this node. Will return "" instead of null.
	 * @return java.lang.String
	 * @param node org.w3c.dom.Node
	 */
	public static String getNodeValue(Node node) {
		NodeList nodeList = node.getChildNodes();
	
		int length = nodeList.getLength();
		for (int i = 0; i < length; i++) {
			Node n = nodeList.item(i);
			if (n instanceof Text) {
				Text t = (Text) n;
				return t.getNodeValue();
			}
		}
		return "";
	}

	/*
	 * Get the value of a subnode.

	 * @return java.lang.String
	 */
	public static String getSubNodeValue(Element element, String name) {
		NodeList nodeList = element.getElementsByTagName(name);
		return getNodeValue(nodeList.item(0)).trim();
	}

	/*
	 * Insert the given text.
	 */
	public static void insertText(Document doc, Node node, String text) {
		node.appendChild(doc.createCDATASection(text));
	}

	protected static String normalize(String s) {
		StringBuffer stringbuffer = new StringBuffer();
		int i = s == null ? 0 : s.length();
		for (int j = 0; j < i; j++) {
			char c = s.charAt(j);
			switch (c) {
				case 60 : /* '<' */
					stringbuffer.append("&lt;");
					break;
	
				case 62 : /* '>' */
					stringbuffer.append("&gt;");
					break;
	
				case 38 : /* '&' */
					stringbuffer.append("&amp;");
					break;
	
				case 34 : /* '"' */
					stringbuffer.append("&quot;");
					break;
	
				case 10 : /* '\n' */
				case 13 : /* '\r' */
				default :
					stringbuffer.append(c);
					break;
	
			}
		}
	
		return stringbuffer.toString();
	}

	protected static void print(PrintStream out, Node node) {
		if (node == null)
			return;
		short type = node.getNodeType();
		switch (type) {
			case Node.DOCUMENT_NODE: {
				out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
				//out.println("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
				NodeList nodelist = node.getChildNodes();
				int size = nodelist.getLength();
				for (int i = 0; i < size; i++)
					print(out, nodelist.item(i));
				break;
			}
	
			case Node.DOCUMENT_TYPE_NODE: {
				DocumentType docType = (DocumentType) node;
				out.print("<!DOCTYPE " + getDocumentTypeData(docType) + ">\n");
				break;
			}
	
			case Node.ELEMENT_NODE: {
				out.print('<');
				out.print(node.getNodeName());
				NamedNodeMap map = node.getAttributes();
				if (map != null) {
					int size = map.getLength();
					for (int i = 0; i < size; i++) {
						Attr attr = (Attr) map.item(i);
						out.print(' ');
						out.print(attr.getNodeName());
						out.print("=\"");
						out.print(normalize(attr.getNodeValue()));
						out.print('"');
					}
				}
	
				if (!node.hasChildNodes())
					out.print("/>");
				else {
					out.print('>');
					NodeList nodelist = node.getChildNodes();
					int numChildren = nodelist.getLength();
					for (int i = 0; i < numChildren; i++)
						print(out, nodelist.item(i));
	
					out.print("</");
					out.print(node.getNodeName());
					out.print('>');
				}
				break;
			}
	
			case Node.ENTITY_REFERENCE_NODE: {
				NodeList nodelist = node.getChildNodes();
				if (nodelist != null) {
					int size = nodelist.getLength();
					for (int i = 0; i < size; i++)
						print(out, nodelist.item(i));
	
				}
				break;
			}
	
			case Node.CDATA_SECTION_NODE: {
				out.print(normalize(node.getNodeValue()));
				break;
			}
	
			case Node.TEXT_NODE: {
				out.print(normalize(node.getNodeValue()));
				break;
			}
	
			case Node.PROCESSING_INSTRUCTION_NODE: {
				out.print("<?");
				out.print(node.getNodeName());
				String s = node.getNodeValue();
				if (s != null && s.length() > 0) {
					out.print(' ');
					out.print(s);
				}
				out.print("?>");
				break;
			}
	
			case Node.COMMENT_NODE: {
				out.print("<!--");
				out.print(node.getNodeValue());
				out.print("-->");
				break;
			}
	
			default: {
				out.print(normalize(node.getNodeValue()));
				break;
			}
		}
		out.flush();
	}

	public static void save(String filename, Document document) throws IOException {
		PrintStream out = null;
		try {
			out = new PrintStream(new BufferedOutputStream(new FileOutputStream(filename)), true, "UTF-8");
			//traceNode(document, "");
			print(out, document);
		} catch (Exception ex) {
			throw new IOException(ex.getLocalizedMessage());
		} finally {
			if (out != null)
				try {
					out.close();
				} catch (Exception e) {
					// ignore
				}
		}
	}

	public static void save(String filename, Node node) throws IOException {
		PrintStream out = null;
		try {
			out = new PrintStream(new BufferedOutputStream(new FileOutputStream(filename)), true, "UTF-8");
			print(out, node);
		} catch (Exception ex) {
			throw new IOException(ex.getLocalizedMessage());
		} finally {
			if (out != null)
				try {
					out.close();
				} catch (Exception e) {
					// ignore
				}
		}
	}

	/*
	 * Set the value of the subnode
	 *
	 * @param name java.lang.String
	 * @param value java.lang.String
	 */
	public static void setNodeValue(Node node, String name, String value) {
		String s = node.getNodeValue();
		if (s != null) {
			node.setNodeValue(value);
			return;
		}
		NodeList nodelist = node.getChildNodes();
		for (int i = 0; i < nodelist.getLength(); i++) {
			if (nodelist.item(i) instanceof Text) {
				Text text = (Text) nodelist.item(i);
				text.setData(value);
				return;
			}
		}
		return;
	}

	public static String toString(Document document) {
		PrintStream out = null;
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
			out = new PrintStream(baos);
			print(out, document);
			return new String(baos.toByteArray(), "UTF-8");
		} catch (Exception ex) {
			// ignore
		} finally {
			if (out != null)
				try {
					out.close();
				} catch (Exception e) {
					// ignore
				}
		}
		return null;
	}
}
