/*
 * This file (ReadFromXML.java) is part of DebGen-ReportPrintLib  developed by ASTRID Research.
 * All rights reserved. Reproduction, modification, use or disclosure
 * to third parties without express authority is forbidden.
 *
 *  Copyright ASTRID Research, Hungary, 2010.
 *
 *  ASTRID Research
 *  Headquaters: Csapó utca 42. Debrecen H-4029 HUNGARY
 *  Phone: +36-52-533-173        Fax: +36-52-533-174
 *  Web: http://www.astrid.hu    E-mail: info@astrid.hu
 *
 * Project name: DEBGEN-Biobank-Project.
 * File last modified at 2010.01.08 14:39
 */

package hu.astrid.printxml.util;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.List;
import java.util.Vector;

/**
 * Reades data from XML
 * @author inagy
 */
public abstract class ReadFromXML {

    /**
     * Reades a file and creates a DOM Document from it
     * @param file The XML file
     * @return The DOM Document
     */
    public static Document readFromXml(File file) {
        return readFromXml(file.toURI());
//        Document doc = null;
//        try {
//            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//            dbf.setNamespaceAware(true);
//            doc = dbf.newDocumentBuilder().parse(new InputSource(new FileReader(file)));
//        } catch (Exception ex) {
//            ex.printStackTrace();
//        }
//        return doc;
    }

    /**
     * Reades a file from an URI and creates a DOM Document from it
     * @param uri The URI of the XML file
     * @return The DOM Document
     */
    public static Document readFromXml(URI uri) {
        Document doc = null;
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            doc = dbf.newDocumentBuilder().parse(new InputSource(uri.toURL().openStream()));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return doc;
    }

    /**
     * Get node value
     *
     * @param node  Root node.
     * @param chain Nodes chain to requested value
     * @return requested node value
     */
    public static String getNodeValue(Node node, String... chain) {
        Node n = getNode(node, chain);

        // System.out.println(n==null?"igen":"nem");
        try {
            return n.getFirstChild().getNodeValue();

        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    /**
     * Get node
     *
     * @param node  Root node.
     * @param chain Nodes chain to requested node
     * @return requested node
     */
    public static Node getNode(Node node, String... chain) {
        List<Node> list = getNodes(node, chain);
        return (list == null || list.isEmpty() ? null : list.get(0));
    }

    /**
     * Get node list
     *
     * @param node  Root node.
     * @param chain Nodes chain to requested node
     * @return requested nodes
     */
    public static List<Node> getNodes(Node node, String... chain) {
        List<Node> result = new Vector<Node>();
        Node step = node;
        boolean last = false;

        for (int k = 0; k < chain.length; k++) {
            if (k == (chain.length - 1)) {
                last = true;
            }
            String s = chain[k];
            NodeList nl = step.getChildNodes();
            for (int i = 0; i < nl.getLength(); i++) {
                Node n = nl.item(i);
                if (n.getNodeName().equals(s)) {
                    if (!last) {
                        step = n;
                        break;
                    } else {
                        result.add(n);
                    }
                }
            }

        }
        return result;
    }

    /**
     * Reads a resource with the given name
     * @param resourceName The name of the resource
     * @return The string content of the resource
     * @throws Exception When the read operation is not possible
     */
    public static String readResource(String resourceName) throws Exception {
        StringBuilder buffer = new StringBuilder();
        InputStream in = null;
        InputStreamReader isr = null;
        try {

            in = ReadFromXML.class.getResourceAsStream(resourceName);
            isr = new InputStreamReader(in);

            //DONE? buffert kene hasznalni (byte[])
            char[] c = new char[1024];
            int i;
            while ((i = isr.read(c)) != -1) {
                buffer.append(c, 0, i);
            }

            return buffer.toString();
        } finally {
            try {
                isr.close();
            } catch (Exception ex) {
                //IGNORED
            }
            try {
                in.close();
            } catch (Exception ex) {
                //IGNORED
            }
        }
    }
}