/*
このファイルの中身は、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) ______________________________________.
*/

//
//	ScormLo
//	変更履歴
//		2004.02.01	新規作成
//		2004.09.14	M004	A.Shimoma
//

package jp.co.ntt.lms.lo.scorm;

import java.io.File;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;

import jp.co.ntt.lms.lo.LOException;
import jp.co.ntt.lms.lo.LoConstant;
import jp.co.ntt.lms.lo.LoLogSessionDataAccess;
import jp.co.ntt.lms.lo.LoPropertyDef;
import jp.co.ntt.lms.lo.LoServer;
import jp.co.ntt.lms.xmo.DataAccess;
import jp.co.ntt.lms.xmo.MessageData;
import jp.co.ntt.lms.xmo.Lo.MaterialData;
import jp.co.ntt.lms.xmo.util.DebugLog;
import jp.co.ntt.lms.xmo.util.FileControl;

import org.w3c.dom.Document;

/**
 * SCORM LOサーバクラスです。<BR>
 * @author T.Nishiki
 */
public class ScormLo extends LoServer implements Remote {
	/**
	 * コンストラクタ。
	 * @throws LOException 初期化に失敗した場合。
	 * @throws RemoteException RMI関連の初期化に失敗した場合。
	 */
	public ScormLo() throws LOException, RemoteException {
		super();

		// メソッド開始ログ
		DebugLog.write(ScormLo.class, "HEAD ScormLo()", DebugLog.ROW);

		try {
			mobjMenuMakerIF = new ScormMenuMaker();
			mobjLearnManagerIF = new ScormLearnManager();
			mobjSetupIF = new ScormSetup();

			// SCORMのLOTYPE「２０」がLOTYPEテーブルに存在する場合
			if (getLoType(LoConstant.LO_TYPE_SCORM)) {

				// SCORM LO サーバ情報を初期化します。
				ScormServerInfoControl control = null;
				control = ScormServerInfoControl.getInstance();
				control.initialize();
			}
		}
		catch (LOException e) {
			throw e;
		}
		catch (Exception e) {
			throw new LOException(this.getClass().getName() + " :: ロード失敗 ");
		}

		// メソッド終了ログ
		DebugLog.write(ScormLo.class, "TAIL ScormLo()", DebugLog.ROW);
	}

	/**
	 * Loに登録されているメソッドを起動します。<br>
	 * 現在有効なメソッドは、{@link #getServerInfo()}だけです。
	 * @param methodName 起動するメソッド名称。<br>
	 * @param params パラメータ。
	 * @return 起動したメソッドから戻されたVector。
	 * @see #getServerInfo()
	 * @see #isExistLoginSession(Hashtable)
	 * @see jp.co.ntt.lms.lo.LoTop#execute(String, Hashtable)
	 * @see ScormLoConstant#METHOD1
	 * @see ScormLoConstant#METHOD2
	 * @see ScormLoConstant#METHOD3
	 * @see ScormLoConstant#METHOD4
	 */
	public Vector execute(String methodName, Hashtable params) {

		Vector returnValue = null;

		if (methodName.equals(ScormLoConstant.METHOD1)) {
			returnValue = getServerInfo();
		}
		else if (methodName.equals(ScormLoConstant.METHOD2)) {
			returnValue = isExistLoginSession(params);
		}
		else if (methodName.equals(ScormLoConstant.METHOD3)) {
			returnValue = insertCommonLog(params);
		}
		else {
			returnValue = new Vector();
		}
		return returnValue;
	}

	/**
	 * SCORM LOサーバ情報のリストを取得します。<br>
	 * @return ０番目の要素に処理メッセージ、
	 *          １番目に「ScormServerInfoを要素とするList」を格納されたVector。
	 */
	public Vector getServerInfo() {
		// メソッド開始ログ
		DebugLog.write(
			this.getClass(), "HEAD getServerInfo()",
			DebugLog.ROW);

		Vector returnValue = new Vector();
		List serverInfoList = null;
		MessageData message = null;

		// サーバ情報リストを取得します
		ScormServerInfoControl control =
			ScormServerInfoControl.getInstance();
		serverInfoList = control.getServerInfoList();

		returnValue.add(message);
		returnValue.add(serverInfoList);

		// メソッド終了ログ
		DebugLog.write(
			this.getClass(), "TAIL getServerInfo() return " + returnValue,
			DebugLog.ROW);
		return returnValue;
	}

	/**
	 * ログインセッション回数が存在するかチェックします。<br>
	 * @param params パラメータ。
	 * 以下の値が設定されていることを期待しています。<br>
	 * <table border="1">
	 * 	<tr>
	 * 		<th>キー</th>
	 * 		<th>値</th>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>ScormConstant.KEY_USERID</td>
	 * 		<td>ユーザID</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>ScormConstant.KEY_LOID</td>
	 * 		<td>LOID</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>ScormConstant.KEY_LOGIN_SESSION</td>
	 * 		<td>ログインセッション回数</td>
	 * 	</tr>
	 * </table><br>
	 * @return ０番目の要素に処理メッセージ、
	 *          １番目に「存在するならtrue、存在しないならfalseの
	 *           ラッパークラス（{@link Boolean}）オブジェクト」を格納したVector。
	 */
	public Vector isExistLoginSession(Hashtable params) {
		// メソッド開始ログ
		DebugLog.write(
			this.getClass(),
			"HEAD isExistLoginSession(" + params + ")",
			DebugLog.ROW);

		Vector returnValue = null;

		// サーバ情報リストを取得します
		try {
			// パラメータの取得
			String userID = (String)params.get(ScormLoConstant.KEY_USERID);
			String loID = (String)params.get(ScormLoConstant.KEY_LOID);
			String loginSession = (String)params.get(
							ScormLoConstant.KEY_LOGIN_SESSION);
			// 検索
			boolean result = LoLogSessionDataAccess.isExistLoginSession(
								userID, loID, loginSession);
			// 結果を戻り値に格納
			returnValue = new Vector();
			returnValue.add(null);
			returnValue.add(Boolean.valueOf(result));
		}
		catch (LOException e) {
			DebugLog.write(this.getClass(), e.getMessage(), DebugLog.HIGHT);
			MessageData message = createSystemErrMessage(e.getMessage());
			returnValue = new Vector();
			returnValue.add(message);
		}


		// メソッド終了ログ
		DebugLog.write(
			this.getClass(),
			"TAIL isExistLoginSession(" + params + ")"
			+ " return " + returnValue,
			DebugLog.ROW);
		return returnValue;
	}

	/**
	 * 共通ログを登録します。<br>
	 * @param params パラメータ。
	 * 以下の値が設定されていることを期待しています。<br>
	 * <table border="1">
	 * 	<tr>
	 * 		<th>キー</th>
	 * 		<th>値</th>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>ScormConstant.KEY_END_LEARN_DATA</td>
	 * 		<td>学習終了情報ScormLoEndLearnData</td>
	 * 	</tr>
	 * </table><br>
	 * @return ０番目の要素に処理メッセージを格納したVector。
	 * @see ScormLoEndLearnData
	 */
	public Vector insertCommonLog(Hashtable params) {
		// メソッド開始ログ
		DebugLog.write( this.getClass(),
			"HEAD insertCommonLog(" + params + ")",
			DebugLog.ROW);

		Vector returnValue = null;

		// サーバ情報リストを取得します
		DataAccess dataAccess = new DataAccess();
		try {
			dataAccess.trans();
			////////////////////////////////////////////////////////////////////
			// データの取得
			ScormLoEndLearnData endLearnData =
					(ScormLoEndLearnData)params.get(
							ScormLoConstant.KEY_END_LEARN_DATA);
			////////////////////////////////////////////////////////////////////
			// ログの挿入(終了理由が中止の場合、挿入しない）
			String reason = endLearnData.getReason();
			if (reason.equals(ScormLoConstant.PARAM_REASON_ABANDON) == false) {
				ScormLoLogControl logControl = new ScormLoLogControl();
				logControl.insertRestOfAiccLog(dataAccess, endLearnData);
			}
			// 結果を戻り値に格納
			returnValue = new Vector();
			returnValue.add(null);
			// コミット
			dataAccess.commit();
		}
		catch (Exception e) {
			MessageData message = createSystemErrMessage(e.getMessage());
			DebugLog.write(this.getClass(), message, DebugLog.HIGHT);

			try {
				dataAccess.rollback();
			}
			catch (Exception e1) {
				DebugLog.write(this.getClass(), e1, DebugLog.HIGHT);
			}

			returnValue = new Vector();
			returnValue.add(message);
		}


		// メソッド終了ログ
		DebugLog.write( this.getClass(),
			"TAIL insertCommonLog(" + params + ")"
			+ " return " + returnValue,
			DebugLog.ROW);
		return returnValue;
	}

	/**
	 * 教材リストを取得します。<br>
	 * @param params パラメータ。
	 *                以下のデータが含まれていることを期待しています。<br>
	 * <table border="1">
	 * 	<tr>
	 * 		<th>キー</th>
	 * 		<th>値</th>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>&quot;METHOD&quot;</td>
	 * 		<td>INSERT、UPDATEなどのメソッド種別</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>&quot;MATERIALID&quot;</td>
	 * 		<td>教材ID。METHODがINSERTの場合、不要。</td>
	 * 	</tr>
	 * </table>
	 * @return ０番目の要素に処理メッセージ、
	 *          １番目に「MaterialDataの配列」を格納されたVector。
	 * @see jp.co.ntt.lms.lo.LoTop#getMaterialList(java.util.Hashtable)
	 */
	public Vector getMaterialList(Hashtable params) {
		// メソッド開始ログ
		DebugLog.write(
			this.getClass(), "HEAD getMaterialList(" +  params + ")",
			DebugLog.ROW);

		Vector returnValue = new Vector();

		MessageData message = null;
		MaterialData[] materialArray = null;
		try {
			String methodType = (String)params.get("METHOD");
			String materialID = (String)params.get("MATERIALID");

			// 教材Tempディレクトリパス取得
			String strTempMaterialPath = "";
			ScormLoEnv scormEnv = new ScormLoEnv();
			//登録処理の場合、教材Tempディレクトリパス取得
			if (methodType.equals("INSERT")) {
				strTempMaterialPath = scormEnv.getTempMaterialPath();
				
				
			}
			//登録処理以外の場合、教材ディレクトリパス取得
			else {
				strTempMaterialPath = scormEnv.getMaterialPath();
			}

			String[] strDirList =
				FileControl.getFileList(
					strTempMaterialPath,
					FileControl.DIR_LIST);

			Vector materialList = new Vector();
			for (int i = 0; i < strDirList.length; i++) {
				if ((methodType.equals("INSERT") == false)
					&& (materialID.equals(strDirList[i]) == false)) {
					continue;
				}

/////////////////////////////////////////////////////////////////////////
//追加修正 START
//Author:NTTR JSATOU
//DATE:20050217
//内容：imsmanifest.xmlファイルの有無を確認
/////////////////////////////////////////////////////////////////////////
				boolean exists_flag = false;
				
				    //パーサーの取得
					File dummy = new File(strTempMaterialPath);
					char separator = dummy.separatorChar;
				
					//imsmanifest.xmlファイルオブジェクトの生成
					String strManifestFilePath = strTempMaterialPath + separator + strDirList[i] + separator + ScormLoConstant.MANIFEST_FILE_NAME;
					File objManifestFile = new File(strManifestFilePath);

					//デバックプリント
					DebugLog.write(
							this.getClass(), "ManifestXML_Path(" + strManifestFilePath + ")",
							DebugLog.ROW);
					
					//imsmanifest.xmlファイルの存在確認
					//戻り値：boolean
					//true:存在する
					//false:存在しない
					exists_flag = objManifestFile.exists();

					
				//if (methodType.equals("INSERT") && (exists_flag==false)){
				if (exists_flag==false){
				    //INSERTでmanifest.xmlがなかったらないもしない	
				}else{
/////////////////////////////////////////////////////////////////////////
//追加処理　END
/////////////////////////////////////////////////////////////////////////				    
				    // 教材構造定義データを取得
				    Document manifestDoc = null;
				    manifestDoc =
				        ScormManifestUtil.getManifestXmlDocument(
				                strTempMaterialPath,
				                strDirList[i]);
				    // 教材構造定義を取得できない場合は、無視
				    if (manifestDoc == null) {
				        continue;
				    }
				    // 教材データをリストに追加
				    // 教材ID

//					@20040624 MOD NTTR 教材IDをXML取得からCP格納フォルダ名に変更
//					String manfestMaterialID =
//					ScormManifestUtil.getMaterialID(manifestDoc);
				    String manfestMaterialID = strDirList[i];
//					MOD END
				    // 教材タイトル
				    String manfestMaterialTitle =
					ScormManifestUtil.getMaterialTitle(manifestDoc);

				    MaterialData materialData = new MaterialData();
				    materialData.setMaterialID(manfestMaterialID);
				    materialData.setTitle(manfestMaterialTitle);
				    materialList.add(materialData);

				    // 登録以外は１つ見つかれば、終了。
				    if (methodType.equals("INSERT") == false) {
				        break;
				    }
				}
			}
			// Vectorを教材データリスト型に変換
			materialArray = new MaterialData[materialList.size()];
			materialList.copyInto(materialArray);
		}
		catch (Exception e) {
			// 教材構造ロード失敗時
			DebugLog.write(this.getClass(), e.getMessage(), DebugLog.HIGHT);
			message = createSystemErrMessage(e.getMessage());
		}
		returnValue.add(message);
		returnValue.add(materialArray);

		// メソッド終了ログ
		DebugLog.write(
			this.getClass(),
			"TAIL getMaterialList(" +  params + ") return " + returnValue,
			DebugLog.ROW);
		return returnValue;
	}

	/**
	 * データを取得します。<br>
	 * データベースにアクセスし、パラメータに指定されたScorm LOデータを取得します。
	 * 詳細は、{@link ScormLoDataAccess#getLoData(Hashtable)}を参照してください。
	 *
	 * @param params パラメータ。
	 * @return {@link ScormLoDataAccess#getLoData(Hashtable)}より返却される値。
	 * @see ScormLoDataAccess#getLoData(Hashtable)
	 * @see jp.co.ntt.lms.lo.LoTop#getData(java.util.Hashtable)
	 */
	public Vector getData(Hashtable params) {
		// メソッド開始ログ
		DebugLog.write(
			this.getClass(), "HEAD getData(" +  params + ")",
			DebugLog.ROW);

		Vector returnValue = new Vector();
		MessageData message = null;
		Object body = null;
		try {
			ScormLoDataAccess dataAccess = new ScormLoDataAccess();
			body = dataAccess.getLoData(params);
		}
		catch (LOException e) {
			// メッセージデータオブジェクトが取得できない場合は
			// システムエラーメッセージオブジェクトを生成
			message = createSystemErrMessage(e.getMessage());
		}
		// 戻すオブジェクトを生成
		returnValue.add(message);
		returnValue.add(body);

		// メソッド終了ログ
		DebugLog.write(
			this.getClass(),
			"TAIL getData(" +  params + ") return " + returnValue,
			DebugLog.ROW);
		return returnValue;
	}

	/**
	 * SCORM LO個別ログを削除します。<br>
	 * データベースにアクセスし、パラメータに指定されたScorm LOデータを取得します。
	 *
	 * @param params パラメータ。
	 * @return MessageData１つを要素とするVector。成功した場合は要素の値はnull。
	 * @see jp.co.ntt.lms.lo.LoTop#deleteIndividualLog(Hashtable)
	 * @see MessageData
	 */
	public Vector deleteIndividualLog(Hashtable params) {
		// メソッド開始ログ
		DebugLog.write(
			getClass(), "HEAD deleteIndividualLog(" +  params + ")",
			DebugLog.ROW);

		Vector returnValue = new Vector();
		MessageData message = null;
		DataAccess dataAccess = new DataAccess();
		try {
			// パラメータの取得
			String userID = (String)params.get(LoPropertyDef.USER);
			String loID = (String)params.get(LoPropertyDef.LOID);
			// トランザクション開始
			dataAccess.trans();

			// Scorm_Attemptテーブルからログを削除
			ScormAttemptDataAccess.delete(dataAccess, userID, loID);
			// Scorm_Interactionテーブルからログを削除
			ScormInteractionDataAccess.delete(dataAccess, userID, loID);
			// Scorm_LearnerCommentテーブルからログを削除
			ScormLearnerCommentDataAccess.delete(dataAccess, userID, loID);
			// Scorm_LMSCommentテーブルからログを削除
			ScormLMSCommentDataAccess.delete(dataAccess, userID, loID);
			// Scorm_Objectiveテーブルからログを削除
			ScormObjectiveDataAccess.delete(dataAccess, userID, loID);
			// Scorm_Sessionテーブルからログを削除
			ScormSessionDataAccess.delete(dataAccess, userID, loID);

			//トランザクションコミット
			dataAccess.commit();
		}
		catch (Exception e) {
			// 例外が発生した場合はトランザクションをロールバック
			try {
				dataAccess.rollback();
			}
			catch (SQLException e1) {
				// メソッド開始ログ
				DebugLog.write( getClass(), e1, DebugLog.ROW);
			}
			message = createSystemErrMessage(e.getMessage());
		}

		returnValue.add(message);

		// メソッド終了ログ
		DebugLog.write( getClass(),
			"TAIL deleteIndividualLog(" +  params + ")"
				+ " return " + returnValue,
			DebugLog.ROW);

		return returnValue;
	}

	/**
	 * ScormLo個別ログ更新
	 *
	 * @param htbParam パラメータリスト
	 * @return Vector メッセージデータ
	 */
	public Vector changeTypeUpdateIndividualLog(Hashtable htbParam)
	{
		Vector vecRet     = new Vector();
		MessageData objMd = null;
		try {
			changeTypeUpdate( htbParam );
		}
		catch(LOException le)
		{
			// メッセージデータオブジェクトが取得できない場合は
			// システムエラーメッセージオブジェクトを生成
			objMd = createSystemErrMessage(le.getMessage());
		}
		catch(Exception e)
		{
			// メッセージデータオブジェクトが取得できない場合は
			// システムエラーメッセージオブジェクトを生成
			objMd = createSystemErrMessage(e.getMessage());
		}

		vecRet.add(objMd);
		return vecRet;
	}

	/**
	 * Scorm教材 個別ログテーブルへ更新処理を行います。
	 *
	 * @param htbParam
	 * @exception LOException LO独自例外
	 */
	public synchronized void changeTypeUpdate( Hashtable htbParam )
		throws LOException
	{
		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess();
		try {
			// トランザクションを開始する
			objDataAccess.trans(htbParam);

			changeTypeUpdateAction( htbParam, objDataAccess );

			// コミット処理
			objDataAccess.commit();
		}
		catch( SQLException e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			// データベースエラーを設定
			throw new LOException( e.getMessage() );
		}
	}

	/**
	 * Scorm教材 個別ログテーブルへの更新処理を行います。
	 *
	 * @param htbParam パラメータ
	 * @param objDataAccess
	 * @exception SQLException DBエラー
	 */
	private void changeTypeUpdateAction( Hashtable htbParam, DataAccess objDataAccess )
		throws SQLException
	{

		// 削除対象の取得
		String loID = (String)htbParam.get( LOID );
		String condition = (String)htbParam.get( CONDITION_KEY );

		// Scorm_Attemptテーブルの更新
		ScormAttemptDataAccess objAttempt = new ScormAttemptDataAccess();
		objAttempt.changeTypeUpdate( loID, condition, objDataAccess );

		// Scorm_Interactionテーブルの更新
		ScormInteractionDataAccess objInteraction = new ScormInteractionDataAccess();
		objInteraction.changeTypeUpdate( loID, condition, objDataAccess );

		// Scorm_LearnerCommentテーブルの更新
		ScormLearnerCommentDataAccess objComment = new ScormLearnerCommentDataAccess();
		objComment.changeTypeUpdate( loID, condition, objDataAccess );

		// Scorm_LMSCommentテーブルの更新
		ScormLMSCommentDataAccess objLMSComment = new ScormLMSCommentDataAccess();
		objLMSComment.changeTypeUpdate( loID, condition, objDataAccess );

		// Scorm_Objectiveテーブルの更新
		ScormObjectiveDataAccess objObjectives = new ScormObjectiveDataAccess();
		objObjectives.changeTypeUpdate( loID, condition, objDataAccess );

		// Scorm_Sessionテーブルの更新
		ScormSessionDataAccess objSession = new ScormSessionDataAccess();
		objSession.changeTypeUpdate( loID, condition, objDataAccess );
	}

	/**
	 * 教材構造定義ファイルの内容を取得します。<br>
	 *
	 * @param params パラメータ。
	 *                以下のデータが含まれていることを期待しています。<br>
	 * <table border="1">
	 * 	<tr>
	 * 		<th>キー</th>
	 * 		<th>値</th>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>&quot;MATID&quot;</td>
	 * 		<td>教材ID。METHODがINSERTの場合、不要。</td>
	 * 	</tr>
	 * </table>
	 * <br>
	 * @return ０番目の要素に処理メッセージ、
	 *          １番目に教材構造定義XML文字列を格納されたVector。
	 * @see jp.co.ntt.lms.lo.LoTop#getMaterialStructFile(Hashtable)
	 */
	public Vector getMaterialStructFile(Hashtable params) {
		// メソッド開始ログ
		DebugLog.write(
			this.getClass(),
			"HEAD getMaterialStructFile(" + params + ")",
			DebugLog.ROW);

		// このメソッドの戻り値
		Vector returnValue = new Vector();
		// メッセージ
		MessageData message = null;
		// 教材構造XML文字列
		String manifestXmlString = null;

		try {
			// 教材IDを取得する
			String materialID = (String) params.get("MATID");
			DebugLog.write(
				this.getClass(),
				"materialID =\"" + materialID + "\"",
				DebugLog.ROW);
			// 登録済みの教材の構造定義を確認します。
			ScormLoEnv env = new ScormLoEnv();
			String materialListPath = env.getMaterialPath();
			String[] strFileList =
				FileControl.getFileList(
					materialListPath,
					FileControl.DIR_LIST);
			boolean found = false;
			for (int i = 0; i < strFileList.length; i++) {
				if (strFileList[i].equals(materialID)) {
					found = true;
					break;
				}
			}
			// 見つからなかった場合、例外。
			if (found == false) {
				DebugLog.write(
					this.getClass(),
					"Manifest File[" + materialID + "] not Found.",
					DebugLog.ROW);
				throw new Exception();
			}
			// 教材構造を読み込み、文字列化
			manifestXmlString =
				ScormManifestUtil.getManifestXmlString(
					materialListPath, materialID, null);
		}
		catch (Exception e) {
			DebugLog.write(this.getClass(), e, DebugLog.HIGHT);
			// システムエラーメッセージオブジェクトを生成
			message = createSystemErrMessage(
						"教材構造ファイルの読み込みに失敗しました。");
			manifestXmlString = "";
		}
		// 戻り値に格納
		returnValue.add(message);
		returnValue.add(manifestXmlString);

		// メソッド終了ログ
		DebugLog.write(
			this.getClass(),
			"TAIL getMaterialStructFile(" + params + ") return " + returnValue,
			DebugLog.ROW);
		return returnValue;
	}

// 2004.09.14 M004 ADD start NTTR(N)
	/**
	 * 個別ログ(CSV)の取得を行います
	 *
	 * @param htbParam パラメータ
	 * @return Vector メッセージデータと個別ログ取得結果
	 */
	public Vector getIndividualLogCSV( Hashtable htbParam ) {

		Vector vecRet = new Vector();
		MessageData objMd = null;
		Object objRet = null;

		try {
			ScormLoDataAccess objDataAccess = new ScormLoDataAccess();
			objRet = objDataAccess.selectCSV( htbParam );
		} catch ( Exception le ) {
			// メッセージデータオブジェクトが取得できない場合は
			// システムエラーメッセージオブジェクトを生成
			objMd = createSystemErrMessage( le.getMessage() );
		}
		vecRet.add( objMd );
		vecRet.add( objRet );
		return vecRet;
	}

	/**
	 * 個別ログの取得を行います
	 *
	 * @param htbParam パラメータ
	 * @return Vector メッセージデータと個別ログ取得結果
	 */
	public Vector getIndividualLog( Hashtable htbParam ) {

		Vector vecRet = new Vector();
		MessageData objMd = null;
		Object objRet = null;

		try {
			ScormLoDataAccess objDataAccess = new ScormLoDataAccess();
			objRet = objDataAccess.select( htbParam );
		} catch ( LOException le ) {
			// メッセージデータオブジェクトが取得できない場合は
			// システムエラーメッセージオブジェクトを生成
			objMd = createSystemErrMessage( le.getMessage() );
		}
		vecRet.add( objMd );
		vecRet.add( objRet );
		return vecRet;
	}
// 2004.09.14 M004 ADD end
}