/*******************************************************************************
 * 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()
    {
        synchronized (documentBuilder)
        {
            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;
    }
}
