/*
このファイルの中身は、NTT オープンソースライセンス　バージョン 1.0（「本
契約」という）の適用を受けます。
本契約を遵守しない限り、このファイルを使用してはなりません。
本契約のコピーは、次のＵＲＬから入手できます。
【配布サイトのURL】 http://www.oss.ecl.ntt.co.jp/lms/

本契約に基づき頒布されるソフトウェアは、現状のまま、明示又は黙示のあらゆ
る種類の保証なしで、頒布されます。本契約に基づく権利及び制限を律する特定
の文言については、本契約を参照してください。

「オリジナルコード」は、 NTT Cyber Space Laboratories Code です。 
「オリジナルコード」の「初期開発者」は、日本電信電話株式会社です。  
日本電信電話株式会社により創作された部分は、Copyright (C) 2004 
日本電信電話株式会社 です。
全ての権利が留保されます。 
「コントリビュータ」：_____________________________________ 


The contents of this file are subject to the NTT Opensource License
Version 1.0 (the License); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
【配布サイトのURL】 http://www.oss.ecl.ntt.co.jp/lms/

Software distributed under the License is distributed on an AS IS
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.

The Original Code is NTT Cyber Space Laboratories Code .

The Initial Developer of the Original Code is NIPPON TELEGRAPH AND 
TELEPHONE CORPORATION.
Portions created by the NIPPON TELEGRAPH AND TELEPHONE CORPORATION 
are Copyright (C) 2004 NIPPON TELEGRAPH AND TELEPHONE CORPORATION. 
All Rights Reserved.

Contributor(s) ______________________________________.
*/

//
//	RDFユーティリティクラス
//			変更履歴
//				2004.01.08	新規作成 T.Nijou
//

package jp.co.ntt.lms.Common.RDF;

import java.util.Vector;
import org.w3c.dom.*;


/**
 * RDFパース　ユーティリティクラス
 * @author T.Nijou
 * @version 0.0.0.1 2004/01/08
 */
public class RDFUtility {

	/**
	 * 指定されたIDの<Descriptioin>ノードを検索します。
	 * @param objNode 検索対象ノード
	 * @param strID ID
	 * @return Node 検索結果ノード
	 */
	public static Node searchDescritionNode( Node objNode, String strID ) {

		if( objNode == null ) {
			return null;
		}

		if( strID.equals( getAttribute( objNode, "ID" ) ) ) {
			return objNode;
		}

		NodeList objList = objNode.getChildNodes();
		if( objList != null ) {

			for( int i = 0; i < objList.getLength(); i++ ) {
				if( objList.item(i).getNodeType() != Node.TEXT_NODE &&
					objList.item(i).getNodeType() != Node.CDATA_SECTION_NODE ) {
					Node objResult = searchDescritionNode( objList.item(i), strID );
					if( objResult != null ) {
						return objResult;
					}
				}
			}
		}

		return null;

	}

	/**
	 * Nodeオブジェクトから指定されたIDのアトリビュートを取得します
	 * @param objNode Nodeオブジェクト
	 * @param strAttrID アトリビュートID
	 * @return String 取得した値 指定されたIDのアトリビュートが存在しない場合はnullを返す
	 */
	public static String getAttribute( Node objNode, String strAttrID ) {

		if( objNode == null ) {
			return null;
		}

		NamedNodeMap objMap = objNode.getAttributes();
		if( objMap == null ) {
			return null;
		}
		Attr objAttr = (Attr)objMap.getNamedItem( strAttrID );
		if( objAttr == null ) {
			return null;
		}
		return objAttr.getValue().trim();
	}

	/**
	 * ノードの子ノードから指定された名称のノードを検索する
	 * @param objNode Nodeオブジェクト
	 * @param strName 検索名称
	 * @return Node 検索結果 見つからなかった場合はnull
	 */
	public static Node searchNodeName( Node objNode, String strName ) {

		if( objNode == null ) {
			return null;
		}

		if( objNode.getNodeName().equals( strName ) ) {
			return objNode;
		}

		NodeList objList = objNode.getChildNodes();
		if( objList != null ) {

			for( int i = 0; i < objList.getLength(); i++ ) {
				if( objList.item(i).getNodeType() != Node.TEXT_NODE &&
					objList.item(i).getNodeType() != Node.CDATA_SECTION_NODE ) {
					Node objResult = searchNodeName( objList.item(i), strName );
					if( objResult != null ) {
						return objResult;
					}
				}
			}
		}

		return null;
	}

	/**
	 * ノードオブジェクトのテキストを取得するメソッドです
	 * @param objNode 対象ノード
	 * @return String テキスト 取得できない場合は空文字を返します
	 */
	public static String getText( Node objNode ) {

		if( objNode == null ) {
			return "";
		}

		String strText = "";

		NodeList objNodeList = objNode.getChildNodes();
		if( objNodeList != null ) {
			for( int i = 0; i < objNodeList.getLength(); i++ ) {
				//#TEXTセクション
				if( objNodeList.item(i).getNodeType() == Node.TEXT_NODE ) {
					strText = objNodeList.item(i).getNodeValue().trim();
				}
			}
		}
		return strText;
	}

	/**
	 * Nodeオブジェクトから子ノードのIDリストを検索して返します
	 * @param objNode 検索対象
	 * @return String[] IDリスト 見つからない場合は、長さ0の配列を返します
	 */
	public static String[] searchChildIDList( Node objNode ) {
		// 結果格納用
		Vector vecIDList = new Vector();

		// <SectionTop>の検索
		Node objSectionTop = searchNodeName( objNode, "SectionTop" );
		if( objSectionTop != null ) {
			// テキストを取得する
			String strText = getText( objSectionTop );
			vecIDList.add( strText );
		}

		// <Children>の検索
		Node objChildrenNode = searchNodeName( objNode, "Children" );
		if( objChildrenNode != null ) {
			String strText = getText( objChildrenNode );
			if( !strText.equals( "" ) ) {
				vecIDList.add( strText );
			}
			Node objRdSeq = searchNodeName( objChildrenNode, "Seq" );
			if( objRdSeq != null ) {
				NodeList objList = objRdSeq.getChildNodes();
				if( objList != null ) {
					for( int i = 0; i < objList.getLength(); i++ ) {
						if( objList.item(i).getNodeType() != Node.TEXT_NODE &&
							objList.item(i).getNodeType() != Node.CDATA_SECTION_NODE )
						{
							strText = getText( objList.item(i) );
							if( !strText.equals( "" ) ) {
								vecIDList.add( strText );
							}
						}
					}
				}
			}
		}

		// <Element>の検索
		Node objElementNode = searchNodeName( objNode, "Element" );
		if( objElementNode != null ) {
			String strText = getText( objElementNode );
			if( !strText.equals( "" ) ) {
				vecIDList.add( strText );
			}
			Node objRdSeq = searchNodeName( objElementNode, "Seq" );
			if( objRdSeq != null ) {
				NodeList objList = objRdSeq.getChildNodes();
				if( objList != null ) {
					for( int i = 0; i < objList.getLength(); i++ ) {
						if( objList.item(i).getNodeType() != Node.TEXT_NODE &&
							objList.item(i).getNodeType() != Node.CDATA_SECTION_NODE )
						{
							strText = getText( objList.item(i) );
							if( !strText.equals( "" ) ) {
								vecIDList.add( strText );
							}
						}
					}
				}
			}
		}



		String[] strIDList = new String[ vecIDList.size() ];
		// 配列コピー
		vecIDList.copyInto( strIDList );
		return strIDList;
	}

	/**
	 * NodeオブジェクトとDescriptionのID属性から、RDFNodeオブジェクトを作成します
	 * @param objNode Nodeオブジェクト
	 * @param strID ID属性
	 * @return RDFNode 作成したRDFNodeオブジェクト
	 */
	public static RDFNode createRDFInstance( Node objNode, String strID, RDFNode objParentNode ) {

		if( objNode == null ) {
			return null;
		}

		// IDからDescriptionノードを検索します
		Node objDescripNode = searchDescritionNode( objNode, strID );
		if( objDescripNode == null ) {
			return null;
		}

		RDFNode objRDFNode = new RDFNode();
		// 親ノードの設定
		objRDFNode.setParentNode( objParentNode );
		// IDの設定
		Node objTempNode = searchNodeName( objDescripNode, "UID" );
		objRDFNode.setID( getText( objTempNode ) );
		// タイトルの設定
		objTempNode = searchNodeName( objDescripNode, "Name" );
		objRDFNode.setTitle( getText( objTempNode ) );
		// Systemの設定
		objTempNode = searchNodeName( objDescripNode, "System" );				
		objRDFNode.setAUsystemID( getText( objTempNode ) );
		// 教材IDの設定
		objTempNode = searchNodeName( objDescripNode, "MaterialCode" );
		if( objTempNode != null ) {
			objRDFNode.setMaterialID( getText( objTempNode ) );
		}
		// バージョンの設定
		objTempNode = searchNodeName( objDescripNode, "Version" );
		if( objTempNode != null ) {
			objRDFNode.setVersion( getText( objTempNode ) );
		}
		// オーダーの設定
		objTempNode = searchNodeName( objDescripNode, "Order" );
		if( objTempNode != null ) {
			String tmpOrder = getText( objTempNode );
			if(tmpOrder != null){
				objRDFNode.setOrder( Integer.parseInt(tmpOrder) );
			}
		}
		// タイプの設定
		try {
			if( strID.indexOf( "Element" ) > 0) {
				// AUタイプ
				objRDFNode.setNodeType( RDFNode.AU_NODE );
			}
			else if( strID.indexOf( "Sections" ) > 0 ) {
				// Blockタイプ
				objRDFNode.setNodeType( RDFNode.BLOCK_NODE );
			}
			else {
				// Courseタイプ
				objRDFNode.setNodeType( RDFNode.COURSE_NODE );
			}
		}
		catch( RDFUnknownNodeTypeException e ) {
			e.printStackTrace();
		}
		// 子IDリストの取得(AUタイプ以外)
		if( objRDFNode.getNodeType() != RDFNode.AU_NODE ) {
			String[] strChildIDList = searchChildIDList( objDescripNode );
			for( int i = 0; i < strChildIDList.length; i++ ) {
				objRDFNode.addChild( createRDFInstance( objNode, strChildIDList[i], objRDFNode ) );
			}
		}

		return objRDFNode;
	}

}






