//
//  ========================================================================
//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.xml;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Stack;
import java.util.StringTokenizer;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.eclipse.jetty.util.LazyList;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

/*--------------------------------------------------------------*/
/**
 * XML Parser wrapper. This class wraps any standard JAXP1.1 parser with convieniant error and
 * entity handlers and a mini dom-like document tree.
 * <P>
 * By default, the parser is created as a validating parser only if xerces is present. This can be 
 * configured by setting the "org.eclipse.jetty.xml.XmlParser.Validating" system property.
 * 
 * 
 */
public class XmlParser
{
    private static final Logger LOG = Log.getLogger(XmlParser.class);

    private Map<String,URL> _redirectMap = new HashMap<String,URL>();
    private SAXParser _parser;
    private Map<String,ContentHandler> _observerMap;
    private Stack<ContentHandler> _observers = new Stack<ContentHandler>();
    private String _xpath;
    private Object _xpaths;
    private String _dtd;

    /* ------------------------------------------------------------ */
    /**
     * Construct
     */
    public XmlParser()
    {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        boolean validating_dft = factory.getClass().toString().startsWith("org.apache.xerces.");
        String validating_prop = System.getProperty("org.eclipse.jetty.xml.XmlParser.Validating", validating_dft ? "true" : "false");
        boolean validating = Boolean.valueOf(validating_prop).booleanValue();
        setValidating(validating);
    }

    /* ------------------------------------------------------------ */
    /**
     * Constructor.
     */
    public XmlParser(boolean validating)
    {
        setValidating(validating);
    }
    
    /* ------------------------------------------------------------ */
    public void setValidating(boolean validating)
    {
        try
        {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            factory.setValidating(validating);
            _parser = factory.newSAXParser();
            
            try
            {
                if (validating)
                    _parser.getXMLReader().setFeature("http://apache.org/xml/features/validation/schema", validating);
            }
            catch (Exception e)
            {
                if (validating)
                    LOG.warn("Schema validation may not be supported: ", e);
                else
                    LOG.ignore(e);
            }

            _parser.getXMLReader().setFeature("http://xml.org/sax/features/validation", validating);
            _parser.getXMLReader().setFeature("http://xml.org/sax/features/namespaces", true);
            _parser.getXMLReader().setFeature("http://xml.org/sax/features/namespace-prefixes", false);  
            try
            {
                if (validating)
                    _parser.getXMLReader().setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", validating);
            }
            catch (Exception e)
            {
                LOG.warn(e.getMessage());
            }
        }
        catch (Exception e)
        {
            LOG.warn(Log.EXCEPTION, e);
            throw new Error(e.toString());
        }
    }
    
    /* ------------------------------------------------------------ */
    /**
     * @param name
     * @param entity
     */
    public synchronized void redirectEntity(String name, URL entity)
    {
        if (entity != null)
            _redirectMap.put(name, entity);
    }

    /* ------------------------------------------------------------ */
    /**
     * 
     * @return Returns the xpath.
     */
    public String getXpath()
    {
        return _xpath;
    }

    /* ------------------------------------------------------------ */
    /**
     * Set an XPath A very simple subset of xpath is supported to select a partial tree. Currently
     * only path like "/node1/nodeA | /node1/nodeB" are supported.
     * 
     * @param xpath The xpath to set.
     */
    public void setXpath(String xpath)
    {
        _xpath = xpath;
        StringTokenizer tok = new StringTokenizer(xpath, "| ");
        while (tok.hasMoreTokens())
            _xpaths = LazyList.add(_xpaths, tok.nextToken());
    }

    /* ------------------------------------------------------------ */
    public String getDTD()
    {
        return _dtd;
    }

    /* ------------------------------------------------------------ */
    /**
     * Add a ContentHandler. Add an additional _content handler that is triggered on a tag name. SAX
     * events are passed to the ContentHandler provided from a matching start element to the
     * corresponding end element. Only a single _content handler can be registered against each tag.
     * 
     * @param trigger Tag local or q name.
     * @param observer SAX ContentHandler
     */
    public synchronized void addContentHandler(String trigger, ContentHandler observer)
    {
        if (_observerMap == null)
            _observerMap = new HashMap();
        _observerMap.put(trigger, observer);
    }

    /* ------------------------------------------------------------ */
    public synchronized Node parse(InputSource source) throws IOException, SAXException
    {
        _dtd=null;
        Handler handler = new Handler();
        XMLReader reader = _parser.getXMLReader();
        reader.setContentHandler(handler);
        reader.setErrorHandler(handler);
        reader.setEntityResolver(handler);
        if (LOG.isDebugEnabled())
            LOG.debug("parsing: sid=" + source.getSystemId() + ",pid=" + source.getPublicId());
        _parser.parse(source, handler);
        if (handler._error != null)
            throw handler._error;
        Node doc = (Node) handler._top.get(0);
        handler.clear();
        return doc;
    }

    /* ------------------------------------------------------------ */
    /**
     * Parse String URL.
     */
    public synchronized Node parse(String url) throws IOException, SAXException
    {
        if (LOG.isDebugEnabled())
            LOG.debug("parse: " + url);
        return parse(new InputSource(url));
    }

    /* ------------------------------------------------------------ */
    /**
     * Parse File.
     */
    public synchronized Node parse(File file) throws IOException, SAXException
    {
        if (LOG.isDebugEnabled())
            LOG.debug("parse: " + file);
        return parse(new InputSource(Resource.toURL(file).toString()));
    }

    /* ------------------------------------------------------------ */
    /**
     * Parse InputStream.
     */
    public synchronized Node parse(InputStream in) throws IOException, SAXException
    {
        _dtd=null;
        Handler handler = new Handler();
        XMLReader reader = _parser.getXMLReader();
        reader.setContentHandler(handler);
        reader.setErrorHandler(handler);
        reader.setEntityResolver(handler);
        _parser.parse(new InputSource(in), handler);
        if (handler._error != null)
            throw handler._error;
        Node doc = (Node) handler._top.get(0);
        handler.clear();
        return doc;
    }

    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    private class NoopHandler extends DefaultHandler
    {
        Handler _next;
        int _depth;

        NoopHandler(Handler next)
        {
            this._next = next;
        }

        /* ------------------------------------------------------------ */
        public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException
        {
            _depth++;
        }

        /* ------------------------------------------------------------ */
        public void endElement(String uri, String localName, String qName) throws SAXException
        {
            if (_depth == 0)
                _parser.getXMLReader().setContentHandler(_next);
            else
                _depth--;
        }
    }
    
    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    private class Handler extends DefaultHandler
    {
        Node _top = new Node(null, null, null);
        SAXParseException _error;
        private Node _context = _top;
        private NoopHandler _noop;

        Handler()
        {
            _noop = new NoopHandler(this);
        }

        /* ------------------------------------------------------------ */
        void clear()
        {
            _top = null;
            _error = null;
            _context = null;
        }

        /* ------------------------------------------------------------ */
        public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException
        {
            String name = null;
            if (_parser.isNamespaceAware())
                name = localName;

            if (name == null || "".equals(name))
                name = qName;

            Node node = new Node(_context, name, attrs);
            

            // check if the node matches any xpaths set?
            if (_xpaths != null)
            {
                String path = node.getPath();
                boolean match = false;
                for (int i = LazyList.size(_xpaths); !match && i-- > 0;)
                {
                    String xpath = (String) LazyList.get(_xpaths, i);

                    match = path.equals(xpath) || xpath.startsWith(path) && xpath.length() > path.length() && xpath.charAt(path.length()) == '/';
                }

                if (match)
                {
                    _context.add(node);
                    _context = node;
                }
                else
                {
                    _parser.getXMLReader().setContentHandler(_noop);
                }
            }
            else
            {
                _context.add(node);
                _context = node;
            }

            ContentHandler observer = null;
            if (_observerMap != null)
                observer = (ContentHandler) _observerMap.get(name);
            _observers.push(observer);

            for (int i = 0; i < _observers.size(); i++)
                if (_observers.get(i) != null)
                    ((ContentHandler) _observers.get(i)).startElement(uri, localName, qName, attrs);
        }

        /* ------------------------------------------------------------ */
        public void endElement(String uri, String localName, String qName) throws SAXException
        {
            _context = _context._parent;
            for (int i = 0; i < _observers.size(); i++)
                if (_observers.get(i) != null)
                    ((ContentHandler) _observers.get(i)).endElement(uri, localName, qName);
            _observers.pop();
        }

        /* ------------------------------------------------------------ */
        public void ignorableWhitespace(char buf[], int offset, int len) throws SAXException
        {
            for (int i = 0; i < _observers.size(); i++)
                if (_observers.get(i) != null)
                    ((ContentHandler) _observers.get(i)).ignorableWhitespace(buf, offset, len);
        }

        /* ------------------------------------------------------------ */
        public void characters(char buf[], int offset, int len) throws SAXException
        {
            _context.add(new String(buf, offset, len));
            for (int i = 0; i < _observers.size(); i++)
                if (_observers.get(i) != null)
                    ((ContentHandler) _observers.get(i)).characters(buf, offset, len);
        }

        /* ------------------------------------------------------------ */
        public void warning(SAXParseException ex)
        {
            LOG.debug(Log.EXCEPTION, ex);
            LOG.warn("WARNING@" + getLocationString(ex) + " : " + ex.toString());
        }

        /* ------------------------------------------------------------ */
        public void error(SAXParseException ex) throws SAXException
        {
            // Save error and continue to report other errors
            if (_error == null)
                _error = ex;
            LOG.debug(Log.EXCEPTION, ex);
            LOG.warn("ERROR@" + getLocationString(ex) + " : " + ex.toString());
        }

        /* ------------------------------------------------------------ */
        public void fatalError(SAXParseException ex) throws SAXException
        {
            _error = ex;
            LOG.debug(Log.EXCEPTION, ex);
            LOG.warn("FATAL@" + getLocationString(ex) + " : " + ex.toString());
            throw ex;
        }

        /* ------------------------------------------------------------ */
        private String getLocationString(SAXParseException ex)
        {
            return ex.getSystemId() + " line:" + ex.getLineNumber() + " col:" + ex.getColumnNumber();
        }

        /* ------------------------------------------------------------ */
        public InputSource resolveEntity(String pid, String sid)
        {
            if (LOG.isDebugEnabled())
                LOG.debug("resolveEntity(" + pid + ", " + sid + ")");
            
            if (sid!=null && sid.endsWith(".dtd"))
                _dtd=sid;
            
            URL entity = null;
            if (pid != null)
                entity = (URL) _redirectMap.get(pid);
            if (entity == null)
                entity = (URL) _redirectMap.get(sid);
            if (entity == null)
            {
                String dtd = sid;
                if (dtd.lastIndexOf('/') >= 0)
                    dtd = dtd.substring(dtd.lastIndexOf('/') + 1);

                if (LOG.isDebugEnabled())
                    LOG.debug("Can't exact match entity in redirect map, trying " + dtd);
                entity = (URL) _redirectMap.get(dtd);
            }

            if (entity != null)
            {
                try
                {
                    InputStream in = entity.openStream();
                    if (LOG.isDebugEnabled())
                        LOG.debug("Redirected entity " + sid + " --> " + entity);
                    InputSource is = new InputSource(in);
                    is.setSystemId(sid);
                    return is;
                }
                catch (IOException e)
                {
                    LOG.ignore(e);
                }
            }
            return null;
        }
    }

    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    /**
     * XML Attribute.
     */
    public static class Attribute
    {
        private String _name;
        private String _value;

        Attribute(String n, String v)
        {
            _name = n;
            _value = v;
        }

        public String getName()
        {
            return _name;
        }

        public String getValue()
        {
            return _value;
        }
    }

    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    /**
     * XML Node. Represents an XML element with optional attributes and ordered content.
     */
    public static class Node extends AbstractList<Object>
    {
        Node _parent;
        private ArrayList<Object> _list;
        private String _tag;
        private Attribute[] _attrs;
        private boolean _lastString = false;
        private String _path;

        /* ------------------------------------------------------------ */
        Node(Node parent, String tag, Attributes attrs)
        {
            _parent = parent;
            _tag = tag;

            if (attrs != null)
            {
                _attrs = new Attribute[attrs.getLength()];
                for (int i = 0; i < attrs.getLength(); i++)
                {
                    String name = attrs.getLocalName(i);
                    if (name == null || name.equals(""))
                        name = attrs.getQName(i);
                    _attrs[i] = new Attribute(name, attrs.getValue(i));
                }
            }
        }

        /* ------------------------------------------------------------ */
        public Node getParent()
        {
            return _parent;
        }

        /* ------------------------------------------------------------ */
        public String getTag()
        {
            return _tag;
        }

        /* ------------------------------------------------------------ */
        public String getPath()
        {
            if (_path == null)
            {
                if (getParent() != null && getParent().getTag() != null)
                    _path = getParent().getPath() + "/" + _tag;
                else
                    _path = "/" + _tag;
            }
            return _path;
        }

        /* ------------------------------------------------------------ */
        /**
         * Get an array of element attributes.
         */
        public Attribute[] getAttributes()
        {
            return _attrs;
        }

        /* ------------------------------------------------------------ */
        /**
         * Get an element attribute.
         * 
         * @return attribute or null.
         */
        public String getAttribute(String name)
        {
            return getAttribute(name, null);
        }

        /* ------------------------------------------------------------ */
        /**
         * Get an element attribute.
         * 
         * @return attribute or null.
         */
        public String getAttribute(String name, String dft)
        {
            if (_attrs == null || name == null)
                return dft;
            for (int i = 0; i < _attrs.length; i++)
                if (name.equals(_attrs[i].getName()))
                    return _attrs[i].getValue();
            return dft;
        }

        /* ------------------------------------------------------------ */
        /**
         * Get the number of children nodes.
         */
        public int size()
        {
            if (_list != null)
                return _list.size();
            return 0;
        }

        /* ------------------------------------------------------------ */
        /**
         * Get the ith child node or content.
         * 
         * @return Node or String.
         */
        public Object get(int i)
        {
            if (_list != null)
                return _list.get(i);
            return null;
        }

        /* ------------------------------------------------------------ */
        /**
         * Get the first child node with the tag.
         * 
         * @param tag
         * @return Node or null.
         */
        public Node get(String tag)
        {
            if (_list != null)
            {
                for (int i = 0; i < _list.size(); i++)
                {
                    Object o = _list.get(i);
                    if (o instanceof Node)
                    {
                        Node n = (Node) o;
                        if (tag.equals(n._tag))
                            return n;
                    }
                }
            }
            return null;
        }

        /* ------------------------------------------------------------ */
        @Override
        public void add(int i, Object o)
        {
            if (_list == null)
                _list = new ArrayList<Object>();
            if (o instanceof String)
            {
                if (_lastString)
                {
                    int last = _list.size() - 1;
                    _list.set(last, (String) _list.get(last) + o);
                }
                else
                    _list.add(i, o);
                _lastString = true;
            }
            else
            {
                _lastString = false;
                _list.add(i, o);
            }
        }

        /* ------------------------------------------------------------ */
        public void clear()
        {
            if (_list != null)
                _list.clear();
            _list = null;
        }

        /* ------------------------------------------------------------ */
        /**
         * Get a tag as a string.
         * 
         * @param tag The tag to get
         * @param tags IF true, tags are included in the value.
         * @param trim If true, trim the value.
         * @return results of get(tag).toString(tags).
         */
        public String getString(String tag, boolean tags, boolean trim)
        {
            Node node = get(tag);
            if (node == null)
                return null;
            String s = node.toString(tags);
            if (s != null && trim)
                s = s.trim();
            return s;
        }

        /* ------------------------------------------------------------ */
        public synchronized String toString()
        {
            return toString(true);
        }

        /* ------------------------------------------------------------ */
        /**
         * Convert to a string.
         * 
         * @param tag If false, only _content is shown.
         */
        public synchronized String toString(boolean tag)
        {
            StringBuilder buf = new StringBuilder();
            toString(buf, tag);
            return buf.toString();
        }

        /* ------------------------------------------------------------ */
        /**
         * Convert to a string.
         * 
         * @param tag If false, only _content is shown.
         */
        public synchronized String toString(boolean tag, boolean trim)
        {
            String s = toString(tag);
            if (s != null && trim)
                s = s.trim();
            return s;
        }

        /* ------------------------------------------------------------ */
        private synchronized void toString(StringBuilder buf, boolean tag)
        {
            if (tag)
            {
                buf.append("<");
                buf.append(_tag);

                if (_attrs != null)
                {
                    for (int i = 0; i < _attrs.length; i++)
                    {
                        buf.append(' ');
                        buf.append(_attrs[i].getName());
                        buf.append("=\"");
                        buf.append(_attrs[i].getValue());
                        buf.append("\"");
                    }
                }
            }

            if (_list != null)
            {
                if (tag)
                    buf.append(">");
                for (int i = 0; i < _list.size(); i++)
                {
                    Object o = _list.get(i);
                    if (o == null)
                        continue;
                    if (o instanceof Node)
                        ((Node) o).toString(buf, tag);
                    else
                        buf.append(o.toString());
                }
                if (tag)
                {
                    buf.append("</");
                    buf.append(_tag);
                    buf.append(">");
                }
            }
            else if (tag)
                buf.append("/>");
        }

        /* ------------------------------------------------------------ */
        /**
         * Iterator over named child nodes.
         * 
         * @param tag The tag of the nodes.
         * @return Iterator over all child nodes with the specified tag.
         */
        public Iterator<Node> iterator(final String tag)
        {
            return new Iterator<Node>()
            {
                int c = 0;
                Node _node;

                /* -------------------------------------------------- */
                public boolean hasNext()
                {
                    if (_node != null)
                        return true;
                    while (_list != null && c < _list.size())
                    {
                        Object o = _list.get(c);
                        if (o instanceof Node)
                        {
                            Node n = (Node) o;
                            if (tag.equals(n._tag))
                            {
                                _node = n;
                                return true;
                            }
                        }
                        c++;
                    }
                    return false;
                }

                /* -------------------------------------------------- */
                public Node next()
                {
                    try
                    {
                        if (hasNext())
                            return _node;
                        throw new NoSuchElementException();
                    }
                    finally
                    {
                        _node = null;
                        c++;
                    }
                }

                /* -------------------------------------------------- */
                public void remove()
                {
                    throw new UnsupportedOperationException("Not supported");
                }
            };
        }
    }
}
