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

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

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

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.Vector;

import jp.co.ntt.lms.lo.LOException;
import jp.co.ntt.lms.lo.LoDataAccess;
import jp.co.ntt.lms.lo.LoLogEnvironment;
import jp.co.ntt.lms.lo.LoPropertyDef;
import jp.co.ntt.lms.lo.util.IndividualLogSQLMaker;
import jp.co.ntt.lms.xmo.DataAccess;
import jp.co.ntt.lms.xmo.MessageData;
import jp.co.ntt.lms.xmo.Lo.lom.LomDataAccess;
import jp.co.ntt.lms.xmo.util.ChangeEncode;
import jp.co.ntt.lms.xmo.util.DebugLog;

/**
 * SCORM LO 教材 個別テーブル(SCORMLOテーブル)へのアクセスクラス。<BR>
 * @author T.Nishiki
 */
// 2004.09.14 M004 MOD start NTTR(N)
public class ScormLoDataAccess extends LoDataAccess implements LoPropertyDef {
// 2004.09.14 M004 MOD end
	/**
	 * 検索条件式を表すハッシュキー。
	 */
	public static final String CONDITION_KEY = "condition_key";

	/**
	 * テーブル名称。
	 */
	public static final String TABLE_NAME = "SCORMLO";

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

// 2004.09.14 M004 ADD start NTTR(N)

	/**
	 * Scorm個別テーブルの検索処理を行います
	 *
	 * @param htbParam 検索データ
	 * @return
	 * @exception LOException LO独自例外
	 */
	public synchronized Vector select( Hashtable htbParam ) throws LOException {

		Vector vecRet = new Vector();
		DataAccess objDataAccess = new DataAccess();

		try {
			// トランザクションの開始
			objDataAccess.trans();
			// クエリーIDの取得
			String strQueryID = ( String ) htbParam.get( LoPropertyDef.QUERY_ID );
			if ( strQueryID == null ) {
				throw new LOException( "クエリーIDを指定してください。" );
			}
			// クエリー条件の取得
			Vector vecQueryCondition = ( Vector ) htbParam.get( LoPropertyDef.LOG_CONDITION );
			if ( vecQueryCondition == null ) {
				// 条件が指定されていない場合、空のVectorを作成します。
				vecQueryCondition = new Vector();
			}
			LoLogEnvironment objEnv = LoLogEnvironment.getInstance();
			String strQuery = objEnv.getQueryString( strQueryID );
			PreparedStatement objStatement = objDataAccess.prepareStatement( strQuery );
			// 検索条件の設定
			for ( int i = 0; i < vecQueryCondition.size(); i++ ) {
				objStatement.setString( i + 1, ( String ) vecQueryCondition.get( i ) );
			}
			// クエリーの実行
			ResultSet rs = objStatement.executeQuery();
			ResultSetMetaData meta = rs.getMetaData();
			int intColCount = meta.getColumnCount();
			Vector vecResult = new Vector();
			while ( rs.next() ) {
				String[] strResult = new String[intColCount];
				for ( int i = 0; i < intColCount; i++ ) {
					strResult[i] = ChangeEncode.setChar( rs.getString( i + 1 ) );
				}
				vecResult.add( strResult );
			}

			String[][] strResult = new String[vecResult.size()][intColCount];
			vecResult.copyInto( strResult );
			// コミット
			objDataAccess.commit();
			// 結果を格納
			vecRet.add( strResult );

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

	/**
	 * Scorm個別テーブルの検索処理を行います
	 *
	 * @param htbParam 検索データ
	 * @return
	 * @exception LOException LO独自例外
	 */
	public synchronized Vector selectCSV( Hashtable htbParam )
		throws LOException {

		Vector vecRet = new Vector();
		DataAccess objDataAccess = new DataAccess();

		try {
			// トランザクションの開始
			objDataAccess.trans();
			// クエリーIDの取得
			String strQueryID = ( String ) htbParam.get( QUERY_ID );
			if ( strQueryID == null ) {
				throw new LOException( "クエリーIDを指定してください。" );
			}
			// クエリー条件の取得
			Vector vecQueryCondition = ( Vector ) htbParam.get( LOG_CONDITION );
			if ( vecQueryCondition == null ) {
				// 条件が指定されていない場合、空のVectorを作成します。
				vecQueryCondition = new Vector();
			}
			LoLogEnvironment objEnv = LoLogEnvironment.getInstance();
			// クエリー
			String strQuery = objEnv.getQueryString( strQueryID );
			// ユーザリスト
			String[] strUserID = ( String[] ) htbParam.get( USERID_LIST );
			// UIDリスト
			String[] strUID = ( String[] ) htbParam.get( UID_LIST );
			// IN句に用いるカラム名(ユーザリスト)
			String inGroupColumn = ( String ) htbParam.get( IN_COLUMN_USER_LIST );
			// IN句に用いるカラム名(UIDリスト)
			String inUIDColumn = ( String ) htbParam.get( IN_COLUMN_UID_LIST );
			IndividualLogSQLMaker objSqlMaker 
				= new IndividualLogSQLMaker( strQuery, strUserID, strUID, inGroupColumn, inUIDColumn );
			strQuery = objSqlMaker.makeQuery();

			// クエリーの実行
			PreparedStatement objStatement = objDataAccess.prepareStatement( strQuery );

			// 検索条件の設定
			for ( int i = 0; i < vecQueryCondition.size(); i++ ) {
				objStatement.setString( i + 1, ( String ) vecQueryCondition.get( i ) );
			}

			ResultSet rs = objStatement.executeQuery();
			ResultSetMetaData meta = rs.getMetaData();
			int intColCount = meta.getColumnCount();
			Vector vecResult = new Vector();
			while ( rs.next() ) {
				String[] strResult = new String[intColCount];
				for ( int i = 0; i < intColCount; i++ ) {
					strResult[i] = ChangeEncode.setChar( rs.getString( i + 1 ) );
				}
				vecResult.add( strResult );
			}
			String[][] strResult = new String[vecResult.size()][intColCount];
			vecResult.copyInto( strResult );
			// コミット
			objDataAccess.commit();
			// 結果を格納
			vecRet.add( strResult );

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

// 2004.09.14 M004 ADD end

	/**
	 * SCORM LO 教材個別テーブルにデータを挿入します。<br>
	 * このメソッド内でトランザクションの開始ならびに終了を実行しています。<br>
	 *
	 * @param params パラメータ。<br>
	 * 以下の値が設定されていることを期待しています。<br>
	 * <table border="1">
	 * 	<tr>
	 * 		<th>キー</th>
	 * 		<th>値</th>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LOID</td>
	 * 		<td>挿入するレコードのLOID</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LoPropertyDef.MATERIALID</td>
	 * 		<td>挿入するレコードの教材ID</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LoPropertyDef.WINHEIGHT</td>
	 * 		<td>挿入するレコードのウィンドウサイズ(縦)</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LoPropertyDef.WINWIDTH</td>
	 * 		<td>挿入するレコードのウィンドウサイズ(横)</td>
	 * 	</tr>
	 * </table><br>
	 * @throws LOException データ挿入でエラーが発生した場合。
	 */
	public synchronized void insert(Hashtable params) throws LOException {
		// メソッド開始ログ
		DebugLog.write(
			this.getClass(),
			"HEAD insert(" + params + ")",
			DebugLog.ROW);

		// データアクセスクラス
		DataAccess dataAccess = null;

		try {
			dataAccess = new DataAccess(TABLE_NAME);
			// =================================================================
			// トランザクションを開始
			dataAccess.trans(params);
			// =================================================================
			// 教材IDの存在チェックを行います
			if (dataAccess.isExit(params, LoPropertyDef.MATERIALID)) {
				MessageData message =
					new MessageData(
						"教材IDが重複しています。",
						MessageData.WAR_TYPE);
				throw new LOException(message);
			}
			// 挿入処理
			insertAction(params, dataAccess);
// ADD 2005/02/23 START SUGAWARA [scorm取り込み]
			LomDataAccess lomAccess = new LomDataAccess();
			lomAccess.enrollEntryData(dataAccess, params);
// ADD 2005/02/23 END SUGAWARA [scorm取り込み]

			// コミット処理
			dataAccess.commit();
		}
		catch (LOException e) {
			DebugLog.write(this.getClass(), e, DebugLog.HIGHT);
			// ロールバック
			try {
				dataAccess.rollback();
			}
			catch (Exception ex) {
			}
			throw e;
		}
		catch (Exception e) {
			DebugLog.write(this.getClass(), e, DebugLog.HIGHT);
			// ロールバック
			try {
				dataAccess.rollback();
			}
			catch (Exception ex) {
			}
			throw new LOException(e.getMessage());
		}

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

	/**
	 * SCORM LO 教材個別テーブルのレコードを更新します。
	 * このメソッド内でトランザクションの開始ならびに終了を実行しています。
	 *
	 * @param params パラメータ。<br>
	 * 以下の値が設定されていることを期待しています。<br>
	 * <table border="1">
	 * 	<tr>
	 * 		<th>キー</th>
	 * 		<th>値</th>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LOID</td>
	 * 		<td>更新するレコードのLOID</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LoPropertyDef.MATERIALID</td>
	 * 		<td>更新するレコードの教材ID</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LoPropertyDef.WINHEIGHT</td>
	 * 		<td>更新するレコードのウィンドウサイズ(縦)</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LoPropertyDef.WINWIDTH</td>
	 * 		<td>更新するレコードのウィンドウサイズ(横)</td>
	 * 	</tr>
	 * </table><br>
	 * @throws LOException データ更新でエラーが発生した場合。
	 */
	public synchronized void update(Hashtable params) throws LOException {
		// メソッド開始ログ
		DebugLog.write(
			this.getClass(),
			"HEAD update(" + params + ")",
			DebugLog.ROW);

		// データアクセスクラス
		DataAccess dataAccess = null;

		try {
			dataAccess = new DataAccess(TABLE_NAME);
			// トランザクションを開始
			dataAccess.trans(params);
			// 更新処理
			updateAction(params, dataAccess);
			// コミット
			dataAccess.commit();
		}
		catch (SQLException e) {
			DebugLog.write(this.getClass(), e, DebugLog.HIGHT);
			// ロールバック
			try {
				dataAccess.rollback();
			}
			catch (Exception ex) {
			}
			throw new LOException(e.getMessage());
		}

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

	/**
	 * SCORM LO 教材個別テーブルからレコードを削除します。<br>
	 * このメソッド内でトランザクションの開始ならびに終了を実行しています。<br>
	 *
	 * @param params パラメータ。<br>
	 * 以下の値が設定されていることを期待しています。<br>
	 * <table border="1">
	 * 	<tr>
	 * 		<th>キー</th>
	 * 		<th>値</th>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>CONDITION_KEY</td>
	 * 		<td>削除するレコードの条件となるWHERE句。</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LoPropertyDef#LOID</td>
	 * 		<td>
	 * 			削除するレコードのLOID。
	 * 			CONDITION_KEYが設定されていない場合に使用する。
	 * 		</td>
	 * 	</tr>
	 * </table><br>
	 * @throws LOException データ削除でエラーが発生した場合。
	 */
	public synchronized void delete(Hashtable params) throws LOException {
		// メソッド開始ログ
		DebugLog.write(
			this.getClass(),
			"HEAD delete(" + params + ")",
			DebugLog.ROW);

		// データアクセスクラス
		DataAccess dataAccess = null;

		try {
			dataAccess = new DataAccess(TABLE_NAME);
			// トランザクションを開始
			dataAccess.trans(params);
			// 削除処理
			deleteAction(params, dataAccess);
			// コミット処理
			dataAccess.commit();
		}
		catch (Exception e) {
			DebugLog.write(this.getClass(), e, DebugLog.HIGHT);
			// ロールバック
			try {
				dataAccess.rollback();
			}
			catch (Exception ex) {
			}
			throw new LOException(e.getMessage());
		}

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

	/**
	 * SCORM LO個別テーブルからレコードを取得します。<br>
	 *
	 * @param params パラメータ。<br>
	 * 以下の値が設定されていることを期待しています。<br>
	 * <table border="1">
	 * 	<tr>
	 * 		<th>キー</th>
	 * 		<th>値</th>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>CONDITION_KEY</td>
	 * 		<td>検索するレコードの条件となるWHERE句。</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LoPropertyDef#LOID</td>
	 * 		<td>
	 * 			検索するレコードのLOID。
	 * 			CONDITION_KEYが設定されていない場合に使用する。
	 * 		</td>
	 * 	</tr>
	 * </table><br>
	 * @return 検索条件に該当するLOデータの配列。
	 *          該当するLOデータがない場合、要素数０の配列を戻します。
	 * @throws LOException データ検索でエラーが発生した場合。
	 */
	public ScormLoData[] getLoData(Hashtable params) throws LOException {
		// メソッド開始ログ
		DebugLog.write(
			this.getClass(),
			"HEAD getLoData(" + params + ")",
			DebugLog.ROW);

		// このメソッドの戻り値。
		ScormLoData[] records = null;
		// データアクセスクラス
		DataAccess dataAccess = null;
		try {
			dataAccess = new DataAccess(TABLE_NAME);
			// トランザクション開始
			dataAccess.trans(params);
			records = getLoData(params, dataAccess);
			// =================================================================
			// コミット処理
			dataAccess.commit();
		}
		catch (SQLException e) {
			DebugLog.write(ScormLoDataAccess.class, e, DebugLog.HIGHT);
			// ロールバック
			try {
				dataAccess.rollback();
			}
			catch (Exception ex) {
			}
			throw new LOException(e.getMessage());
		}
		catch (LOException e) {
			DebugLog.write(ScormLoDataAccess.class, e, DebugLog.HIGHT);
			// ロールバック
			try {
				dataAccess.rollback();
			}
			catch (Exception ex) {
			}
			throw e;
		}

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

		return records;
	}


	/**
	 * SCORM LO個別テーブルからレコードを取得します。<br>
	 * @param params パラメータ。<br>
	 * 以下の値が設定されていることを期待しています。<br>
	 * <table border="1">
	 * 	<tr>
	 * 		<th>キー</th>
	 * 		<th>値</th>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>CONDITION_KEY</td>
	 * 		<td>検索するレコードの条件となるWHERE句。</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LoPropertyDef#LOID</td>
	 * 		<td>
	 * 			検索するレコードのLOID。
	 * 			CONDITION_KEYが設定されていない場合に使用する。
	 * 		</td>
	 * 	</tr>
	 * </table><br>
	 * @param dataAccess データアクセスクラス。
	 *                    このメソッド内ではトランザクションを操作していません。
	 * @return 検索条件に該当するLOデータの配列。
	 *          該当するLOデータがない場合、要素数０の配列を戻します。
	 * @throws LOException データ検索でエラーが発生した場合。
	 */
	public static ScormLoData[] getLoData(
			Hashtable params, DataAccess dataAccess) throws LOException {
		// メソッド開始ログ
		DebugLog.write(
			ScormLoDataAccess.class,
			"HEAD getLoData(" + params
			+ "," + "DataAccess[" + dataAccess + "])",
			DebugLog.ROW);

		ScormLoData[] records = null;

		// =====================================================================
		// クエリー文の組み立て
		// 検索条件文の取得
		String condition = (String) params.get(CONDITION_KEY);
		// 検索条件文が取得されていない場合
		if (condition == null) {
			String loID = (String) params.get(LoPropertyDef.LOID);
			if (loID != null) {
				condition =
					" WHERE " + LoPropertyDef.LOID + "='" + loID + "'";
			}
			else {
				condition = "";
			}
		}
		String strSQL =
			"SELECT * FROM " + TABLE_NAME + condition;

		// 結果セット
		ResultSet rs = null;
		// 処理結果フラグ
		boolean success = false;
		try {
			// クエリー発行
			rs = dataAccess.executeQuery(strSQL);
			// =================================================================
			// データの取得
			Vector recordList = new Vector();
			while (rs.next()) {
				ScormLoData record = new ScormLoData();
				// セッションレコードにコピー
				record.setLoID(
					ChangeEncode.setChar(
						rs.getString(LoPropertyDef.LOID)));
				record.setMaterialID(
					ChangeEncode.setChar(
						rs.getString(LoPropertyDef.MATERIALID)));
				record.setWinHeight(
					ChangeEncode.setChar(
						rs.getString(LoPropertyDef.WINHEIGHT)));
				record.setWinWidth(
					ChangeEncode.setChar(
						rs.getString(LoPropertyDef.WINWIDTH)));

				// 結果格納用Vectorに格納
				recordList.add(record);
			}
			// =================================================================
			// 配列に変換
			records = new ScormLoData[recordList.size()];
			recordList.copyInto(records);
			// tryブロックの最後まで処理がおわれば、成功扱い。
			success = true;
		}
		catch (SQLException e) {
			throw new LOException(e.getMessage());
		}
		finally {
			// 結果セットを閉じる。
			// 処理フラグが成功となっている場合のみ、呼び出し元にスロー
			if (rs != null) {
				try {
					rs.close();
				}
				catch (Exception e) {
					if (success) {
						DebugLog.write(
							ScormLoDataAccess.class, e, DebugLog.HIGHT);
						throw new LOException(e.getMessage());
					}
				}

			}
		}

		// メソッド終了ログ
		DebugLog.write(
			ScormLoDataAccess.class,
			"TAIL getLoData("
				+ params + "," + "DataAccess[" + dataAccess + "])"
			+ " return " + records,
			DebugLog.ROW);

		return records;
	}

	/**
	 * SCORM LO 教材個別テーブルにレコードを挿入します。<br>
	 * このメソッド内ではトランザクションの開始または終了処理は行いません。
	 *
	 * @param params パラメータ。<br>
	 * 以下の値が設定されていることを期待しています。<br>
	 * <table border="1">
	 * 	<tr>
	 * 		<th>キー</th>
	 * 		<th>値</th>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>PropertyDef.LOID</td>
	 * 		<td>挿入するレコードのLOID</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LoPropertyDef.MATERIALID</td>
	 * 		<td>挿入するレコードの教材ID</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>PropertyDef.WINHEIGHT</td>
	 * 		<td>挿入するレコードのウィンドウサイズ(縦)</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LoPropertyDef.WINWIDTH</td>
	 * 		<td>挿入するレコードのウィンドウサイズ(横)</td>
	 * 	</tr>
	 * </table><br>
	 * @param dataAccess データアクセス・オブジェクト。
	 * @throws SQLException データ挿入でエラーが発生した場合。
	 */
	private void insertAction(Hashtable params, DataAccess dataAccess)
		throws SQLException {

		// ハッシュから必要なデータのみ抽出
		Hashtable htbData = extractValues(params);
		// 登録用SQLを生成します
		String query = dataAccess.getInsertSQL(htbData);

		// 登録処理を実行
		dataAccess.execute(query);
	}

	/**
	 * SCORM LO 教材個別テーブルからレコードを削除します。<br>
	 * このメソッド内ではトランザクションの開始または終了処理は行いません。
	 *
	 * @param params パラメータ。<br>
	 * 以下の値が設定されていることを期待しています。<br>
	 * <table border="1">
	 * 	<tr>
	 * 		<th>キー</th>
	 * 		<th>値</th>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>CONDITION_KEY</td>
	 * 		<td>削除するレコードの条件となるWHERE句。</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LOID</td>
	 * 		<td>
	 * 			削除するレコードのLOID。
	 * 			CONDITION_KEYが設定されていない場合に使用する。
	 * 		</td>
	 * 	</tr>
	 * </table><br>
	 * @param dataAccess データアクセス・オブジェクト。
	 * @throws SQLException データ更新でエラーが発生した場合。
	 */
	private void deleteAction(Hashtable params, DataAccess dataAccess)
		throws SQLException {

		// 検索条件文の取得
		String strCondition = (String) params.get(CONDITION_KEY);

		// 検索条件文が取得されていない場合、LOIDを条件に利用。
		if (strCondition == null) {
			String strLoID = (String) params.get(LoPropertyDef.LOID);
			if (strLoID != null) {
				strCondition =
					" WHERE " + LoPropertyDef.LOID + "='" + strLoID + "'";
			}
		}
		if (strCondition == null) {
			strCondition = "";
		}
		// 削除用SQL
		String strSQL =
			"DELETE FROM " + TABLE_NAME + " " + strCondition;

		// 削除処理を実行
		dataAccess.execute(strSQL);
	}
	/**
	 * 挿入または更新処理でレコードの値設定に利用するキー／値を抽出します。<br>
	 * @param params 抽出元となるハッシュテーブル。
	 *                以下のキーと値が含まれていることを期待しています。<br>
	 * <table border="1">
	 * 	<tr>
	 * 		<th>キー</th>
	 * 		<th>値</th>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LOID</td>
	 * 		<td>挿入または更新するLOID</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LoPropertyDef.MATERIALID</td>
	 * 		<td>挿入または更新する教材ID</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LoPropertyDef.WINHEIGHT</td>
	 * 		<td>挿入または更新するウィンドウサイズ(縦)</td>
	 * 	</tr>
	 * 	<tr>
	 * 		<td>LoPropertyDef.WINWIDTH</td>
	 * 		<td>挿入または更新するウィンドウサイズ(横)</td>
	 * 	</tr>
	 * </table><br>
	 * @return paramsから上表のキーで抽出した値を、同名のキーで格納したハッシュテーブル。
	 *          paramsに登録されていない場合は、登録しない。
	 */
	private Hashtable extractValues(Hashtable params) {
		// メソッド開始ログ
		DebugLog.write(
			this.getClass(),
			"HEAD extractValues(" + params + ")",
			DebugLog.ROW);

		Hashtable returned = new Hashtable();
		String[] keys = new String[] {
			// LOID
			LoPropertyDef.LOID,
			// 教材ID
			LoPropertyDef.MATERIALID,
			// Windowサイズ(縦)
			LoPropertyDef.WINHEIGHT,
			// Windowサイズ(横)
			LoPropertyDef.WINWIDTH,
		};
		ScormLoUtil.copyValues(returned, params, keys);

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

	/**
	 * 登録、更新処理時のデータを組み立てます.
	 * @see jp.co.ntt.lms.lo.LoDataAccess#changeData(java.util.Hashtable)
	 */
	protected Hashtable changeData( Hashtable htbParam ) {

		return extractValues( htbParam );
	}
}
