/*******************************************************************************
 * Copyright (c) 2003, 2010 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
 *     Angelo Zerr <angelo.zerr@gmail.com> - Jetty packages
 *******************************************************************************/
package org.eclipse.jst.server.jetty.core.internal.xml;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
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.parsers.ParserConfigurationException;

import org.eclipse.jst.server.jetty.core.internal.Trace;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
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);
                // In case we happen to have a Xerces parser, try to set the feature that allows Java encodings to be used
                try
                {
                    factory.setFeature("http://apache.org/xml/features/allow-java-encodings",true);
                }
                catch (ParserConfigurationException e)
                {
                    // Ignore if feature isn't supported
                }
                // 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,"Error 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<Node> getNodeIterator(Element element, String name)
    {
        List<Node> list = new ArrayList<Node>();
        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;
    }
}
