/* JFox, the OpenSource J2EE Application Server
 *
 * Distributable under GNU LGPL license by gun.org
 * more details please visit http://www.huihoo.org/jfox
 */

package org.jfox.framework.util;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
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.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public class XmlUtils {

    private XmlUtils() {

    }

    private static DocumentBuilder db = null;

    static {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            dbf.setValidating(false);
            db = dbf.newDocumentBuilder();
//      db.setEntityResolver(new EJBEntityResolver());
        }
        catch(ParserConfigurationException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * get child node of the node
     *
     * @param node
     * @param tagName
     * @return
     */
    public static Node getChildNodeOf(Node node, String tagName) {
        for(Node temp = node.getFirstChild(); temp != null; temp = temp.getNextSibling())
            if(temp.getNodeType() == Node.ELEMENT_NODE
                    && tagName.equals(temp.getNodeName())) {
                return temp;
            }
        return null;
    }

    public static String getChildNodeValueOf(Node node, String tagName) {
        if(tagName.equals(node.getNodeName())) {
            return getValueOf(node);
        }
        for(Node temp = node.getFirstChild(); temp != null; temp = temp.getNextSibling()) {
            if(temp.getNodeType() == Node.ELEMENT_NODE && tagName.equals(temp.getNodeName())) {
                return getValueOf(temp);
            }
        }
        return null;
    }

    public static final String getValueOf(Node node) {
        if(node == null) {
            return null;
        }
        else if(node instanceof Text) {
            return node.getNodeValue().trim();
        }
        else if(node instanceof Element) {
            ((Element) node).normalize();
            Node temp = node.getFirstChild();
            if(temp != null && (temp instanceof Text))
                return temp.getNodeValue().trim();
            else
                return "";
        }
        else {
            return node.getNodeValue().trim();
        }
    }

    public static final String getAtrributeValueOf(Node node, String attribute) {
        Node _node = node.getAttributes().getNamedItem(attribute);
        return getValueOf(_node);
    }

    public static Iterator getElementsByTagName(Element element, String tag) {
        ArrayList children = new ArrayList();
        if(element != null && tag != null) {
            NodeList nodes = element.getElementsByTagName(tag);
            for(int i = 0; i < nodes.getLength(); i++) {
                Node child = nodes.item(i);
//      System.out.println("Name: " + child.getNodeName() + ", Value: " + child.getFirstChild().getNodeValue());
                children.add((Element) child);
            }
        }
        return children.iterator();
    }

    public static Iterator getElementsByTagNames(Element element, String[] tags) {
        List children = new ArrayList();
        if(element != null && tags != null) {
            List tagList = Arrays.asList(tags);
            NodeList nodes = element.getChildNodes();
            for(int i = 0; i < nodes.getLength(); i++) {
                Node child = nodes.item(i);
                if(child.getNodeType() == Node.ELEMENT_NODE
                        && tagList.contains(((Element) child).getTagName())) {
                    children.add((Element) child);
//        System.out.println("Name: " + child.getNodeName() + ", Value: " + child.getFirstChild().getNodeValue());
                }
            }
        }
        return children.iterator();
    }

    /**
     * get the xml root document of the xml descriptor
     *
     * @param url the xml descriptor url
     * @return
     */

    public static Document getDocument(URL url) throws Exception {
        InputStream is = null;
        try {
            is = new BufferedInputStream(url.openStream());
            return db.parse(is);
        }
        finally {
            if(is != null) {
                try {
                    is.close();
                }
                catch(IOException e) {

                }
            }
        }
    }

    public static void main(String[] args) {

    }
}

