/*
 * Copyright 2004,2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.axis2.util;

import com.ibm.wsdl.Constants;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.util.StAXUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.CharacterData;
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.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Stack;


public class XMLUtils {
    public static final String charEncoding = "ISO-8859-1";
    private static final String saxParserFactoryProperty =
        "javax.xml.parsers.SAXParserFactory";

    private static DocumentBuilderFactory dbf = getDOMFactory();
    private static SAXParserFactory       saxFactory;
    private static Stack                  saxParsers = new Stack();

    private static String empty = "";
    private static ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());

    static {
        // Initialize SAX Parser factory defaults
        initSAXFactory(null, true, false);
    }

    /** 
     * Initializes the SAX parser factory.
     *
     * @param factoryClassName The (optional) class name of the desired
     *                         SAXParserFactory implementation. Will be
     *                         assigned to the system property
     *                         <b>javax.xml.parsers.SAXParserFactory</b>
     *                         unless this property is already set.
     *                         If <code>null</code>, leaves current setting
     *                         alone.
     * @param namespaceAware true if we want a namespace-aware parser
     * @param validating true if we want a validating parser
     *
     */
    public static void initSAXFactory(String factoryClassName,
                                      boolean namespaceAware,
                                      boolean validating)
    {
        if (factoryClassName != null) {
            try {
                saxFactory = (SAXParserFactory)Loader.loadClass(factoryClassName).
                    newInstance();
                /*
                 * Set the system property only if it is not already set to
                 * avoid corrupting environments in which Axis is embedded.
                 */
                if (System.getProperty(saxParserFactoryProperty) == null) {
                    System.setProperty(saxParserFactoryProperty,
                                       factoryClassName);
                }
            } catch (Exception e) {
                //log.error(Messages.getMessage("exception00"), e);
                saxFactory = null;
            }
       } else {
            saxFactory = SAXParserFactory.newInstance();
        }
        saxFactory.setNamespaceAware(namespaceAware);
        saxFactory.setValidating(validating);

        // Discard existing parsers
        saxParsers.clear();
    }

    private static DocumentBuilderFactory getDOMFactory() {
        DocumentBuilderFactory dbf;
        try {
            dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
        }
        catch( Exception e ) {
            //log.error(Messages.getMessage("exception00"), e );
            dbf = null;
        }
        return( dbf );
    }
    
    private static boolean tryReset= true;

    /** 
     * Returns a SAX parser for reuse.
     * @param parser A SAX parser that is available for reuse
     */
    public static void releaseSAXParser(SAXParser parser) {
        if(!tryReset) return;

        //Free up possible ref. held by past contenthandler.
        try{
            XMLReader xmlReader= parser.getXMLReader();
            if(null != xmlReader){
                synchronized (XMLUtils.class ) {
                    saxParsers.push(parser);
                }
            }
            else {
                tryReset= false;
            }
        } catch (org.xml.sax.SAXException e) {
            tryReset= false;
        }
    }
    /**
     * Gets an empty new Document.
     * @return Returns Document.
     * @throws ParserConfigurationException if construction problems occur
     */
    public static Document newDocument() 
         throws ParserConfigurationException
    {
        synchronized (dbf) {
            return dbf.newDocumentBuilder().newDocument();
        }
    }

    /**
     * Gets a new Document read from the input source.
     * @return Returns Document.
     * @throws ParserConfigurationException if construction problems occur
     * @throws SAXException if the document has xml sax problems
     * @throws IOException if i/o exceptions occur
     */
    public static Document newDocument(InputSource inp)
        throws ParserConfigurationException, SAXException, IOException
    {
        DocumentBuilder db;
        synchronized (dbf) {
            db = dbf.newDocumentBuilder();
        }
        db.setEntityResolver(new DefaultEntityResolver());
        db.setErrorHandler( new ParserErrorHandler() );
        return( db.parse( inp ) );
    }

    /**
     * Gets a new Document read from the input stream
     * @return Returns Document.
     * @throws ParserConfigurationException if construction problems occur
     * @throws SAXException if the document has xml sax problems
     * @throws IOException if i/o exceptions occur
     */
    public static Document newDocument(InputStream inp) 
        throws ParserConfigurationException, SAXException, IOException 
    {
        return XMLUtils.newDocument(new InputSource(inp));
    } 

    /**
     * Gets a new Document read from the indicated uri
     * @return Returns Document.
     * @throws ParserConfigurationException if construction problems occur
     * @throws SAXException if the document has xml sax problems
     * @throws IOException if i/o exceptions occur
     */
    public static Document newDocument(String uri) 
        throws ParserConfigurationException, SAXException, IOException 
    {
        // call the authenticated version as there might be 
        // username/password info embeded in the uri.
        return XMLUtils.newDocument(uri, null, null);
    }
    
    /**
     * Creates a new document from the given URI. Uses the username and password
     * if the URI requires authentication.
     * @param uri the resource to get
     * @param username basic auth username
     * @param password basic auth password
     * @throws ParserConfigurationException if construction problems occur
     * @throws SAXException if the document has xml sax problems
     * @throws IOException if i/o exceptions occur
     */ 
    public static Document newDocument(String uri, String username, String password)
        throws ParserConfigurationException, SAXException, IOException
     {
         InputSource ins = XMLUtils.getInputSourceFromURI(uri, username, password);
         Document doc = XMLUtils.newDocument(ins);
         // Close the Stream
         if (ins.getByteStream() != null) {
             ins.getByteStream().close();
         } else if (ins.getCharacterStream() != null) {
             ins.getCharacterStream().close();
         }
         return doc;
     }



    public static String getPrefix(String uri, Node e) {
        while (e != null && (e.getNodeType() == Element.ELEMENT_NODE)) {
            NamedNodeMap attrs = e.getAttributes();
            for (int n = 0; n < attrs.getLength(); n++) {
                Attr a = (Attr)attrs.item(n);
                String name;
                if ((name = a.getName()).startsWith("xmlns:") &&
                    a.getNodeValue().equals(uri)) {
                    return name.substring(6);
                }
            }
            e = e.getParentNode();
        }
        return null;
    }

    public static String getNamespace(String prefix, Node e) {
        while (e != null && (e.getNodeType() == Node.ELEMENT_NODE)) {
            Attr attr =
                ((Element)e).getAttributeNodeNS(Constants.NS_URI_XMLNS, prefix);
            if (attr != null) return attr.getValue();
            e = e.getParentNode();
        }
        return null;
    }

    /**
     * Returns a QName when passed a string like "foo:bar" by mapping
     * the "foo" prefix to a namespace in the context of the given Node.
     *
     * @return Returns a QName generated from the given string representation.
     */
    public static QName getQNameFromString(String str, Node e) {
        if (str == null || e == null)
            return null;

        int idx = str.indexOf(':');
        if (idx > -1) {
            String prefix = str.substring(0, idx);
            String ns = getNamespace(prefix, e);
            if (ns == null)
                return null;
            return new QName(ns, str.substring(idx + 1));
        } else {
            return new QName("", str);
        }
    }

    /**
     * Returns a string for a particular QName, mapping a new prefix
     * if necessary.
     */
    public static String getStringForQName(QName qname, Element e)
    {
        String uri = qname.getNamespaceURI();
        String prefix = getPrefix(uri, e);
        if (prefix == null) {
            int i = 1;
            prefix = "ns" + i;
            while (getNamespace(prefix, e) != null) {
                i++;
                prefix = "ns" + i;
            }
            e.setAttributeNS(Constants.NS_URI_XMLNS,
                        "xmlns:" + prefix, uri);
        }
        return prefix + ":" + qname.getLocalPart();
    }

  /**
   * Concatinates all the text and cdata node children of this elem and returns
   * the resulting text.
   * (by Matt Duftler)
   *
   * @param parentEl the element whose cdata/text node values are to
   *                 be combined.
   * @return Returns the concatinated string.
   */
  public static String getChildCharacterData (Element parentEl) {
    if (parentEl == null) {
      return null;
    }
    Node          tempNode = parentEl.getFirstChild();
    StringBuffer  strBuf   = new StringBuffer();
    CharacterData charData;

    while (tempNode != null) {
      switch (tempNode.getNodeType()) {
        case Node.TEXT_NODE :
        case Node.CDATA_SECTION_NODE : charData = (CharacterData)tempNode;
                                       strBuf.append(charData.getData());
                                       break;
      }
      tempNode = tempNode.getNextSibling();
    }
    return strBuf.toString();
  }
    
    public static class ParserErrorHandler implements ErrorHandler
    {
        /**
         * Returns a string describing parse exception details
         */
        private String getParseExceptionInfo(SAXParseException spe) {
            String systemId = spe.getSystemId();
            if (systemId == null) {
                systemId = "null";
            }
            return "URI=" + systemId +
                " Line=" + spe.getLineNumber() +
                ": " + spe.getMessage();
        }

        // The following methods are standard SAX ErrorHandler methods.
        // See SAX documentation for more info.

        public void warning(SAXParseException spe) throws SAXException {
        }
        
        public void error(SAXParseException spe) throws SAXException {
            String message = "Error: " + getParseExceptionInfo(spe);
            throw new SAXException(message);
        }

        public void fatalError(SAXParseException spe) throws SAXException {
            String message = "Fatal Error: " + getParseExceptionInfo(spe);
            throw new SAXException(message);
        }
    }


    /**
     * Utility to get the bytes uri.
     * Does NOT handle authenticated URLs, 
     * use getInputSourceFromURI(uri, username, password)
     *
     * @param uri the resource to get
     */
    public static InputSource getInputSourceFromURI(String uri) {
        return new InputSource(uri);
    }



    /**
     * Utility to get the bytes at a protected uri
     * 
     * Retrieves the URL if a username and password are provided.
     * The java.net.URL class does not do Basic Authentication, so we have to
     * do it manually in this routine.
     * 
     * If no username is provided, creates an InputSource from the uri
     * and lets the InputSource go fetch the contents.
     * 
     * @param uri the resource to get
     * @param username basic auth username
     * @param password basic auth password
     */ 
    private static InputSource getInputSourceFromURI(String uri,
                                                     String username,
                                                     String password)
        throws IOException, ProtocolException, UnsupportedEncodingException
    {
        URL wsdlurl = null;
        try {
            wsdlurl = new URL(uri);
        } catch (MalformedURLException e) {
            // we can't process it, it might be a 'simple' foo.wsdl
            // let InputSource deal with it
            return new InputSource(uri);
        }
        
        // if no authentication, just let InputSource deal with it
        if (username == null && wsdlurl.getUserInfo() == null) {
            return new InputSource(uri);
        }
        
        // if this is not an HTTP{S} url, let InputSource deal with it
        if (!wsdlurl.getProtocol().startsWith("http")) {
            return new InputSource(uri);
        }

        URLConnection connection = wsdlurl.openConnection();
        // Does this work for https???
        if (!(connection instanceof HttpURLConnection)) {
            // can't do http with this URL, let InputSource deal with it
            return new InputSource(uri);
        }
        HttpURLConnection uconn = (HttpURLConnection) connection;
        String userinfo = wsdlurl.getUserInfo();
        uconn.setRequestMethod("GET");
        uconn.setAllowUserInteraction(false);
        uconn.setDefaultUseCaches(false);
        uconn.setDoInput(true);
        uconn.setDoOutput(false);
        uconn.setInstanceFollowRedirects(true);
        uconn.setUseCaches(false);

        // username/password info in the URL overrides passed in values 
        String auth = null;
        if (userinfo != null) {
            auth = userinfo;
        } else if (username != null) {
            auth = (password == null) ? username : username + ":" + password;
        }
        
        if (auth != null) {
            uconn.setRequestProperty("Authorization",
                                     "Basic " + 
                                     base64encode(auth.getBytes(charEncoding)));
        }
        
        uconn.connect();

        return new InputSource(uconn.getInputStream());
    }

    public static String base64encode(byte[] bytes) {
        return Base64.encode(bytes);
    }

    public static InputSource getEmptyInputSource() {
        return new InputSource(bais);
    }
    
    /**
     * Finds a Node with a given QNameb.
     * 
     * @param node parent node
     * @param name QName of the child we need to find
     * @return Returns child node.
     */ 
    public static Node findNode(Node node, QName name){
        if(name.getNamespaceURI().equals(node.getNamespaceURI()) && 
           name.getLocalPart().equals(node.getLocalName()))
            return node;
        NodeList children = node.getChildNodes();
        for(int i=0;i<children.getLength();i++){
            Node ret = findNode(children.item(i), name);
            if(ret != null)
                return ret;
        }
        return null;
    }
    
    /**
     * Converts a given DOM Element to an OMElement.
     * @param element
     * @return Returns OMElement.
     * @throws Exception
     */
    public static OMElement toOM(Element element) throws Exception {

        Source source = new DOMSource(element);
         
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Result result = new StreamResult(baos);

        Transformer xformer = TransformerFactory.newInstance().newTransformer();
        xformer.transform(source, result);

        ByteArrayInputStream is = new ByteArrayInputStream(baos.toByteArray());
        XMLStreamReader reader = StAXUtils
                .createXMLStreamReader(is);

        StAXOMBuilder builder = new StAXOMBuilder(reader);
        builder.setCache(true);

        return builder.getDocumentElement();
    }
    

    /**
     * Converts a given OMElement to a DOM Element.
     * @param element
     * @return Returns Element.
     * @throws Exception
     */
    public static Element toDOM(OMElement element) throws Exception {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            element.serialize(baos);
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(true);
            return factory.newDocumentBuilder().parse(bais).getDocumentElement();
    }
}
