/*
 * @(#)XmlUtil.java
 *
 * Copyright 2001 Nomura Research Institute, LTD. All rights reserved.
 *
 * RID-X :  XPath Utility
 *
 * @author  Intelligent Technology Inc.
 * @version 1.01 2002/02/18
 */
package jp.co.nri.rid.mapper;


import java.io.*;
import org.w3c.dom.*;

import org.apache.xpath.XPathAPI;
import org.apache.xml.serialize.*;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import	jp.co.iti.fagot.util.*;

/**
  * XPath Utility
  **/
public class XmlUtil {

/**
  * コンストラクタ
  *
  */
    public XmlUtil() {}

/**
  * エレメントのテキストを取得
  *
  * @param  Node        elem            親エレメント
  * @param  String      rel_xpath       エレメント名
  *
  * @return String      テキスト
  */
    public String getTextValue(Node elem, String rel_xpath) throws Exception {
        Node rel_elem = XPathAPI.selectSingleNode( elem, rel_xpath );
        if (rel_elem == null) {
            ZDebug.err("Fail to get text Value: \"" + rel_xpath + "\" in " + elem.getNodeName() + ".");
            throw new Exception();
        }
        return getTextValue( rel_elem );
    }



/**
  * エレメントのテキストを取得
  *
  * @param  Node        elem            エレメント
  *
  * @return String      テキスト
  */
    public String getTextValue(Node elem) throws Exception {
        Node text_node = XPathAPI.selectSingleNode( elem, "text()" );
        if (text_node == null) {
            return "";
        }
        return text_node.getNodeValue();
    }



/**
  * エレメントにテキストを生成／取得
  *
  * @param  Node        elem            エレメント
  *
  * @return String      テキスト
  */
    public String createOrGetTextValue(Node elem) throws Exception {
        Node text = XPathAPI.selectSingleNode( elem, "text()" );
        if (text == null) {
            Document doc = elem.getOwnerDocument();
            text = doc.createTextNode("");
            elem.appendChild(text);
        }
        return text.getNodeValue();
    }



/**
  * エレメントにテキストを取得する／存在しない場合は生成
  *
  * @param  Node        elem            エレメント
  * @param  String      rel_xpath       エレメント名
  *
  * @return String      テキスト
  */
    public String createOrGetTextValue(Node elem, String rel_xpath) throws Exception {
        Element text_elem = createOrGetSubElement( elem, rel_xpath );
        return createOrGetTextValue(text_elem);
    }



/**
  * エレメントにテキストを指定する
  *
  * @param  Node        elem            親エレメント
  * @param  String      rel_xpath       エレメント名
  * @param  String      value           値
  *
  * @return void
  */
    public void setTextValue( Node elem, String rel_xpath, String value ) throws Exception {
        Node rel_elem = XPathAPI.selectSingleNode( elem, rel_xpath );
        if ( rel_elem == null ) {
            ZDebug.err("Fail to set text Value.");
            throw new Exception();
        }
        setTextValue( rel_elem, value );
    }



/**
  * エレメントにテキストを指定する
  *
  * @param  Element     elem            エレメント
  * @param  String      value           値
  *
  * @return void
  */
    public void setTextValue( Node elem, String value ) throws Exception {
        Node text_node = XPathAPI.selectSingleNode( elem, "text()" );
        text_node.setNodeValue(value);
    }



/**
  * エレメントにテキストを指定する
  *
  * @param  Element     elem            エレメント
  * @param  String      value           値
  *
  * @return void
  */
    public void createOrSetTextValue( Node elem, String value ) throws Exception {
        Node text_node = XPathAPI.selectSingleNode( elem, "text()" );
        if ( text_node == null ) {
            Document doc = elem.getOwnerDocument();
            Node text = doc.createTextNode(value);
            elem.appendChild(text);
        } else{
            text_node.setNodeValue(value);
		}
    }



/**
  * サブエレメントの(生成/取得)し、テキストを指定する
  *
  * @param  Element     parentElem      親エレメント
  * @param  String      subElemName     エレメント名
  * @param  String      value           値
  *
  * @return void
  */
    public void createOrSetTextValue( Element elem, String subElemName, String value ) throws Exception {
        Element subelem = createOrGetSubElement( elem, subElemName );
        createOrSetTextValue( subelem, value );
    }



/**
  * サブエレメントの生成　又は　取得
  *
  * @param  Element     parentElem      親エレメント
  * @param  String      subElemName     エレメント名
  *
  * @return Element     エレメント
  */
    public Element createOrGetSubElement( Node parentElem, String subElemName ) throws Exception {

        Element elem = (Element)XPathAPI.selectSingleNode( parentElem, subElemName );
        if ( elem == null ) {
            Document doc = parentElem.getOwnerDocument();
            elem = doc.createElement(subElemName);
            parentElem.appendChild(elem);
        }
        return elem;
    }



/**
  * サブエレメントの生成
  *
  * @param  Element     parentElem      親エレメント
  * @param  String      subElemName     エレメント名
  *
  * @return Element     エレメント
  */
    public Element createSubElement( Node parentElem, String subElemName ) throws Exception {
        Document doc = parentElem.getOwnerDocument();
        Element elem = doc.createElement(subElemName);
        parentElem.appendChild(elem);
        return elem;
    }



/**
  * エレメントにアトリビュート生成　又は　取得
  *
  * @param  Element     parentElem      エレメント
  * @param  String      attrName        アトリビュート名
  *
  * @return Attr        アトリビュート
  */
/*
    public Attr createOrGetAttribute( Element parentElem, String attrName ) throws Exception {
        Attr attr = (Attr)XPathAPI.selectSingleNode( parentElem, "@" + attrName );
        if ( attr == null ) {
            Document doc = parentElem.getOwnerDocument();
            attr = doc.createAttribute(attrName);
            attr.setNodeValue("");
            parentElem.setAttributeNode(attr);
        }
        return attr;
    }
*/


/**
  * エレメントにサブエレメントが存在するかの判断
  *
  * @param  Element     parent          エレメント
  * @param  String      childName       サブエレメント名（タグ）
  *
  * @return boolean     true(存在する) / false (存在しない)
  */
    public boolean hasChild(Element parent, String childName) throws Exception{
        NodeList list = XPathAPI.selectNodeList(parent, childName);
        return (list.getLength() > 0);
    }



/**
  * XMLのファイル出力
  *
  * @param  String      file            出力ファイル名
  * @param  Document    document        ドキュメント
  *
  * @return boolean     true(存在する) / false (存在しない)
  */
  public boolean writeDocment2XMLFile(String file, Document document) throws Exception  {
      // 出力
      OutputFormat fm = new OutputFormat(document,"Shift_JIS", true);
      FileOutputStream out = new FileOutputStream(file);
      DOMSerializer ser = new XMLSerializer(out,fm).asDOMSerializer();
      ser.serialize(document);
      return true;
  }

}