/////////////////////////////////////////////////////////////////
//Copyright (C) 2005 NTT CORPORATION.
//
//LoInfo オブジェクトリスト生成クラス
//
//変更履歴
//2005.01.27  新規作成  森　智志
//
//機能
//
//　XPath 式を用いて、ノード検索を行うためのクラスです。
//
/////////////////////////////////////////////////////////////////
package jp.co.ntt.lms.lo.lom.learnableinfo;

import java.io.File;
import java.io.IOException;
import java.io.UTFDataFormatException;

import javax.xml.parsers.*;
import javax.xml.transform.TransformerException;

import org.apache.xpath.XPathAPI;
import org.w3c.dom.*;
import org.xml.sax.SAXException;

/**
 * XPath 式を用いて、ノード検索を行うためのクラスです。
 * @author s-mori
 * @version 1.0
 */
public class NodeController {

	Document document = null;
	
    /**
     * XMLファイルをパースしてDocumentオブジェクトを作成します。
     * @param xmlFile パース対象のXMLファイル
     * @throws Exception
     */
    public Node parse(File xmlFile) throws Exception{
        DocumentBuilderFactory dbf = null;
        DocumentBuilder parser = null;
        Document document = null;
        
        dbf = DocumentBuilderFactory.newInstance();

        dbf.setIgnoringElementContentWhitespace(true);
        dbf.setNamespaceAware(true);
        //dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage","http://www.w3.org/2001/XMLSchema");


        // DocumentBuilder を作成
        try {
            parser = dbf.newDocumentBuilder();
        }catch (ParserConfigurationException ex) {
            throw ex;
        }

        //パースを行い、取得したオブジェクトを doc フィールドへ
        try{
            document = parser.parse(xmlFile);
        }catch (UTFDataFormatException ex){
            throw ex;
        }catch (IOException ex) {
            throw ex;
        }catch (SAXException ex) {
            throw ex;
        }
        
        this.document = document;
        return document;

    }
	
	
	
    /**
     * XPath式に相当するノードのリストを取得します。
     * @param document ノードオブジェクト
     * @param xPathStr XPath式
     * @param namespaceNode 名前空間ノード
     * @return XPath式に該当するノードのNodeList
     * @throws Exception
     * */
	public NodeList getNodeList(Node document, String xPathStr, Node namespaceNode) throws Exception{
		if(document == null){
            throw new NullPointerException("The document is null.");
        }
		if(xPathStr == null || xPathStr.equals("")){
            throw new NullPointerException("The parameter (XPath string) is null.");
		}

		NodeList nodeList = null;
		
        try {
        	if(namespaceNode == null){
        		nodeList = XPathAPI.selectNodeList(document, xPathStr);
        	}else{
        		nodeList = XPathAPI.selectNodeList(document, xPathStr, namespaceNode);
        	}
        }
        catch (TransformerException ex) {
            throw ex;
        }

		return nodeList;
	}
	
    /**
     * XPath式に相当するノードのリストを取得します。
     * @param document ノードオブジェクト
     * @param xPathStr XPath式
     * @return XPath式に該当するノードのNodeList
     * @throws Exception
     * */
	public NodeList getNodeList(Node document, String xPathStr) throws Exception{
		return this.getNodeList(document, xPathStr, null);
	}

    /**
     * XPath式に相当するノードを取得します。複数該当する場合は、最初に該当したノードを返します。
     * @param document ノードオブジェクト
     * @param xPathStr XPath式
     * @param namespaceNode 名前空間ノード
     * @return XPath式に該当するノード
     * @throws Exception
     * */
	public Node getNode(Node document, String xPathStr, Node namespaceNode) throws Exception{

		NodeList nodeList = this.getNodeList(document, xPathStr, namespaceNode);
		if(nodeList.getLength() == 0){
			return null;
		}else{
			return nodeList.item(0);
		}
		
	}

    /**
     * XPath式に相当するノードを取得します。複数該当する場合は、最初に該当したノードを返します。
     * @param document ノードオブジェクト
     * @param xPathStr XPath式
     * @return XPath式に該当するノード
     * @throws Exception
     */
	public Node getNode(Node document, String xPathStr) throws Exception{
		return this.getNode(document, xPathStr, null);
	}

	
	/**
	 * XPath式の特殊文字列をエスケープします。
	 * @param str 文字列
	 * @return エスケープ文字列
	 */
	public static String escapeString(String str){
		if(str == null){
			return null;
		}
		
		String buf = str;
		buf = buf.replaceAll("&", "&amp;");
		buf = buf.replaceAll("'", "&apos;");
		buf = buf.replaceAll("\"", "&quot;");
		buf = buf.replaceAll("<", "&lt;");
		buf = buf.replaceAll(">", "&gt;");
		
		return buf;
		
	}

}
