package com.nifty.cloud.ncs.util;

import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

/**
 * XML解析用クラスです。
 *
 */
public class XmlUtils
{
	private XPathFactory xpathFactory = XPathFactory.newInstance();
	private XPath xpath = xpathFactory.newXPath();
	private DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
	private Document doc;

	/**
	 * 指定した入力ストリームを使用してXmlUtilsを生成します。
	 *
	 * @param is
	 * 	XMLデータを含む入力ストリーム
	 *
	 * @throws SAXException
	 * @throws IOException
	 * @throws ParserConfigurationException
	 */
	public XmlUtils(InputStream is) throws SAXException, IOException, ParserConfigurationException
	{
		doc = dbFactory.newDocumentBuilder().parse(is);
	}

    /**
     * 指定したexpressionの文字列を返却します。
     *
     * @param expression
     *
     * @return 指定したexpressionの評価結果の文字列
     *
     * @throws XPathExpressionException
     */
	public String getString(String expression) throws XPathExpressionException
	{
		return (getString(expression, doc));
	}

    /**
     * 指定したXPath表現を評価し、結果を返却します。
     *
     * @param name
     *            評価するXPath表現
     * @param node
     *            expressionを実行するノード
     *
     * @return 結果ノード
     *
     * @throws XPathExpressionException
     */
	private Node evaluateNode(String name, Node node) throws XPathExpressionException
	{
		if (node == null) {
			return (null);
		}

		Node n = (Node)xpath.evaluate(name, node, XPathConstants.NODE);

		return (n);
	}

    /**
     * 指定したノード上の指定したexpression文字列を返却します
     *
     * @param expression
     *            評価するXPath表現
     * @param node
     *            expression評価を実行するノード
     *
     * @return 指定したexpressionの評価結果の文字列
     *
     * @throws XPathExpressionException
     */
	private String getString(String expression, Node node) throws XPathExpressionException
	{
		if (node == null) {
			return (null);
		}

		if (expression.equals(".") == false) {
			if (evaluateNode(expression, node) == null) {
				return (null);
			}
		}

		String s = xpath.evaluate(expression, node);

		return (s.trim());
	}
}
