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

//
//	スマートフォースログファイル操作クラス
//			変更履歴
//				2004.01.08	新規作成	五木田 泰史
//
package jp.co.ntt.lms.lo.SmartForce;

import jp.co.ntt.lms.lo.*;

// Java API
import java.util.Vector;
import java.util.Hashtable;

import org.apache.commons.lang.StringEscapeUtils;
// XMS API
import jp.co.ntt.lms.xmo.util.DBAccess;
import jp.co.ntt.lms.xmo.util.DebugLog;

public class SmartForceLoLogControl
	implements SmartForceLoPropertyDef
{

	//////////////////////////////////////////////////////////////////
	// メンバ変数
	//////////////////////////////////////////////////////////////////
	DBAccess mobjDba;
	
	//////////////////////////////////////////////////////////////////
	// メンバ関数
	//////////////////////////////////////////////////////////////////
	
	/**
	 * コンストラクタ
	 **/
	public SmartForceLoLogControl()
	{
		;
	}
	
	/**
	 * ステータスログ設定
	 *
	 * 処理内容：ステータスログクラスに
	 *           データを設定する。
	 * @param htbParam ユーザID等のハッシュ
	 * @return LoLogRecord[] ステータスログクラス
	 *
	 **/
	public LoLogRecord getLoLog(Hashtable htbParam)
			throws LOException
	{
		// XMSログテーブルデータ
		String strCourseID        = "";		// 教材ID
		String strBlockID         = "";		// ブロックID
		String strAuID            = "";		// AUID
		String strStudyStartDate  = "";		// 開始日
		String strResidanceTime   = "";		// 累積滞在時間
		String strPassday         = "";		// 合格日
		String strStudyEndDate    = "";		// 修了日
		String strHighScore       = "";		// 最高点
		String strLowScore        = "";		// 最低点
		String strExecisePoint    = "";		// 得点
		String strUserID          = "";		// 人ID
		String strLoID            = "";		// LOID
		String strCourseCount     = "";		// 学習回数
		
		// SmartForceテーブルデータ
		String strStudentID       = "";		// 学習者ID
		String strCourseVersion   = "";		// 教材バージョン
		String strDateAccessed    = "";		// 教材接続日
		String strDateTest        = "";		// テスト日
		String strResultTest      = "";		// テスト記録
		String strMinResultTest   = "";		// 最低テスト記録
		String strMaxResultTest   = "";		// 最高テスト記録
		
		int i                     = 0;
		int j                     = 0;
		int intUnitCount          = 0;		// ユニット数
		
		LoLogRecord objRet      = null;	// 戻り値
		
		try
		{
			// ユーザID取得
			strUserID        = (String)htbParam.get(USER);
			// 教材ID取得
			strCourseID      = (String)htbParam.get(COURSECODE);
			// 学習回数取得
			strCourseCount   = (String)htbParam.get(STUDYCOUNT);
			// LoID取得
			strLoID          = (String)htbParam.get(LOID);
			
			// DBAccessクラス生成
			mobjDba          = new DBAccess();
			
			// DBAccessプロパティ設定処理
			SmartForceLoEnv objEnv = new SmartForceLoEnv();
			mobjDba.setDriver(objEnv.getDBDriver());
			mobjDba.setConStr(objEnv.getDBConStr());
			mobjDba.setUser(objEnv.getDBUser());
			mobjDba.setPass(objEnv.getDBPass());
			
			// DB結果リスト生成(VectorのString[]リスト)
			Vector vecList   = new Vector();
			
			//////////////////////////////////////////////////////////
			// 学習情報リスト取得処理(1件のみ)
			//////////////////////////////////////////////////////////
			// 学習者情報レコードリスト取得処理(キー = ユーザID)
			vecList = getStudentInfo(strUserID);
			if(vecList.size() > 0)
			{
				// 学習者情報指定レコード取得
				String[] strList = new String[vecList.size()];
				strList          = (String[])vecList.get(0);
				// 学習者ID取得
				strStudentID     = strList[0];
			}
			// DB結果リスト初期化
			vecList.removeAllElements();
			// DBAccessクラスメンバ変数初期化
			mobjDba.clearProperty();
			
			//////////////////////////////////////////////////////////
			// 教材情報リスト取得処理(1件のみ)
			//////////////////////////////////////////////////////////
			vecList = getCourseInfo(strCourseID);
			if(vecList.size() > 0)
			{
				String[] strList = new String[vecList.size()];
				strList          = (String[])vecList.get(0);
				strCourseVersion = strList[1];									// 教材バージョン取得
			}
			vecList.removeAllElements();
			mobjDba.clearProperty();
			
			//////////////////////////////////////////////////////////
			// 教材履歴情報リスト取得処理(1件のみ)
			//////////////////////////////////////////////////////////
			vecList = getCourseResultInfo(strCourseID,
											strCourseVersion,
											strStudentID);
			int intResultCount = 0;
			int intMaxResultCount = 0;
			// 教材接続回数分繰り返す
			for(i = 0; i < vecList.size(); i++)
			{
				String[] strList = (String[])vecList.get(i);					// 履歴データ取得
				String strResultCount = strList[3];								// 学習回数取得
				if(strResultCount != null &&
					 !strResultCount.equals(""))
				{
					intResultCount = Integer.parseInt(strResultCount);
					if(i == 0 || intMaxResultCount < intResultCount)
					{
						intMaxResultCount = intResultCount;
						if(strList[5] != null && strList[5].equals("1"))		// 学習終了ならば
						{
							strDateAccessed = strList[4];						// 教材接続日取得
						}
						else
						{
							strDateAccessed = null;								// 教材接続日初期化
						}
					}
				}

			}
			vecList.removeAllElements();
			mobjDba.clearProperty();
			
			//////////////////////////////////////////////////////////
			// 教材テスト情報取得処理(テスト回数分)
			//////////////////////////////////////////////////////////
			vecList = getCourseTestInfo(strCourseID,
										strCourseVersion,
										strStudentID);
			int intMinResultTest = 0;											// 最低点
			int intMaxResultTest = 0;											// 最高点
			int intNowResultTest = 0;											// 得点
			int intTestCount = 0;
			int intMaxTestCount = 0;
			String strMaxTestCourseCount = String.valueOf(intMaxResultCount);
			// テスト回数分繰り返す
			for(i = 0; i < vecList.size(); i++)
			{
				String[] strList = (String[])vecList.get(i);					// テストデータ取得
				String strScore = strList[5];									// テスト記録取得
				String strTestCourseCount = strList[7];							// 学習回数取得
				if(strScore != null)
				{
					intNowResultTest = Integer.parseInt(strScore);				// 得点設定
					if(intNowResultTest < intMinResultTest || i == 0)
					{
						intMinResultTest = intNowResultTest;					// 最低点設定
					}
					if(intNowResultTest > intMaxResultTest || i == 0)			// 最高点設定
					{
						intMaxResultTest = intNowResultTest;
					}
				}
				String strTestCount = strList[3];								// テスト回数取得
				if(strTestCount != null && !strTestCount.equals("")
					&& strMaxTestCourseCount.equals(strTestCourseCount))
				{
					intTestCount = Integer.parseInt(strTestCount);
					if(i == 0 || intMaxTestCount < intTestCount)
					{
						intMaxTestCount = intTestCount;
						if(strList[6] != null && strList[6].equals("1"))		// 学習終了ならば
						{
							strDateTest = strList[4];							// 教材接続日取得
						}
						else
						{
							strDateTest = null;									// 教材接続日初期化
						}
					}
				}

			}
			strResultTest    = String.valueOf(intNowResultTest);				// 得点取得
			strMinResultTest = String.valueOf(intMinResultTest);				// 最低点取得
			strMaxResultTest = String.valueOf(intMaxResultTest);				// 最高点取得
			vecList.removeAllElements();
			mobjDba.clearProperty();
			
			// ログ変換処理(共通教材レコードは必ず１件)
			objRet = new LoLogRecord();
			if(strDateTest != null && strDateTest.equals(""))
			{
				// 指定学習回数のテストが不合格ならば、NULLを設定
				strDateTest = null;
			}

			objRet.setPassday(strDateTest);
			objRet.setStudyEndDate(strDateAccessed);
			objRet.setExecisePoint(strResultTest);
			objRet.setHighScore(strMaxResultTest);
			objRet.setLowScore(strMinResultTest);
			objRet.setUserID(strUserID);
			objRet.setLoID(strLoID);
			mobjDba.commit();
		}
		catch(LOException le)
		{
			DebugLog.write( this.getClass(), le.getMessage(), DebugLog.HIGHT );
			le.printStackTrace();
			try
			{
				if(mobjDba != null)
				{
					mobjDba.rollback();
				}
			}
			catch(Exception ex)
			{
				throw new LOException("ロールバックに失敗しました1");
			}
			throw le;
		}
		catch(Exception ex)
		{
			DebugLog.write( this.getClass(), ex.getMessage(), DebugLog.HIGHT );
			ex.printStackTrace();
			try
			{
				if(mobjDba != null)
				{
					mobjDba.rollback();
				}
			}
			catch(Exception e)
			{
				throw new LOException("ロールバックに失敗しました2");
			}
			throw new LOException("getLoLogにて例外発生");
		}

		return objRet;
	}

	/**
	 * 学習者情報レコードリスト取得処理
	 * <PRE>
	 * 処理内容：学習者情報テーブルの内容を取得する。
	 *           ユーザIDから学習者情報レコードを取得する。
	 * </PRE>
	 * @param String ユーザID
	 * @return Vector 学習者情報レコードリスト
	 **/
	private Vector getStudentInfo(String strUserID)
			throws LOException
	{
		// 戻り値初期化
		Vector vecRet       = new Vector();
		try
		{
			// Select, Update, Insert, Deleteを設定
			mobjDba.setCommand(DBAccess.CMD_SELECT);
			// 項目名("*"等)を設定
			mobjDba.setItem(DBAccess.ITEM_ALL);
			// テーブル名を設定
			mobjDba.setTableName("student_info");
			// Where句を設定
			StringBuffer strBuf = new StringBuffer();
			strBuf.append("LoginName='");
			strBuf.append(StringEscapeUtils.escapeSql(strUserID));
			strBuf.append("'");
			mobjDba.setWhere(strBuf.toString());
			DebugLog.write( this.getClass(), "学習情報テーブルSQL : " + strBuf.toString(), DebugLog.ROW );
			// Execute実行
			vecRet = mobjDba.execute();
		}
		catch(Exception ex)
		{
			DebugLog.write( this.getClass(), "学習情報テーブルからデータ取得失敗SQL", DebugLog.HIGHT );
			throw new LOException("学習情報テーブルからデータ取得失敗");
		}
		return vecRet;
	}
	
	/**
	 * 教材情報レコードリスト取得処理
	 * <PRE>
	 * 処理内容：教材情報テーブルの内容を取得する。
	 *           教材IDから教材情報を取得する。
	 * </PRE>
	 * @param String 教材ID
	 * @return Vector 教材情報データリスト
	 **/
	private Vector getCourseInfo(String strCourseID)
			throws LOException
	{
		// 戻り値初期化
		Vector vecRet       = new Vector();

		try
		{
			// Select, Update, Insert, Deleteを設定
			mobjDba.setCommand(DBAccess.CMD_SELECT);
			// 項目名("*"等)を設定
			mobjDba.setItem(DBAccess.ITEM_ALL);
			// テーブル名を設定
			mobjDba.setTableName("course_info");
			// Where句を設定
			StringBuffer strBuf = new StringBuffer();
			strBuf.append("CourseCode='");
			strBuf.append(StringEscapeUtils.escapeSql(strCourseID));
			strBuf.append("'");
			mobjDba.setWhere(strBuf.toString());
			DebugLog.write( this.getClass(), "教材情報テーブルSQL : " + strBuf.toString(), DebugLog.ROW );
			// Execute実行
			vecRet = mobjDba.execute();
		}
		catch(Exception ex)
		{
			DebugLog.write( this.getClass(), "教材情報テーブルからデータ取得失敗", DebugLog.HIGHT );
			throw new LOException("教材情報テーブルからデータ取得失敗");
		}

		return vecRet;
	}

	/**
	 * 教材履歴情報レコードリスト取得処理
	 * <PRE>
	 * 処理内容：教材履歴情報テーブルの内容を取得する。
	 *           教材ID、教材バージョン、学習者ID、学習回数
	 *           から教材履歴情報レコードを取得する。
	 * </PRE>
	 * @param String 教材ID
	 * @param String 教材バージョン
	 * @param String 学習者ID
	 * @return Vector 教材履歴情報レコードリスト
	 **/
	private Vector getCourseResultInfo(String strCourseID,
										String strCourseVersion,
										String strStudentID)
			throws LOException
	{
		// 戻り値初期化
		Vector vecRet       = new Vector();

		try
		{
			// Select, Update, Insert, Deleteを設定
			mobjDba.setCommand(DBAccess.CMD_SELECT);
			// 項目名("*"等)を設定
			mobjDba.setItem(DBAccess.ITEM_ALL);
			// テーブル名を設定
			mobjDba.setTableName("course_result");
			// Where句を設定
			StringBuffer strBuf = new StringBuffer();
			strBuf.append("CourseCode='");
			strBuf.append(StringEscapeUtils.escapeSql(strCourseID));
			strBuf.append("'");
			strBuf.append(" AND ");
			strBuf.append("CourseVersion='");
			strBuf.append(StringEscapeUtils.escapeSql(strCourseVersion));
			strBuf.append("'");
			strBuf.append(" AND ");
			strBuf.append("StudentID='");
			strBuf.append(StringEscapeUtils.escapeSql(strStudentID));
			strBuf.append("'");
			mobjDba.setWhere(strBuf.toString());
			DebugLog.write( this.getClass(), "教材履歴情報テーブルSQL : " + strBuf.toString(), DebugLog.ROW );
			// Execute実行
			vecRet = mobjDba.execute();
		}
		catch(Exception ex)
		{
			DebugLog.write( this.getClass(), "教材履歴情報テーブルからデータ取得失敗", DebugLog.HIGHT );
			throw new LOException("教材履歴情報テーブルからデータ取得失敗");
		}
		return vecRet;
	}
	
	/**
	 * 教材テスト情報レコードリスト取得処理
	 * <PRE>
	 * 処理内容：教材テスト情報テーブルの内容を取得する。
	 *           教材ID、教材バージョン、学習者ID、学習回数
	 *           から教材テスト情報レコードを取得する。
	 * </PRE>
	 * @param String 教材ID
	 * @param String 教材バージョン
	 * @param String 学習者ID
	 * @return Vector 教材テスト情報レコードリスト
	 **/
	private Vector getCourseTestInfo(String strCourseID,
										String strCourseVersion,
										String strStudentID)
			throws LOException
	{
		// 戻り値初期化
		Vector vecRet       = new Vector();
		try
		{
			// Select, Update, Insert, Deleteを設定
			mobjDba.setCommand(DBAccess.CMD_SELECT);
			// 項目名("*"等)を設定
			mobjDba.setItem(DBAccess.ITEM_ALL);
			// テーブル名を設定
			mobjDba.setTableName("course_test");
			// Where句を設定
			StringBuffer strBuf = new StringBuffer();
			strBuf.append("CourseCode='");
			strBuf.append(StringEscapeUtils.escapeSql(strCourseID));
			strBuf.append("'");
			strBuf.append(" AND ");
			strBuf.append("CourseVersion='");
			strBuf.append(StringEscapeUtils.escapeSql(strCourseVersion));
			strBuf.append("'");
			strBuf.append(" AND ");
			strBuf.append("StudentID='");
			strBuf.append(StringEscapeUtils.escapeSql(strStudentID));
			strBuf.append("'");
			mobjDba.setWhere(strBuf.toString());
			DebugLog.write( this.getClass(), "教材テスト情報テーブルSQL : " + strBuf.toString(), DebugLog.ROW );
			// Execute実行
			vecRet = mobjDba.execute();
		}
		catch(Exception ex)
		{
			DebugLog.write( this.getClass(), "教材テスト情報テーブルからデータ取得失敗", DebugLog.HIGHT );
			throw new LOException("教材テスト情報テーブルからデータ取得失敗");
		}
		return vecRet;
	}
}
