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

//
//	Lo 管理XMO サーバクラス
//			変更履歴
//				2004.01.08	新規作成	二條智文
//
package jp.co.ntt.lms.xmo.Lo;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.*;
import java.sql.*;
import java.net.URLEncoder;
import java.io.UnsupportedEncodingException;

import org.apache.commons.lang.StringEscapeUtils;

import jp.co.ntt.lms.xmo.*;
import jp.co.ntt.lms.xmo.Assignments.AssignmentsClient;
import jp.co.ntt.lms.xmo.GroupAndPeople.GroupAndPeopleTable;
import jp.co.ntt.lms.xmo.LoRelation.*;
import jp.co.ntt.lms.xmo.Message.Message;
import jp.co.ntt.lms.xmo.util.DebugLog;
import jp.co.ntt.lms.lo.*;
import jp.co.ntt.lms.Common.status.*;
import jp.co.ntt.lms.xmo.Lo.LoLogDelete.LogUtil;
import jp.co.ntt.lms.xmo.Lo.lom.LomDataAccess;
import jp.co.ntt.lms.xmo.Base.XMSBaseClient;
import jp.co.ntt.lms.Common.status.prerequisite.*;
import jp.co.ntt.lms.lo.LoLogDataAccess;
// ADD 2005/02/12 START Katsuhiko Kagami(UNITEC) [LO追加情報/追加/更新/削除メソッド追加]
import jp.co.ntt.lms.xmo.Lo.LoExtend.LoExtendCheck;
import jp.co.ntt.lms.xmo.Lo.LoExtend.LoExtendDataAccess;
import jp.co.ntt.lms.xmo.Lo.LoExtend.LoExtendTable;
// ADD 2005/02/12 END Katsuhiko Kagami(UNITEC) [LO追加情報/追加/更新/削除メソッド追加]

/**
 * Lo 管理XMO サーバクラスです。<BR>
 * XMO基本メソッドを実装し、クライアントからの登録、更新、削除、検索処理
 * 要求をうけそれぞれの処理を行います。<BR>
 * RMIサーバとして動作するためRemoteインタフェースであるXMOインタフェースを実装し、
 * 永続的な起動状態を確保するためjava.rmi.server.UnicastRemoteObjectクラスを継承します。
 * @author T.Nijou
 * @version 0.0.0.1 2004.01.08
 */
// MOD 2005/02/12 START Katsuhiko Kagami(UNITEC) [LO追加情報/追加/更新/削除メソッド追加]
public class Lo extends UnicastRemoteObject
implements XMO, LoMessage, LoTable, LoExtendTable, XMOPropertyDef
// MOD 2005/02/12 END Katsuhiko Kagami(UNITEC) [LO追加情報/追加/更新/削除メソッド追加]
{

	//////////////////////////////////////////////////////////////////
	// メソッド名定義
	//////////////////////////////////////////////////////////////////
	/** 登録メソッド名です */
	private static final String METHOD1 = "insert";	// 登録
	/** 更新メソッド名です */
	private static final String METHOD2 = "update";	// 更新
	/** 削除メソッド名です */
	private static final String METHOD3 = "delete";	// 削除
	/** 検索メソッド名です */
	private static final String METHOD4 = "select";	// 検索
	/** Lo種別テーブルの登録メソッド名です */
	private static final String METHOD5 = "insertLoType";
	/** Lo種別テーブルの更新メソッド名です */
	private static final String METHOD6 = "updateLoType";
	/** Lo種別テーブルの削除メソッド名です */
	private static final String METHOD7 = "deleteLoType";
	/** Lo種別テーブルの検索メソッド名です */
	private static final String METHOD8 = "selectLoType";
	/** LOOptionテーブルの登録メソッド名です */
	private static final String METHOD9 = "insertLOOption";
	/** LOOptionテーブルの更新メソッド名です */
	private static final String METHOD10 = "updateLOOption";
	/** LOOptionテーブルの削除メソッド名です */
	private static final String METHOD11 = "deleteLOOption";
	/** LOOptionテーブルの検索メソッド名です */
	private static final String METHOD12 = "selectLOOption";
	/** LOのメニュー一覧を取得するメソッド名です */
	private static final String METHOD13 = "getLoMenuList";	// LOメニュー一覧取得
	/** 教材一覧を取得するメソッド名です */
	private static final String METHOD14 = "getMaterialList";	// 教材一覧取得
	/** LOの属性を変更するメソッド名です */
	private static final String METHOD15 = "changeType";
	/** LOIDからRealLOIDを取得するメソッド名です */
	private static final String METHOD16 = "getRealLOID";
	/** LOIDから参照LOIDを取得するメソッド名です */
	private static final String METHOD17 = "getRefListFromLOID";
	/** RealLOIDから参照LOIDを取得するメソッド名です */
	private static final String METHOD18 = "getRefListFromRealLOID";
	/** LOの階層（グループ名）を検索するメソッド名です */
	private static final String METHOD19 = "searchReferenceList";
	/** 「LO更新」画面、「LO削除」画面に表示する登録内容を検索します。 */
	private static final String METHOD20 = "selectHistory";
	/** 前提条件テーブルのPrereIDからLOIDリストを取得します。 */
	private static final String METHOD21 = "selectLOIDFromPrere";
	/** 前提条件の判定結果を取得します。 */
	private static final String METHOD22 = "isPrerequisited";
	/** ステータス判定結果を取得します。 */
	private static final String METHOD23 = "getStatus";
	// F2FLoタイプ
	private static final String strF2F = "8";

	/** メール送信の１回あたりの送信件数を取得するメソッド名称 */
	private static final String METHOD24 = "getSendMailCount";

//  ADD 2005/02/10 START SUGAWARA [LOM情報取得]
	/** 選択項目付きでLOM情報取得する */
	private static final String METHOD25 = "getLomDisplayData";
//  ADD 2005/02/10 END SUGAWARA
//  ADD 2005/02/11 START SUGAWARA [LOM情報追加]
	/** 選択項目付きでLOM情報取得する */
	private static final String METHOD26 = "updateLomData";
//  ADD 2005/02/11 END SUGAWARA
//  ADD 2005/02/12 START Katsuhiko Kagami(UNITEC) [LO追加情報/追加/更新/削除メソッド追加]
	/** LO拡張情報を検索する */
	private static final String METHOD27 = "selectLoExtend";
	/** LO拡張情報を追加する */
	private static final String METHOD28 = "insertLoExtend";
	/** LO拡張情報を更新する */
	private static final String METHOD29 = "updateLoExtend";
	/** LO拡張情報を削除する */
	private static final String METHOD30 = "deleteLoExtend";
	
//  ADD 2005/02/12 END Katsuhiko Kagami(UNITEC) [LO追加情報/追加/更新/削除メソッド追加]
//	ADD 2005/02/16 START SUGAWARA [LOM属性検索]
	/** LOM情報のテキスト項目の検索を行う */
	private static final String METHOD31 = "searchLomText";
	/** LOM情報の選択項目の検索を行う */
	private static final String METHOD32 = "searchLom";
//	ADD 2005/02/16 START SUGAWARA [LOM属性検索]	
//	ADD 2005/02/23 START SUGAWARA [LOM学習時間取得]
	private static final String METHOD33 = "getTimeSpan";
//	ADD 2005/02/23 START END [LOM学習時間取得]
	/**
	 * ＲＭＩ戻り値Ｍａｐキー：エラーメッセージ。
	 */
	private static final String KEY_ERROR_MESSAGE = "errormessage";

	/**
	 * ＲＭＩ戻り値Ｍａｐキー：送信件数。
	 */
	private static final String KEY_SEND_MAIL_COUNT = "sendMailCount";

	/**
	 * ＬＯテーブルアクセスクラスを保持します
	 */
	private LoDataAccess pobjDataAccess = new LoDataAccess();

	/**
	 * コンストラクタです。
	 */
	public Lo() throws RemoteException {
		// リモートオブジェクトをエクスポートする
		// java.rmi.server.UnicastRemoteObject の
		// 引数なしのコンストラクタを呼び出す
		super();

	}

	/**
	 * メニュー一覧を返します
	 * @return Vector メニュー一覧
	 */
	public Vector getMenuList(Hashtable htbParam) {

		Vector vecMenuList = new Vector();
		try {
			LoEnv objEnv = LoEnv.getInstance();

			checkAssign(htbParam);
			String check = (String)htbParam.get(LoPropertyDef.MANAGE_ASSIGN);
			//管理アサインされている場合のみメニューを取得する
			if ( check != null && check.equals("1") == true ){
				vecMenuList = objEnv.getMenuList();
				// LOコンテナかどうかの判別処理を行います
				String strLoID = (String)htbParam.get( PARAM_ID );
				if( strLoID != null && !strLoID.equals( "" ) ) {
					// 検索文の設定
					String strCondition = " WHERE " + LO_ID + "='" + StringEscapeUtils.escapeSql(strLoID) + "'";
					Hashtable htbData = new Hashtable();
					htbData.put( CONDITION_KEY, strCondition );
					// 検索処理
					Vector vecResult = pobjDataAccess.select( htbData );
					if( vecResult.size() > 0 ) {
						LoData objData = (LoData)vecResult.get(0);
						// 検索結果からLO種別を取り出します
						String strLoType = objData.getLoType();
						if( strLoType.equals( CONTAINER_TYPE ) ) {
							// タイプがコンテナの場合はメニューから属性変更を削除します
							// 20050209 ADD Start s-mori 属性変更はメニューの最後にあるとは限らない
							//vecMenuList.removeElementAt( vecMenuList.size() - 1 );
							int removeIndex = -1;
							for(int vm = 0; vm < vecMenuList.size(); vm++){
								MenuData data = (MenuData)vecMenuList.get(vm);
								if(data.getTitle().equals("ＬＯ属性変更")){
									removeIndex = vm;
									break;
								}
							}
							if(removeIndex != -1){
								vecMenuList.remove(removeIndex);
							}
							// 20050209 ADD End
						}
					}
				}
			}
		}
		catch( Exception e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			return new Vector();
		}
		return vecMenuList;
	}

	/**
	 * メソッド一覧を返します
	 * @return Vector
	 */
	public Vector getMethodList() {
		Vector vecMethod = new Vector();
		vecMethod.add( METHOD1 );
		vecMethod.add( METHOD2 );
		vecMethod.add( METHOD3 );
		vecMethod.add( METHOD4 );
		vecMethod.add( METHOD5 );
		vecMethod.add( METHOD6 );
		vecMethod.add( METHOD7 );
		vecMethod.add( METHOD8 );
		vecMethod.add( METHOD9 );
		vecMethod.add( METHOD10 );
		vecMethod.add( METHOD11 );
		vecMethod.add( METHOD12 );
		vecMethod.add( METHOD24 );
//	  ADD 2005/02/10 START SUGAWARA [LOM情報取得]
		vecMethod.add( METHOD25 );
//	  ADD 2005/02/10 END SUGAWARA
//	  ADD 2005/02/11 START SUGAWARA [LOM情報更新]
		vecMethod.add( METHOD26 );
//	  ADD 2005/02/11 END SUGAWARA
//	  ADD 2005/02/12 START Katsuhiko Kagami(UNITEC) [LO追加情報/追加/更新/削除メソッド追加]
		vecMethod.add( METHOD27 );
		vecMethod.add( METHOD28 );
		vecMethod.add( METHOD29 );
		vecMethod.add( METHOD30 );
//	  ADD 2005/02/12 END Katsuhiko Kagami(UNITEC) [LO追加情報/追加/更新/削除メソッド追加]
		return vecMethod;
	}

	/**
	 * デフォルトメニューを返します
	 * @return String
	 */
	public MenuData getDefaultMenu() {
		return null;
	}

	/**
	 * このXMOで定義された、メソッドのクライアント側からの入り口になるメソッドです。
	 * @param strMethodName 実行するメソッド名を指定します
	 * @param htData メソッドで実行するパラメータを指定します<BR>
	 *               なお必要なキーと値は各DAOの処理メソッドの説明を参照して下さい。
	 * @retunr Object 戻り値（さまざまな戻り値に対応するためObject型としてあります)<BR>
	 *                受け取り側では適切な値にキャストする必要があります。
	 */
	public Object execute( String strMethodName, Hashtable htData ) {

		Object objReturn = null;

		if( strMethodName.equals( METHOD1 ) ) {
			objReturn = insert( htData );
		}
		else if( strMethodName.equals( METHOD2 ) ) {
			objReturn = update( htData );
		}
		else if( strMethodName.equals( METHOD3 ) ) {
			objReturn = delete( htData );
		}
		else if( strMethodName.equals( METHOD4 ) ) {
			objReturn = select( htData );
		}
		else if( strMethodName.equals( METHOD5 ) ) {
			objReturn = insertLoType( htData );
		}
		else if( strMethodName.equals( METHOD6 ) ) {
			objReturn = updateLoType( htData );
		}
		else if( strMethodName.equals( METHOD7 ) ) {
			objReturn = deleteLoType( htData );
		}
		else if( strMethodName.equals( METHOD8 ) ) {
			objReturn = selectLoType( htData );
		}
		else if( strMethodName.equals( METHOD9 ) ) {
			objReturn = insertLOOption( htData );
		}
		else if( strMethodName.equals( METHOD10 ) ) {
			objReturn = updateLOOption( htData );
		}
		else if( strMethodName.equals( METHOD11 ) ) {
			objReturn = deleteLOOption( htData );
		}
		else if( strMethodName.equals( METHOD12 ) ) {
			objReturn = selectLOOption( htData );
		}
		else if( strMethodName.equals( METHOD13 ) ) {
			objReturn = getLoMenuList( htData );
		}
		else if( strMethodName.equals( METHOD14 ) ) {
			objReturn = getMaterialList( htData );
		}
		else if( strMethodName.equals( METHOD15 ) ) {
			objReturn = changeType( htData );
		}
		else if( strMethodName.equals( METHOD16 ) ) {
			objReturn = getRealLOID( htData );
		}
		else if( strMethodName.equals( METHOD17 ) ) {
			objReturn = getRefListFromLOID( htData );
		}
		else if( strMethodName.equals( METHOD18 ) ) {
			objReturn = getRefListFromRealLOID( htData );
		}
		else if( strMethodName.equals( METHOD19 ) ) {
			objReturn = searchReferenceList( htData );
		}
		else if( strMethodName.equals( METHOD20 ) ) {
			objReturn = selectHistory( htData );
		}
		else if( strMethodName.equals( METHOD21 ) ) {
			objReturn = selectLOIDFromPrere( htData );
		}
		else if( strMethodName.equals( METHOD22 ) ) {
			objReturn = isPrerequisited( htData );
		}
		else if( strMethodName.equals( METHOD23 ) ) {
			objReturn = getStatus( htData );
		}

		else if( strMethodName.equals( METHOD24 ) ) {
			objReturn = getSendMailCount( htData );
		}

//	  ADD 2005/02/10 START SUGAWARA[LOM情報取得メソッド追加]
		else if( strMethodName.equals( METHOD25 ) ) {
			objReturn = getLomDisplayData( htData );
		}
//	  ADD 2005/02/10 END SUGAWARA
//	  ADD 2005/02/11 START SUGAWARA[LOM情報更新メソッド追加]
		else if( strMethodName.equals( METHOD26 ) ) {
			objReturn = updateLomData( htData );
		}
//	  ADD 2005/02/10 END SUGAWARA
//	  ADD 2005/02/12 START Katsuhiko Kagami(UNITEC) [LO追加情報/追加/更新/削除メソッド追加]
		else if( strMethodName.equals( METHOD27 ) ) {
			objReturn = selectLoExtend( htData );
		}
		else if( strMethodName.equals( METHOD28 ) ) {
			objReturn = insertLoExtend( htData );
		}
		else if( strMethodName.equals( METHOD29 ) ) {
			objReturn = updateLoExtend( htData );
		}
		else if( strMethodName.equals( METHOD30 ) ) {
			objReturn = deleteLoExtend( htData );
		}
//	  ADD 2005/02/12 END Katsuhiko Kagami(UNITEC) [LO追加情報/追加/更新/削除メソッド追加]
//	  ADD 2005/02/16 START SUGAWARA [LOM属性検索]
		else if( strMethodName.equals( METHOD31 ) ) {
			objReturn = searchLomText( htData );
		}
		else if( strMethodName.equals( METHOD32 ) ) {
			objReturn = searchLom( htData );
		}
//	  ADD 2005/02/10 END SUGAWARA
//		ADD 2005/02/23 START SUGAWARA [LOM学習時間取得]
		else if( strMethodName.equals( METHOD33 ) ) {
		    objReturn = getTimeSpan(htData);
		}
//		ADD 2005/02/23 START END [LOM学習時間取得]

		return objReturn;
	}

	/**
	 * 起動確認（必ずtrueを返す）
	 * @return boolean 必ずtrueが返ります
	 */
	public boolean isLaunch() {
		return true;
	}

	/**
	 * Loテーブルへ登録処理を行います。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの登録処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_ADDRESS              LO実アドレス
	 *             LO_TYPE                 LOタイプ
	 *             LO_TYTLE                LOタイトル
	 *             LO_EXPLANATION          LOの説明
	 *             LO_VERSION              LOのバージョン
	 *             LO_CREATEDATE           作成日
	 *             DELETE_FLAG             隠しフラグ
	 *             MATERIAL_ID             教材ID
	 *             DELETE_FLAG             削除フラグ
	 *             FOREING_ID                外部キー
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 登録情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納して返します)
	 */
	private Vector insert( Hashtable htData ) {
		Vector vecReturn = new Vector();
		MessageData objMessage = null;
		// 登録処理パラメータチェック
		String strMessage = insertCheck( htData );

		// 更新前にLoRelationTreeを取得する
		String strParentID = (String)htData.get( PARENT_ID );

		//XMOTree objTree = LoRelation.getTree();
		XMOTree objTree = LoRelation.getTree( htData );
		
		synchronized( objTree ) {
			String strCopyFlag = (String)htData.get( COPY_FLAG );
			String strLoType = (String)htData.get( LO_TYPE );
			XMONode objBeforeNode = null;
			// コピーではない場合にメモリツリーを保持する
			if( strCopyFlag == null ) {
				objBeforeNode = objTree.searchNode( strParentID );
				objBeforeNode = objBeforeNode.copySelf();
			}
			if( strMessage.equals( "" ) ) {
				DataAccess objDataAccess = new DataAccess();
				try {
					// トランザクションを開始する
					objDataAccess.trans( htData );

					// コネクションインデックスを取得
					Integer objConIndex = new Integer( objDataAccess.getConnectionIndex() );
					// ハッシュテーブルにコネクションインデックスを設定
					htData.put( objDataAccess.CONNECTIONINDEX, objConIndex );

					// LO共通項目の登録処理
					LoData objData = pobjDataAccess.insert( htData );
					vecReturn.add( objData );

					String strChangeFlag = (String)htData.get( CHANGE_FLAG );
					// コピー処理フラグが設定されていない場合はLOサーバに対して、個別の登録処理を行う。
					// コピー処理フラグが設定されていても、コンテナコピー処理時はLOサーバに対して、個別の登録処理を行う。
					//登録処理（コピーと属性変更ではない場合）
					if( strCopyFlag == null  && strChangeFlag == null ) {
						// LO個別テーブルの登録処理
						// LOサーバ名の取得
						Environment objEnv = new Environment();
						String strLoServerName = objEnv.getLoServerName();
						// LOクラスをインスタンス化します
						LoTopClient objLoClient = new LoTopClient( strLoServerName, (String)htData.get( LO_TYPE ) );

						// 個別登録用
						// LOIDの設定
						// RealLOIDの取得
						String strRealLOID = pobjDataAccess.getRealLOID( objData.getLoID(), objDataAccess );
						htData.put( LO_ID, strRealLOID );

						// コネクションインデックスを消去する
						htData.remove( objDataAccess.CONNECTIONINDEX );
						// 登録処理
						if( !objLoClient.setUp( LoTopClient.SETUP_INSERT, htData ) ) {
							throw new XMOException( objLoClient.getMessageData() );
						}
					}
					else if(strCopyFlag != null){
						//コピーの登録処理
						// LO個別テーブルの登録処理
						// LOサーバ名の取得
						Environment objEnv = new Environment();
						String strLoServerName = objEnv.getLoServerName();
						// LOクラスをインスタンス化します
						LoTopClient objLoClient = new LoTopClient( strLoServerName, (String)htData.get( LO_TYPE ) );

						// 個別登録用
						// RealLOIDの取得
						String strRealLOID = pobjDataAccess.getRealLOID( objData.getLoID(), objDataAccess );
						htData.put( LO_ID, strRealLOID );

						// コネクションインデックスを消去する
						htData.remove( objDataAccess.CONNECTIONINDEX );
						// コピーの登録処理
						if( !objLoClient.setUp( LoTopClient.SETUP_COPY, htData ) ) {
							throw new XMOException( objLoClient.getMessageData() );
						}
					}
					else if(strChangeFlag != null){
						//処理無し
					}
					objDataAccess.commit();

					// コピー時以外に以下の処理を実行する
					if( strCopyFlag == null ) {
						//----------------------------------------------------------------------------------------------
						// F2Fの登録時には登録先のアサイン者存在チェックを行い、存在する場合は共通ログの登録を行います。
						//----------------------------------------------------------------------------------------------
						if(strLoType.equals(strF2F)){
							// LOタイプがF2Fの場合、登録先LOのアサインユーザリストを取得する。
							AssignmentsClient objAssignments = new AssignmentsClient();
							Vector vecUserList = new Vector();
							if(!objAssignments.getUserList(strParentID)){
								// エラーの場合
								throw new XMOException( objAssignments.getMessageData() );
							}else{
								vecUserList = objAssignments.getUserListResult();
							}

							// 登録先にアサインユーザがいた場合、共通ログを作成します。
							if(vecUserList != null && vecUserList.size() > 0 ){
								// LOサーバ名の取得
								Environment objEnv = new Environment();
								String strLoServerName = objEnv.getLoServerName();
								// LOクラスをインスタンス化します
								LoTopClient objLoClient = new LoTopClient( strLoServerName, strF2F );

								objDataAccess.trans();

								// RealLOIDの取得
								String strRealLOID = pobjDataAccess.getRealLOID( objData.getLoID(), objDataAccess );

								objDataAccess.commit();

								Hashtable htbParam  = new Hashtable();
								htbParam.put( LO_ID, strRealLOID );
								htbParam.put( "UserList", vecUserList );
								// 登録処理
								if( !objLoClient.setUp( LoTopClient.SETUP_INSERT, htbParam ) ) {
									throw new XMOException( objLoClient.getMessageData() );
								}
							}
						}
					}
					else {
					}

				}
				catch( XMOException xe ) {
					DebugLog.write( this.getClass(), xe, DebugLog.HIGHT );
					// エラー発生時ロールバック
					// ロールバック
					try { objDataAccess.rollback(); } catch( Exception ex ) {}
					// コピーではない場合にメモリツリーのロールバック
					if( strCopyFlag == null ) {
						// メモリ上のツリーもロールバックを行う
						objTree.switchNode( strParentID, objBeforeNode );
					}
					objMessage = xe.getMessageData();
				}
				catch( SQLException se ) {
					DebugLog.write( this.getClass(), se, DebugLog.HIGHT );
					// エラー発生時ロールバック
					// ロールバック
					try { objDataAccess.rollback(); } catch( Exception ex ) {}
					// コピーではない場合にメモリツリーのロールバック
					if( strCopyFlag == null ) {
						// メモリ上のツリーもロールバックを行う
						objTree.switchNode( strParentID, objBeforeNode );
					}
					objMessage = getMessageData( DB_ERR );
				}
				catch( Exception e ) {
					DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
					// エラー発生時ロールバック
					// ロールバック
					try { objDataAccess.rollback(); } catch( Exception ex ) {}
					// コピーではない場合にメモリツリーのロールバック
					if( strCopyFlag == null ) {
						// メモリ上のツリーもロールバックを行う
						objTree.switchNode( strParentID, objBeforeNode );
					}
					objMessage = getMessageData( SYSTEM_ERR );
				}
			}
			else {
				DebugLog.write( this.getClass(), new Exception(), DebugLog.HIGHT );
				objMessage = getMessageData( strMessage );
			}
		}
		vecReturn.add( 0, objMessage );
		return vecReturn;
	}

	/**
	 * Loテーブルへ更新処理を行います。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの更新処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_ID                   LOID
	 *             LO_ADDRESS              LO実アドレス
	 *             LO_TYPE                 LOタイプ
	 *             LO_TYTLE                LOタイトル
	 *             LO_EXPLANATION          LOの説明
	 *             LO_VERSION              LOのバージョン
	 *             LO_CREATEDATE           作成日
	 *             DELETE_FLAG             隠しフラグ
	 *             MATERIAL_ID             教材ID
	 *             FOREING_ID               外部キー
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 登録情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納して返します)
	 */
	private Vector update( Hashtable htData ) {
		Vector vecReturn = new Vector();
		MessageData objMessage = null;
		// 登録処理パラメータチェック
		String strMessage = updateCheck( htData );
		if( strMessage.equals( "" ) ) {
			DataAccess objDataAccess = new DataAccess();
			try {
				// トランザクションを開始する
				objDataAccess.trans( htData );

				// ハッシュテーブルにコネクションインデックスを設定
				htData.put( objDataAccess.CONNECTIONINDEX, new Integer( objDataAccess.getConnectionIndex() ) );

				// LO共通項目の登録処理
				pobjDataAccess.update( htData );

				// LO個別テーブルの登録処理
				// LOサーバ名の取得
				Environment objEnv = new Environment();
				String strLoServerName = objEnv.getLoServerName();
				// LOクラスをインスタンス化します
				LoTopClient objLoClient = new LoTopClient( strLoServerName, (String)htData.get( LO_TYPE ) );
				// コネクションインデックスを消去する
				htData.remove( objDataAccess.CONNECTIONINDEX );

				// LOIDの取得
				String strLOID = (String)htData.get( LO_ID );
				// RealLOIDの取得
				String strRealLOID = pobjDataAccess.getRealLOID( strLOID, objDataAccess );
				htData.put( LO_ID, strRealLOID );
				// 登録処理
				if( !objLoClient.setUp( LoTopClient.SETUP_UPDATE, htData ) ) {
					throw new XMOException( objLoClient.getMessageData() );
				}

				objDataAccess.commit();


			}
			catch( XMOException xe ) {
				// エラー発生時ロールバック
				// ロールバック
				try { objDataAccess.rollback(); } catch( Exception ex ) {}
				objMessage = xe.getMessageData();
			}
			catch( SQLException se ) {
				DebugLog.write( this.getClass(), se, DebugLog.HIGHT );
				// エラー発生時ロールバック
				// ロールバック
				try { objDataAccess.rollback(); } catch( Exception ex ) {}
				objMessage = getMessageData( DB_ERR );
			}
			catch( Exception e ) {
				DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
				// エラー発生時ロールバック
				// ロールバック
				try { objDataAccess.rollback(); } catch( Exception ex ) {}
				objMessage = getMessageData( SYSTEM_ERR );
			}

			// ステータス伝搬フラグを取得し、設定されていたら
			// ステータス伝搬を行います。
			// ステータス伝搬でエラーが起きた場合は、ログにはき、画面には正常で返します。
			String strStatusFlag = (String)htData.get( STATUS_PROPAGATE_FLAG );
			if( strStatusFlag != null ) {

				String strLoID = (String)htData.get( LO_ID );
				StatusPropagation objPropagation = new StatusPropagation( strLoID );
				PropagateControl.getInstance().addPropagate(objPropagation);

			}
		}
		else {
			DebugLog.write( this.getClass(), new Exception(), DebugLog.HIGHT );
			objMessage = getMessageData( strMessage );
		}


		vecReturn.add( objMessage );
		return vecReturn;
	}

	/**
	 * Loテーブルへ削除処理を行います。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの削除処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           更新条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 削除情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納して返します)
	 */
	private Vector delete( Hashtable htData ) {
		Vector vecReturn = new Vector();
		Vector vecF2FList = new Vector();	// 未整理フォルダに移動するF2FのLOIDリストを格納します。

		MessageData objMessage = null;
		DataAccess objDataAccess = new DataAccess();
		try {
			// トランザクションを開始する
			objDataAccess.trans( htData );

			// コネクションインデックスを取得
			Integer objConIndex = new Integer( objDataAccess.getConnectionIndex() );
			// ハッシュテーブルにコネクションインデックスを設定
			htData.put( objDataAccess.CONNECTIONINDEX, objConIndex );

			htData.put("F2FList", vecF2FList);

			// LO共通項目の登録処理
			pobjDataAccess.delete( htData );


			objDataAccess.commit();
			
			// 未整理フォルダに移動するF2FのLOIDリストを取得します。
			vecF2FList = (Vector)htData.get("F2FList");
			
			// 未整理フォルダに移動するF2F教材がある場合の処理
			if(vecF2FList.size() > 0){
				// 未整理フォルダのアサインユーザリストを取得する。
				AssignmentsClient objAssignments = new AssignmentsClient();
				Vector vecUserList = new Vector();
				if(!objAssignments.getUserList(WASTES_LOID)) {
					// エラーの場合
					throw new XMOException( objAssignments.getMessageData() );
				}else{
					vecUserList = objAssignments.getUserListResult();
					if(vecUserList != null){
						htData.put("UserList", vecUserList);
					}
				}
				// 未整理フォルダにアサインされているユーザが一人以上いた場合のみF2Fの初期ログ作成を行う。
				if( vecUserList != null && vecUserList.size() > 0 ) {
					// F2FLOIDリスト分LOOPしてアサイン者分の共通ログを作成します。
					for( int i = 0; i < vecF2FList.size(); i++ ){
						// 登録項目設定
						Hashtable htbData = new Hashtable();
						htData.put( "LOID", vecF2FList.get(i) );
						htData.put( "UserList", vecUserList );
						// LOサーバ名の取得
						Environment objEnv = new Environment();
						String strLoServerName = objEnv.getLoServerName();
						// LOクラスをインスタンス化します
						LoTopClient objLoClient = new LoTopClient( strLoServerName, strF2F );
						// 共通ログ登録処理
						if( !objLoClient.setUp( LoTopClient.SETUP_INSERT, htData ) ) {
							throw new XMOException( objLoClient.getMessageData() );
						}
					}
				}
			}
			
			
		}
		catch( XMOException xe ) {
			// エラー発生時ロールバック
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			objMessage = xe.getMessageData();
		}
		catch( SQLException se ) {
			DebugLog.write( this.getClass(), se, DebugLog.HIGHT );
			// エラー発生時ロールバック
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			objMessage = getMessageData( DB_ERR );
		}
		catch( Exception e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// エラー発生時ロールバック
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			objMessage = getMessageData( LO_DELETE_FAILD_ERR );
		}
		vecReturn.add( objMessage );
		return vecReturn;
	}

	/**
	 * Loテーブルへ検索処理を行います。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの検索処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           検索条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 検索情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納し、２番目移行に
	 *                      AssignmentsDataクラスを格納して返します。)
	 */
	private Vector select( Hashtable htData ) {
		Vector vecResult = new Vector();

		MessageData objMessage = null;
		try {
			vecResult = pobjDataAccess.select( htData );
		}
		catch( XMOException xe ) {
			objMessage = xe.getMessageData();
		}

		// 配列の先頭にメッセージデータを格納します
		vecResult.add( 0, objMessage );
		return vecResult;
	}

	/**
	 * Lo種別テーブルへ登録処理を行います。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの登録処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             TYPE_NAME               LO種別名
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 登録情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納して返します)
	 */
	private Vector insertLoType( Hashtable htData ) {
		Vector vecReturn = new Vector();
		MessageData objMessage = null;
		// 登録処理パラメータチェック
		String strMessage = insertLoTypeCheck( htData );
		if( strMessage.equals( "" ) ) {
			try {
				pobjDataAccess.insertLoType( htData );
			}
			catch( XMOException xe ) {
				objMessage = xe.getMessageData();
			}
		}
		else {
			objMessage = getMessageData( strMessage );
		}

		vecReturn.add( objMessage );
		return vecReturn;
	}

	/**
	 * Lo種別テーブルへ更新処理を行います。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの更新処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_TYPE                 LO種別
	 *             TYPE_NAME               LO種別名
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 登録情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納して返します)
	 */
	private Vector updateLoType( Hashtable htData ) {
		Vector vecReturn = new Vector();

		MessageData objMessage = null;
		// 登録処理パラメータチェック
		String strMessage = updateLoTypeCheck( htData );
		if( strMessage.equals( "" ) ) {
			try {
				pobjDataAccess.updateLoType( htData );
			}
			catch( XMOException xe ) {
				objMessage = xe.getMessageData();
			}
		}
		else {
			objMessage = getMessageData( strMessage );
		}

		vecReturn.add( objMessage );
		return vecReturn;
	}

	/**
	 * Lo種別テーブルへ削除処理を行います。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの削除処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           更新条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 削除情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納して返します)
	 */
	private Vector deleteLoType( Hashtable htData ) {
		Vector vecReturn = new Vector();

		MessageData objMessage = null;
		try {
			pobjDataAccess.deleteLoType( htData );
		}
		catch( XMOException xe ) {
			objMessage = xe.getMessageData();
		}

		vecReturn.add( objMessage );
		return vecReturn;
	}

	/**
	 * Lo種別テーブルへ検索処理を行います。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの検索処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           検索条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 検索情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納し、２番目移行に
	 *                      AssignmentsDataクラスを格納して返します。)
	 */
	private Vector selectLoType( Hashtable htData ) {
		Vector vecResult = new Vector();

		MessageData objMessage = null;
		try {
			vecResult = pobjDataAccess.selectLoType( htData );
		}
		catch( XMOException xe ) {
			objMessage = xe.getMessageData();
		}
		// 配列の先頭にメッセージオブジェクトを格納します
		vecResult.add( 0, objMessage );
		return vecResult;
	}

	/**
	 * LOOptionテーブルへ登録処理を行います。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの登録処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_ID                   LOID
	 *             OptionID                OptionID
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 登録情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納して返します)
	 */
	private Vector insertLOOption( Hashtable htData ) {
		Vector vecReturn = new Vector();

		MessageData objMessage = null;
		// 登録処理パラメータチェック
		String strMessage = insertLOOptionCheck( htData );
		if( strMessage.equals( "" ) ) {
			try {
				pobjDataAccess.insertLOOption( htData );
			}
			catch( XMOException xe ) {
				objMessage = xe.getMessageData();
			}
		}
		else {
			objMessage = getMessageData( strMessage );
		}
		vecReturn.add( objMessage );
		return vecReturn;
	}

	/**
	 * LOOptionテーブルへ更新処理を行います。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの更新処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_ID                   LOID
	 *             OptionID                OptionID
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 登録情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納して返します)
	 */
	private Vector updateLOOption( Hashtable htData ) {
		Vector vecReturn = new Vector();

		MessageData objMessage = null;
		// 登録処理パラメータチェック
		String strMessage = updateLOOptionCheck( htData );
		if( strMessage.equals( "" ) ) {
			try {
				pobjDataAccess.updateLOOption( htData );
			}
			catch( XMOException xe ) {
				objMessage = xe.getMessageData();
			}
		}
		else {
			objMessage = getMessageData( strMessage );
		}

		// 配列の先頭にメッセージオブジェクトを格納します
		vecReturn.add( objMessage );
		return vecReturn;
	}

	/**
	 * LOOptionテーブルへ削除処理を行います。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの削除処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           更新条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 削除情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納して返します)
	 */
	private Vector deleteLOOption( Hashtable htData ) {
		Vector vecReturn = new Vector();

		MessageData objMessage = null;
		try {
			pobjDataAccess.deleteLOOption( htData );
		}
		catch( XMOException xe ) {
			objMessage = xe.getMessageData();
		}

		vecReturn.add( objMessage );
		return vecReturn;
	}

	/**
	 * LOOptionテーブルへ検索処理を行います。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの検索処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           検索条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 検索情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納し、２番目移行に
	 *                      AssignmentsDataクラスを格納して返します。)
	 */
	private Vector selectLOOption( Hashtable htData ) {
		Vector vecResult = new Vector();

		MessageData objMessage = null;
		try {
			vecResult = pobjDataAccess.selectLOOption( htData );
		}
		catch( XMOException xe ) {
			objMessage = xe.getMessageData();
		}

		// 配列の先頭にメッセージオブジェクトを格納します
		vecResult.add( 0, objMessage );
		return vecResult;
	}

	/**
	 * 指定されたLOのメニューリストを取得します。<BR>
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_ID                   取得するLOID
	 *             USER_ID                 学習をするユーザID
	 *             PASSWD                  学習をするユーザのパスワード
	 *             RETURNURL               戻りURL
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData LO情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納し、２番目移行に
	 *                      MenuDataオブジェクトの配列です。)
	 */
	private Vector getLoMenuList( Hashtable htData ) {

		// LOIDの取得
		String strLoID = (String)htData.get( LO_ID );
		String strAuID = (String)htData.get( AU_ID );
		String strUserID = (String)htData.get( USER_ID );
		String strUserType = (String)htData.get( USER_TYPE );
		String strPassword = (String)htData.get( PASSWD );
		String strReturnURL = (String)htData.get( RETURNURL );
		String strLoType = "";
		String strMaterialID = "";
		String strMaterialURL = "";

		Vector vecReturn = new Vector();
		try {


			// LOIDをキーにして、materialIDを取得し、パラメータにセットします
			// 検索条件の設定
			String strCondition = " WHERE " + LO_ID + "='" + StringEscapeUtils.escapeSql(strLoID) + "'";
			Hashtable htCondition = new Hashtable();
			htCondition.put( DataAccess.CONDITION_KEY, strCondition );

			// 検索処理
			Vector vecLoInfo = pobjDataAccess.select( htCondition );
			if( vecLoInfo.size() > 0 ) {
				// 検索結果の取得（サイズが1以上)
				LoData objLoData = (LoData)vecLoInfo.get(0);
				strLoType = objLoData.getLoType();
				strMaterialID = objLoData.getMaterialID();
				strMaterialURL = objLoData.getLoAddress();
			}
			else {
				vecReturn.add( null );
				return vecReturn;
			}

			// LOサーバ名の取得
			Environment objEnv = new Environment();
			String strLoServerName = objEnv.getLoServerName();
			// LOクラスをインスタンス化します
			LoTopClient objLoClient = new LoTopClient( strLoServerName, strLoType );
			// ユーザIDを設定します
			objLoClient.setUserID( strUserID );
			// パスワードを設定します
			objLoClient.setPassword( strPassword );
			// LO種別を設定します
			objLoClient.setLoType( strLoType );
			// 戻りURLを設定します
			objLoClient.setReturnURL( strReturnURL );
			// LOIDを設定します
			objLoClient.setLoID( strLoID );
			// 章IDを設定します
			objLoClient.setAuID( strAuID );

			// メニューデータを取得
			Vector vecLoMenuList = new Vector();
			if( !objLoClient.getMenuList() ) {
				// @pending ここにエラー処理を記述
				MessageData objMessage = getMessageData( SYSTEM_ERR );
				throw new XMOException( objMessage );
			}

			// LOメニューデータをXMOメニューデータにマッピング
			for( int i = 0; i < objLoClient.getMenuListSize(); i++ ) {
				MenuData objMenu = objLoClient.getMenuData(i);
				if( objMenu.getLoMenuType().equals( MenuData.DEFAULT_MENU ) ) {
					LoData objData = new LoData();
					objData.setMenuData( objMenu );
					vecReturn.add( objData );
				}
			}

			// パラメータの引数のLOIDでOptionテーブルを検索し、レコードが存在した場合は付加LOの
			// getMenuListも呼ぶ
			// パラメータのセット
			Hashtable htbOptionParam = new Hashtable();
			String strOptionCondition = " WHERE " + LO_ID + "='" + StringEscapeUtils.escapeSql(strLoID) + "'";
			htbOptionParam.put( CONDITION_KEY, strOptionCondition );
			Vector vecOptionResult = pobjDataAccess.selectLOOption( htbOptionParam );
			// 検索がうまくいった場合
			for( int i = 0; i < vecOptionResult.size(); i++ ) {
				LoData objLoData = (LoData)vecOptionResult.get(i);
				for( int j = 0; j < objLoData.getOptionInfoLength(); j++ ) {
					String[] strOptionInfo = objLoData.getOptionInfo(j);

					// OptionIDをキーにしてLOテーブルからLO情報を取得します
					String strOptionID = strOptionInfo[1];
					// パラメータの設定
					Hashtable htbParam = new Hashtable();
					String strLoConditin = " WHERE " + LO_ID + "='" + StringEscapeUtils.escapeSql(strOptionID) + "'";
					htbParam.put( CONDITION_KEY, strLoConditin );
					// LOテーブル検索処理
					Vector vecLoResult = pobjDataAccess.select( htbParam );
					if( vecLoResult.size() > 0 ) {
						// 検索結果の取得
						LoData objOptionLoData = (LoData)vecLoResult.get(0);
						String strOptinLoType = objOptionLoData.getLoType();
						String strOptionMaterialID = objOptionLoData.getMaterialID();
						String strOptionMaterialURL = objOptionLoData.getLoAddress();

						// 検索結果を元にLoサーバからメニューを取得する
						LoTopClient objOptionClient = new LoTopClient( strLoServerName, strOptinLoType );
						// ユーザIDを設定します
						objOptionClient.setUserID( strUserID );
						// パスワードを設定します
						objOptionClient.setPassword( strPassword );
						// ユーザタイプを設定します
						objOptionClient.setUserType( strUserType );
						// LO種別を設定します
						objOptionClient.setLoType( strOptinLoType );
						// 教材IDを設定します
						objOptionClient.setMaterialID( strMaterialID );
						// 教材URLを設定します
						objOptionClient.setMaterialURL( java.net.URLEncoder.encode( strOptionMaterialURL, "UTF-8") );
						// 戻りURLを設定します
						objOptionClient.setReturnURL( strReturnURL );
						// LOIDを設定します
						objOptionClient.setLoID( strOptionID );
						// 章IDを設定します
						objLoClient.setAuID( strAuID );

						// メニューデータを取得
						Vector vecLoOptionMenuList = new Vector();

						if( !objOptionClient.getMenuList() ) {
							// @pending エラー処理記述
							MessageData objMessage = getMessageData( SYSTEM_ERR );
							throw new XMOException( objMessage );
						}

						// LOメニューデータをXMOメニューデータにマッピング
						for( int k = 0; k < objOptionClient.getMenuListSize(); k++ ) {
							MenuData objMenu = objOptionClient.getMenuData(k);
							if( objMenu.getLoMenuType().equals( MenuData.DEFAULT_MENU ) ) {
								LoData objData = new LoData();
								objData.setMenuData( objMenu );
								vecReturn.add( objData );
							}
						}
					}
				}
			}
		}
		catch( XMOException xe ) {
			DebugLog.write( this.getClass(), xe, DebugLog.HIGHT );
			// エラーメッセージからメッセージオブジェクトを生成
			// メッセージデータオブジェクトの作成
			MessageData objMessage = xe.getMessageData();
			Vector vecErr = new Vector();
			vecErr.add( objMessage );
			return vecErr;
		}
		catch( Exception e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// 例外発生時はシステムエラーを投げる
			MessageData objMessage = getMessageData( SYSTEM_ERR );
			Vector vecErr = new Vector();
			vecErr.add( objMessage );
			return vecErr;
		}

		// 正常終了メッセージ
		MessageData objMessage = new MessageData();
		// 配列の先頭に正常終了メッセージを挿入する
		vecReturn.add( 0, objMessage );
		return vecReturn;
	}

	/**
	 * 指定されたLO種別に登録されている教材リストを取得します。<BR>
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_TYPE                 取得するLOID
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData LO種別情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納し、２番目移行に
	 *                      教材リストを格納します。)
	 */
	private Vector getMaterialList( Hashtable htbParam ) {

		// メッセージIDを保持します
		String strMessage = "";

		// 結果を保持します
		Vector vecReturn = new Vector();

		// LO種別の取得
		String strLoType = (String)htbParam.get( LO_TYPE );

		// パラメータチェック
		if( strLoType == null ) {
			// メッセージデータオブジェクトの作成
			MessageData objMessage = getMessageData( LOTYPE_HISSU_WAR );
			vecReturn.add( objMessage );
			return vecReturn;
		}

		try {
			// LOサーバ名の取得
			Environment objEnv = new Environment();
			String strLoServerName = objEnv.getLoServerName();
			// LOクラスをインスタンス化します
			LoTopClient objLoClient = new LoTopClient( strLoServerName, strLoType );

			// LO種別を設定します
			objLoClient.setLoType( strLoType );
			// 教材一覧取得メソッドを実行します
			if( !objLoClient.getMaterialList() ) {
				// @pending エラー処理記述
				throw new Exception();
			}

			for( int i = 0; i < objLoClient.getMaterialSize(); i++ ) {
				LoData objLoData = new LoData();
				objLoData.setMaterialData( objLoClient.getMaterialData(i) );
				vecReturn.add( objLoData );
			}

		}
		catch( Exception e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// メッセージデータオブジェクトの作成
			MessageData objMessage = getMessageData( GETMATERIALLIST_ERR );
			Vector vecTemp = new Vector();
			vecTemp.add( objMessage );
			return vecTemp;
		}

		// 配列の1番目に正常値を格納
		vecReturn.add( 0, new MessageData() );
		return vecReturn;
	}

	/**
	 * LOの属性を変更します
	 * @param htbParam パラメータ
	 * @return vecReturn
	 */
	public Vector changeType( Hashtable htbParam ) {
		MessageData objMessage = null;

		// LOID
		String strLoID = null;

		// ユーザID
		String strUserID = null;

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

		// 属性変更のメインロジッククラス(スーパークラス)
		ChangeTypeAbstract changeType = null;

		// 属性変更サブクラスファクトリークラス
		ChangeTypeFactory factory = null;

		// パラメータからLOIDを取得します
		strLoID = (String)htbParam.get(LO_ID);
		// パラメータからLOIDを取得します
		strUserID = (String)htbParam.get(LOGIN_USER_ID);

		try {
			// データアクセスクラスのインスタンス
			objDataAccess = new DataAccess();

			objDataAccess.trans();

			factory = new ChangeTypeFactory();
			changeType = factory.getFactory(strLoID, strUserID, objDataAccess);

			// 最小LOID取得処理
			changeType.setMinimumLoID();
			// LO情報変更アクションメソッド
			changeType.changeLoAction();
			// ログセッション情報変更アクションメソッド
			changeType.changeLoLogSessionAction();
			// 共通ログ情報変更アクションメソッド
			changeType.changeLoLogAction();
			// 評価情報変更アクションメソッド
			changeType.changeEvaluteAction();
			// 更新履歴情報変更アクションメソッド
			changeType.changeLoHistoryAction();
			// 個別ログ情報変更アクションメソッド
			changeType.changeIndividualLogAction();
			// 各LO個別情報変更アクションメソッド
			changeType.changeOriginalLoAction();

			// コミット処理
			objDataAccess.commit();

			// 正常に終わった場合
			Vector vecReturn = new Vector();
			vecReturn.add( null );
			return vecReturn;

		} catch( XMOException xe ) {
			// ロールバック
			try{ objDataAccess.rollback(); } catch( Exception e ) {}
			DebugLog.write( this.getClass(), xe, DebugLog.HIGHT );
			objMessage = xe.getMessageData();
			Vector vecErr = new Vector();
			vecErr.add( objMessage );
			return vecErr;
		} catch( Exception e ) {
			// ロールバック
			try{ objDataAccess.rollback(); } catch( Exception ex ) {}
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// システムエラーを作成
			objMessage = getMessageData( SYSTEM_ERR );
			Vector vecErr = new Vector();
			vecErr.add( objMessage );
			return vecErr;
		}
	}

	/**
	 * メッセージオブジェクトを作成します
	 * @param strMessageID メッセージID
	 * @return MessageData メッセージオブジェクト 例外発生時はnullを返します
	 */
	private MessageData getMessageData( String strMessageID) {
		MessageData objMessage = null;
		try {
			objMessage = Message.getInstance().getMessageData( strMessageID, MSG_FIEL_PATH, MSG_FILE_NAME );
		}
		catch( Exception e ) {

		}
		return objMessage;
	}



	/*
	 * 登録処理のパラメータチェックを行います<BR>
	 * 以下のパラメータのチェックを行います。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_ADDRESS              LO実アドレス
	 *             LO_TYPE                 LOタイプ
	 *             LO_TYTLE                LOタイトル
	 *             LO_EXPLANATION          LOの説明
	 *             LO_VERSION              LOのバージョン
	 *             LO_CREATEDATE           作成日
	 *             DELETE_FLAG             隠しフラグ
	 *             MATERIAL_ID             教材ID
	 *             FOREING_ID               外部キー
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htbParam パラメータ
	 * @return String エラー時はエラー番号 OKのときは空文字を返します
	 */
	private String insertCheck( Hashtable htbParam ) {

		String strMessage = "";
		String strCheck = "";

		// LO実アドレスのチェック
		strCheck = (String)htbParam.get( LO_ADDRESS );
		strMessage = LoCheck.checkLoAddress( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// LOタイプのチェック(必須チェックあり)
		strCheck = (String)htbParam.get( LO_TYPE );
		strMessage = LoCheck.checkLoType( strCheck, true );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// LOタイトルのチェック(必須チェックあり)
		strCheck = (String)htbParam.get( LO_TYTLE );
		strMessage = LoCheck.checkLoTytle( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// LOの説明のチェック
		strCheck = (String)htbParam.get( LO_EXPLANATION );
		strMessage = LoCheck.checkLoExplanation( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// LOのバージョンのチェック
		strCheck = (String)htbParam.get( LO_VERSION );
		strMessage = LoCheck.checkVersion( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// 作成日のチェック
		strCheck = (String)htbParam.get( LO_CREATEDATE );
		strMessage = LoCheck.checkLoCreateDate( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// 隠しフラグのチェック
		strCheck = (String)htbParam.get( DELETE_FLAG );
		strMessage = LoCheck.checkDeleteFlag( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// 教材IDのチェック
		strCheck = (String)htbParam.get( MATERIAL_ID );
		strMessage = LoCheck.checkMaterialID( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		//画面入力なら
		if(!BoolAutomaticLoForeignID()){
			strCheck = (String)htbParam.get( FOREIGN_ID );
			strMessage = LoCheck.checkForeignID( strCheck, true );
			if( !strMessage.equals( "" ) ) {
				return strMessage;
			}
		}
		
	   // Mentor Email アドレスのチェック
	   strCheck = (String)htbParam.get( MENTOR_EMAIL_ADDRESS );
	   strMessage = LoCheck.checkMentorEmail( strCheck, false );
	   if( !strMessage.equals( "" ) ) {
		   return strMessage;
	   }

		// 正常時は空文字を返す
		return "";
	}


	/*
	 * 登録処理のパラメータチェックを行います<BR>
	 * 以下のパラメータのチェックを行います。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_ID                   LOID
	 *             LO_ADDRESS              LO実アドレス
	 *             LO_TYPE                 LOタイプ
	 *             LO_TYTLE                LOタイトル
	 *             LO_EXPLANATION          LOの説明
	 *             LO_VERSION              LOのバージョン
	 *             LO_CREATEDATE           作成日
	 *             DELETE_FLAG             隠しフラグ
	 *             MATERIAL_ID             教材ID
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htbParam パラメータ
	 * @return String エラー時はエラー番号 OKのときは空文字を返します
	 */
	private String updateCheck( Hashtable htbParam ) {

		String strMessage = "";
		String strCheck = "";

		// LOIDのチェック
		strCheck = (String)htbParam.get( LO_ID );
		strMessage = LoCheck.checkLoID( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// LO実アドレスのチェック
		strCheck = (String)htbParam.get( LO_ADDRESS );
		strMessage = LoCheck.checkLoAddress( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// LOタイプのチェック
		strCheck = (String)htbParam.get( LO_TYPE );
		strMessage = LoCheck.checkLoType( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// LOタイトルのチェック
		strCheck = (String)htbParam.get( LO_TYTLE );
		strMessage = LoCheck.checkLoTytle( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// LOの説明のチェック
		strCheck = (String)htbParam.get( LO_EXPLANATION );
		strMessage = LoCheck.checkLoExplanation( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// LOのバージョンのチェック
		strCheck = (String)htbParam.get( LO_VERSION );
		strMessage = LoCheck.checkVersion( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// 作成日のチェック
		strCheck = (String)htbParam.get( LO_CREATEDATE );
		strMessage = LoCheck.checkLoCreateDate( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// 隠しフラグのチェック
		strCheck = (String)htbParam.get( DELETE_FLAG );
		strMessage = LoCheck.checkDeleteFlag( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// 教材IDのチェック
		strCheck = (String)htbParam.get( MATERIAL_ID );
		strMessage = LoCheck.checkMaterialID( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// 外部キーのチェック(必須チェックあり)
		strCheck = (String)htbParam.get( FOREIGN_ID );
		strMessage = LoCheck.checkForeignID( strCheck, true );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}
		
			 // MentorEmailアドレスのチェック
			 strCheck = (String)htbParam.get( MENTOR_EMAIL_ADDRESS );
			 strMessage = LoCheck.checkMentorEmail( strCheck, false );
			 if( !strMessage.equals( "" ) ) {
				 return strMessage;
			 }
		

		// 正常時は空文字を返す
		return "";
	}

	/*
	 * Lo種別テーブル登録処理のパラメータチェックを行います<BR>
	 * 以下のパラメータのチェックを行います。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             TYPE_NAME               LO種別名
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htbParam パラメータ
	 * @return String エラー時はエラー番号 OKのときは空文字を返します
	 */
	private String insertLoTypeCheck( Hashtable htbParam ) {

		String strMessage = "";
		String strCheck = "";

		// LO種別名のチェック(必須チェックあり)
		strCheck = (String)htbParam.get( TYPE_NAME );
		strMessage = LoCheck.checkTypeName( strCheck, true );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// LOサブ種別のチェック(必須チェックあり)
		strCheck = (String)htbParam.get( LO_SUB_TYPE );
		strMessage = LoCheck.checkForeignID( strCheck, true );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// 正常時は空文字を返す
		return "";
	}

	/*
	 * 登録処理のパラメータチェックを行います<BR>
	 * 以下のパラメータのチェックを行います。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_TYPE                 LOタイプ
	 *             TYPE_NAME               LO種別名
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htbParam パラメータ
	 * @return String エラー時はエラー番号 OKのときは空文字を返します
	 */
	private String updateLoTypeCheck( Hashtable htbParam ) {

		String strMessage = "";
		String strCheck = "";

		// LOタイプのチェック
		strCheck = (String)htbParam.get( LO_TYPE );
		strMessage = LoCheck.checkLoType( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// LO種別名のチェック
		strCheck = (String)htbParam.get( TYPE_NAME );
		strMessage = LoCheck.checkTypeName( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// LOサブ種別のチェック
		strCheck = (String)htbParam.get( LO_SUB_TYPE );
		strMessage = LoCheck.checkForeignID( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// 正常時は空文字を返す
		return "";
	}

	/*
	 * LOOptionテーブル登録処理のパラメータチェックを行います<BR>
	 * 以下のパラメータのチェックを行います。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_ID                   LOID
	 *             OPTION_ID               オプションID
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htbParam パラメータ
	 * @return String エラー時はエラー番号 OKのときは空文字を返します
	 */
	private String insertLOOptionCheck( Hashtable htbParam ) {

		String strMessage = "";
		String strCheck = "";

		// LOIDのチェック(必須チェック有り)
		strCheck = (String)htbParam.get( LO_ID );
		strMessage = LoCheck.checkLoID( strCheck, true );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// OptionIDのチェック(必須チェック有り)
		strCheck = (String)htbParam.get( OPTION_ID );
		strMessage = LoCheck.checkOptionID( strCheck, true );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}


		// 正常時は空文字を返す
		return "";
	}

	/*
	 * LOOptionテーブル更新処理のパラメータチェックを行います<BR>
	 * 以下のパラメータのチェックを行います。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_ID                   LOID
	 *             OPTION_ID               オプションID
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htbParam パラメータ
	 * @return String エラー時はエラー番号 OKのときは空文字を返します
	 */
	private String updateLOOptionCheck( Hashtable htbParam ) {

		String strMessage = "";
		String strCheck = "";

		// LOIDのチェック
		strCheck = (String)htbParam.get( LO_ID );
		strMessage = LoCheck.checkLoID( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}

		// OptionIDのチェック
		strCheck = (String)htbParam.get( OPTION_ID );
		strMessage = LoCheck.checkOptionID( strCheck, false );
		if( !strMessage.equals( "" ) ) {
			return strMessage;
		}


		// 正常時は空文字を返す
		return "";
	}


	/**
	 * LOの管理アサイン、学習アサイン状況を調べます。<BR>
	 * 管理アサイン、学習アサインされている場合はパラメータで渡したHastable内に以下のように情報を格納します。
	 * <PRE>
	 *              KEY      | 管理アサイン | 学習アサイン |
	 *       MANAGE_ASSIGN   |      ○      |              |
	 *       LEARNER_ASSIGN  |              |      ○      |
	 * </PRE>
	 * @param htbParam 情報格納用のHashtable
	 */
	private void checkAssign( Hashtable htbParam )
		throws XMOException
	{
		try {
			// ユーザIDの取得
			String strUserID = (String)htbParam.get( LoPropertyDef.USER );
			// LOIDの取得
			String strLoID = (String)htbParam.get( LoPropertyDef.LOID );

			if( strUserID == null || strLoID == null ) {
				// ユーザIDとLOIDのどちらかが設定されていない場合は処理は行わない
				return;
			}

			if( strUserID.equals( XMOPropertyDef.ROOT_USER ) ) {
				// ルートユーザの場合は管理アサイン、学習アサイン両方を設定する
				htbParam.put( LoPropertyDef.MANAGE_ASSIGN, "1" );
				htbParam.put( LoPropertyDef.LEARNER_ASSIGN, "1" );
				return;
			}

			// 指定したLoIDのアサイン状況を再帰的に調べます。
			checkAssignRef( htbParam, strLoID );

		}
		catch( XMOException le ) {
			throw le;
		}
		catch( Exception e ) {
			throw new XMOException( SYSTEM_ERR );
		}
	}

	/**
	 * 再帰呼び出し用のメソッド<BR>
	 * ユーザIDとLOIDを受け取りアサイン情報を取得します。
	 * @param htbParam 情報格納用のHashtable
	 * @param strLoID 検索対象のLOID
	 */
	private void checkAssignRef( Hashtable htbParam, String strLoID )
		throws XMOException, Exception
	{
		// 管理アサイン、学習アサイン情報を取り出す。
		String strManageAssign = (String)htbParam.get( LoPropertyDef.MANAGE_ASSIGN );
		String strLearnerAssign = (String)htbParam.get( LoPropertyDef.LEARNER_ASSIGN );
		// すでに管理アサイン、学習アサイン情報が設定されていた場合は処理を行わない
		if( strManageAssign != null &&
			strLearnerAssign != null ) {
			return;
		}

		// ユーザIDの取得
		String strUserID = (String)htbParam.get( LoPropertyDef.USER );

		// ユーザIDからMemberShipIDを取得する
		StringBuffer sbSubQuery = new StringBuffer();
		sbSubQuery.append( "(SELECT " );
		sbSubQuery.append( GroupAndPeopleTable.MEMBER_SHIP_ID );
		sbSubQuery.append( " FROM " );
		sbSubQuery.append( GroupAndPeopleTable.TABLE_NAME );
		sbSubQuery.append( " WHERE " );
		sbSubQuery.append( GroupAndPeopleTable.CHILD_ID );
		sbSubQuery.append( "='" + StringEscapeUtils.escapeSql(strUserID) +"') " );

		// LOIDを子IDに設定して、親IDを取得する
		LoRelationClient objLoRelation = new LoRelationClient();
		objLoRelation.setChildID( strLoID );
		// 検索処理実行
		if( !objLoRelation.select() ) {
			// 検索処理に失敗した場合
			throw new XMOException( objLoRelation.getMessage() );
		}

		// 検索結果の取得
		while( objLoRelation.next() ) {
			String strParentID = objLoRelation.getParentID();

			String strMaterialID = strParentID + strLoID;

			// Assignmentsの検索処理
			AssignmentsClient objAss = new AssignmentsClient();
			// 検索条件文を作成する
			String strCondition = objAss.MATERIAL_ID + "='" + StringEscapeUtils.escapeSql(strMaterialID) + "' AND " + objAss.MEMBER_SHIP_ID + " in " + sbSubQuery.toString();
			// 検索条件を設定する
			objAss.setCondition( strCondition );
			// 検索処理実行
			if( !objAss.select() ) {
				// 検索処理に失敗した場合
				throw new XMOException( objAss.getMessage() );
			}

			// 検索結果の取得
			while( objAss.next() ) {
				// 管理アサインの取得
				strManageAssign = objAss.getManagementAuthority();
				if( strManageAssign.equals( "1" ) ) {
					// ハッシュテーブルに設定する
					htbParam.put( LoPropertyDef.MANAGE_ASSIGN, strManageAssign );
				}
				// 学習アサインの取得
				strLearnerAssign = objAss.getLearnAuthority();
				if( strLearnerAssign.equals( "1" ) ) {
					// ハッシュテーブルに設定する
					htbParam.put( LoPropertyDef.LEARNER_ASSIGN, strLearnerAssign );
				}
			}

			// 親LOIDで上記の処理を再帰的に繰り返す。
			checkAssignRef( htbParam, strParentID );
		}
	}

	/**
	 * LO外部ID自動採番判断
	 * @return boolen　自動採番: true
	 */
	public boolean BoolAutomaticLoForeignID() {

		boolean boolflag = false;
		// XMS2.ini ファイルにグループPrefixが設定しているかをチェックする
		try{
			Environment objEnv = new Environment();
			String strGetLoPrefix = objEnv.getLoPrefix();

			if (strGetLoPrefix != null ){
				boolflag = true;
			}
		}
		catch(Exception ex)
		{
		}
		return 	boolflag;
	}

	/**
	 * LOIDからRealLOIDを取得します。
	 * @return String RealLOID
	 */
	public String getRealLOID(Hashtable htbParam) {
		String strRealLOID = null;

		try {
			strRealLOID = pobjDataAccess.getRealLOID((String)htbParam.get(LoPropertyDef.LOID));
		}catch( XMOException xe ) {
			return strRealLOID;
		}

		return strRealLOID;
	}

	/**
	 * LOIDから参照リストを取得します。
	 * @return String RealLOID
	 */
	public String[] getRefListFromLOID(Hashtable htbParam) {
		Vector vecList = new Vector();
		String strRealLOID = "";

		try {
			strRealLOID = pobjDataAccess.getRealLOID((String)htbParam.get(LoPropertyDef.LOID));
			vecList = pobjDataAccess.getCopyList(strRealLOID);
		}catch( XMOException xe ) {
			return null;
		}

		// 配列コピー
		String[] strLOIDList = new String[ vecList.size() ];
		vecList.copyInto( strLOIDList );

		return strLOIDList;
	}

	/**
	 * RealLOIDから参照リストを取得します。
	 * @return String RealLOID
	 */
	public String[] getRefListFromRealLOID(Hashtable htbParam) {
		Vector vecList = new Vector();
		String strRealLOID = "";

		try {
			vecList = pobjDataAccess.getCopyList((String)htbParam.get(LoPropertyDef.LOID));
		}catch( XMOException xe ) {
			return null;
		}

		// 配列コピー
		String[] strLOIDList = new String[ vecList.size() ];
		vecList.copyInto( strLOIDList );

		return strLOIDList;
	}

	/**
	 * 安全にHashtableに追加するメソッドです
	 */
	private void putData( Hashtable htbData, String strKey, String strValue ) {
		if( strValue != null ) {
			htbData.put( strKey, strValue );
		}
	}


	/**
	 * LOIDから参照LOIDリストを取得します。<BR>
	 * LoRelation.javaのsearchPathメソッドでパスを取得。
	 * @param htData 検索情報
	 * @return Vector 結果を返します。
	 */
	private Vector searchReferenceList( Hashtable htData ) {

		Vector vecRes = new Vector();									// 戻り値用ベクター
		MessageData objMessage = null;
		String[][] strReferenceList = null;
		String strTargetLoID = (String)htData.get( LO_ID );				// LOID
		String strLoginUserID = (String)htData.get( LOGIN_USER_ID2 );	// ログインユーザID
		String strLoID = "";
		try
		{

			// パラメータチェック
			if( strTargetLoID == null || strLoginUserID == null ) {
				throw new XMOException( PARAM_WAR );
			}

			// 権限フィルター用ベクター
			Vector vecFilterList = null;

			// ログインユーザがスーパユーザ以外の場合は権限対象LOのリストを取得します。
			if( !strLoginUserID.equals(XMOPropertyDef.ROOT_USER) ) {

				// XMSBaseを使用して、ログインユーザが使用できるLOリストを取得します。
				XMSBaseClient objBase = new XMSBaseClient();
				if( !objBase.searchRootLoList( strLoginUserID ) ) {
					throw new XMOException( objBase.getMessageData() );
				}

				LoData[] objRootLo = objBase.getRootLoList();
				// 権限フィルタ用のIDリストを作成する。
				vecFilterList = new Vector();
				for( int i = 0; i < objRootLo.length; i++ ) {
					vecFilterList.add( objRootLo[i].getLoID() );
				}
			}

			// LOIDから参照LOIDリストを取得します。
			DataAccess objDataAccess = new DataAccess();
			objDataAccess.trans();
			LoDataAccess objLoDataAccess = new LoDataAccess();
			String[] strRefLoIDList = objLoDataAccess.getRefLOList( strTargetLoID, objDataAccess );

			// 参照IDリスト格納用のベクター
			Vector vecReferenceIDList = new Vector();
			for( int i = 0; i < strRefLoIDList.length; i++ ) {
				// 参照LOIDのパスを取得する
				LoRelationClient objLoRelation = new LoRelationClient();
				if( !objLoRelation.searchPath(strRefLoIDList[i]) ) {
					// パス検索がうまくいかなかった場合
					DebugLog.write(this.getClass(), "LOパス検索失敗", DebugLog.HIGHT);
					throw new XMOException( objLoRelation.getMessageData() );
				}

				while( objLoRelation.next() ) {
					StringBuffer sbPathForID = new StringBuffer();

					boolean isAuth = false;
					String[] strPath = objLoRelation.getPath();
					for( int j = 0; j < strPath.length; j++ ) {
						strLoID = strPath[j];

						// 権限フィルターが設定されていた場合は権限によるチェックをします。
						if( vecFilterList != null &&
						    vecFilterList.contains( strLoID ) )
						{
							// 権限フィルターにIDが含まれていたら権限フラグをtrueにする
							isAuth = true;
						}

						// 権限フィルターに含まれているIDより後にIDをバスリストに足す
						if( vecFilterList == null || isAuth ) {
							// 各階層のLO名を取得
							sbPathForID.append(strLoID);

							// LOID階層を'/'で区切って表現する。
							if( j < strPath.length - 1 ) {
								sbPathForID.append("/");
							}
						}
					}

					if( vecFilterList == null || isAuth ) {
						String strPathForID = sbPathForID.toString();
						if( vecFilterList != null ) {
							// 権限フィルターが設定されていた場合はパスの頭に"lotreeroot"を足す
							strPathForID = "lotreeroot/" + strPathForID;
						}
						// PATHの取得
						vecReferenceIDList.add( strPathForID );
					}
				}
			}
			// 結果を配列にコピーする
			String[] strReferenceIDList = new String[vecReferenceIDList.size()];
			vecReferenceIDList.copyInto( strReferenceIDList );


			// 名前パスリストを格納する
			String[] strReferenceNameList = new String[strReferenceIDList.length];
			// IDパスから名前パスを生成する。
			for(int i = 0; i < strReferenceIDList.length; i ++) {
				// 名前パス生成StringBufferのインスタンス化
				StringBuffer strNameBuf = new StringBuffer();

				// トークン分割
				StringTokenizer objToken = new StringTokenizer( strReferenceIDList[i], "/" );

				while( objToken.hasMoreTokens() ) {
					String strID = objToken.nextToken();
					String strLoTitle = null;
					if( strID.equals( "lotreeroot" ) ) {
						strLoTitle = "root";
					}
					else {
						strLoTitle = objLoDataAccess.getLoTitle(strID, objDataAccess);
					}
					// 各階層のLO名を取得
					strNameBuf.append( strLoTitle );
					// 区切り文字('/')の付加
					strNameBuf.append( "/" );
				}
				// 最後の'/'を取り除き配列に格納
				strReferenceNameList[i] = strNameBuf.substring( 0, strNameBuf.length() - 1 );
			}

			objDataAccess.commit();

			strReferenceList = new String[2][strReferenceIDList.length];
			strReferenceList[0] = strReferenceIDList;
			strReferenceList[1] = strReferenceNameList;
		}
		catch( SQLException se ) {
			objMessage = getMessageData( DB_ERR );
			DebugLog.write(this.getClass(), se, DebugLog.HIGHT);
		}
		catch( XMOException xe ) {
			objMessage = xe.getMessageData();
			DebugLog.write(this.getClass(), xe, DebugLog.HIGHT);
		}
		catch( Exception e ) {
			objMessage = getMessageData( SYSTEM_ERR );
			DebugLog.write(this.getClass(), e, DebugLog.HIGHT);
		}

		vecRes.add( objMessage );
		vecRes.add( strReferenceList );

		return vecRes;
	}

	/**
	 * Loテーブルへ検索処理を行います。<BR>
	 * 以下のパラメータチェックを行い、すべてOKの場合は
	 * DAOの検索処理メソッドを実行します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           検索条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 検索情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納し、２番目移行に
	 *                      AssignmentsDataクラスを格納して返します。)
	 */
	private Vector selectHistory( Hashtable htData ) {
		Vector vecRet = new Vector();									// 戻り値用ベクター
		MessageData objMessage = null;
		HistoryData objHistory = new HistoryData();

		try {
			objHistory = pobjDataAccess.selectHistory( htData );
		}
		catch( XMOException xe ) {
			objMessage = xe.getMessageData();
		}
		vecRet.add( objMessage );
		vecRet.add( objHistory );

		return vecRet;
	}

	/**
	 * prerequisiteテーブルの検索処理を行います。
	 * PrereIDからLOIDリストを取得します。<BR>
	 * @param htData 検索情報
	 * @return Vector 結果を返します。
	 */
	private Vector selectLOIDFromPrere( Hashtable htData ) {
		Vector vecRet = new Vector();									// 戻り値用ベクター
		MessageData objMessage = null;

		try {
			String[] strList = pobjDataAccess.selectLOIDFromPrere( htData );
			vecRet.add( strList );
		}
		catch( XMOException xe ) {
			objMessage = xe.getMessageData();
		}
		vecRet.add( 0, objMessage );

		return vecRet;
	}

	/**
	 * 前提条件の判定結果を取得します。
	 * 前提条件を満たしている場合は1を、満たしていない場合は0を返します。<BR>
	 * @param htData 検索情報
	 * @return Vector 結果を返します。
	 */
	private Vector isPrerequisited( Hashtable htData ) 
	{
		Vector vecRet = new Vector();									// 戻り値用ベクター
		MessageData objMessage = null;
		
		try {
			// ユーザIDの取得
			String strUserID = (String)htData.get( USER_ID );
			// LOIDの取得
			String strLoID = (String)htData.get( LO_ID );
			// 前提条件の取得
			String strPrere = (String)htData.get(PRERE);

			if( strUserID == null || strLoID == null ) {
				// ユーザIDとLOIDのどちらかが設定されていない場合は処理は行わない
				objMessage = getMessageData(PARAM_WAR);
				throw new XMOException(objMessage);
			}

			// --------------------------------------
			// 前提条件を満たしているか、判定します。
			// --------------------------------------
			boolean blIsPrerequisited = false;
			if(strPrere != null && !strPrere.equals("")){
				// 前提条件クラスをインスタンス化
				Prerequisite objPrerequisite = new Prerequisite(	strPrere,
																	strUserID,
																	strLoID );
				// 前提条件パース
				objPrerequisite.parse();
				blIsPrerequisited = objPrerequisite.isPrerequisited();
			}
			else{
				blIsPrerequisited = true;
			}
			
			// 前提条件を満たしている場合は、前提条件フラグをonにする。
			int intRet = 0;
			if(blIsPrerequisited){
				intRet = 1;
			}
			Integer objRet = new Integer(intRet);
			vecRet.add( objRet );
		}
		catch( Exception e ) {
			objMessage = getMessageData( SYSTEM_ERR );
		}
		vecRet.add( 0, objMessage );
		
		return vecRet;
	}

	/**
	 * ステータスを判定します。
	 * 以下のステータスを返却します。<BR>
	 * @param htData 検索情報
	 * @return Vector 結果を返します。
	 */
	private Vector getStatus( Hashtable htData ) 
	{
		Vector vecRet = new Vector();									// 戻り値用ベクター
		MessageData objMessage = null;
		
		try {
			// LOIDの取得
			String strLoID = (String)htData.get( LO_ID );
			// ユーザIDの取得
			String strUserID = (String)htData.get( USER_ID );

			if( strLoID == null || strUserID == null ) {
				// LOIDとユーザIDのどちらかが設定されていない場合は処理は行わない
				objMessage = getMessageData(PARAM_WAR);
				throw new XMOException(objMessage);
			}
			
			// LOIDからRealLOIDを取得します。
			String strRealLOID = pobjDataAccess.getRealLOID( strLoID );

			// LOLogテーブル情報を取得します。
			LoLogDataAccess objLoLogDataAccess= new LoLogDataAccess();
			LoLogRecord objLoLogRecord = objLoLogDataAccess.getLoLog(strUserID, strRealLOID);
			
			// 取得したLOLogテーブルデータからステータスの判定を行います。
			// 未学習の場合
			int intStatus = 0;
			if(objLoLogRecord == null){
				intStatus = 1;
			}
			else{
				String strPassDay = objLoLogRecord.getPassday();
				String strStudyEndDate = objLoLogRecord.getStudyEndDate();
				// 学習中の場合
				if((strPassDay == null || strPassDay.equals("")) && (strStudyEndDate == null || strStudyEndDate.equals(""))){
					intStatus = 2;
				}
				// 完了の場合
				else if((strPassDay == null || strPassDay.equals("")) && (strStudyEndDate != null && !strStudyEndDate.equals(""))){
					intStatus = 3;
				}
				// 合格の場合
				else if((strPassDay != null && !strPassDay.equals("")) && (strStudyEndDate == null || strStudyEndDate.equals(""))){
					intStatus = 4;
				}
				// 完了・合格の場合
				else if((strPassDay != null && !strPassDay.equals("")) && (strStudyEndDate != null && !strStudyEndDate.equals(""))){
					intStatus = 5;
				}
			}
			
			Integer objRet = new Integer(intStatus);
			vecRet.add( objRet );
		}
		catch( Exception e ) {
			objMessage = getMessageData( SYSTEM_ERR );
		}
		vecRet.add( 0, objMessage );
		
		return vecRet;
	}


	/**
	 * メール送信の１回あたりの送信件数を取得する。
	 * @param htbParam パラメータ・ハッシュテーブル。
	 * @return 送信件数またはエラーメッセージを含むMap。
	 * 以下のキー−値の組み合わせのいずれかを戻す。<br>
	 * <table border="1">
	 *	<tr>
	 *		<td>キー</td><td>型</td><td>内容</td>
	 *	</tr>
	 *	<tr>
	 *		<td>KEY_ERROR_MESSAGE</td><td>String</td><td>エラーメッセージ</td>
	 *	</tr>
	 *	<tr>
	 *		<td>KEY_SEND_MAIL_COUNT</td><td>Integer</td><td>送信件数</td>
	 *	</tr>
	 * </table>
	 * @see #KEY_ERROR_MESSAGE
	 * @see #KEY_SEND_MAIL_COUNT
	 * @see Integer
	 */
	private Map getSendMailCount( Hashtable htbParam ) {
		// このメソッドの戻り値
		Map returnValue = null;

		// アサインメント環境変数クラス 
		LoEnv objEnv = null;
		// 送信件数
		Integer sendMailCount = null;
		String  strSendMailCount = null;
		
		try {
			returnValue = new HashMap();
			// アサインメント環境変数クラスを取得
			objEnv = LoEnv.getInstance();
			//一括送信数を取得
			strSendMailCount = objEnv.getSendMailCount();
			// 数値化
			sendMailCount = new Integer(strSendMailCount);
			// 戻り値に格納
			returnValue.put(KEY_SEND_MAIL_COUNT, sendMailCount);
		} catch (Exception e) {
			// 例外発生時は、メッセージを格納
			DebugLog.write(this.getClass(), e,DebugLog.HIGHT);
			returnValue.put(KEY_ERROR_MESSAGE, e.getMessage());
		}
		return returnValue;	
	}

//  ADD 2005/02/10 START SUGAWARA[LOM情報取得メソッド追加]
	/**
	 * 
	 */
	public Vector getLomDisplayData(Hashtable params) {
		MessageData objMessage = null;
		Vector displayData = null;
		
		try {
	        LomDataAccess dataAccess = new LomDataAccess();
	        if (params.get(LO_ID).equals("")) {
		        displayData = dataAccess.getDisplayData();
	        }
	        else {
		        displayData = dataAccess.getDisplayData((String) params.get(LO_ID));
	        }
	    }
	    catch (Exception e) {
			// 例外発生時は、メッセージを格納
			DebugLog.write(this.getClass(), e,DebugLog.HIGHT);
			objMessage = getMessageData( SYSTEM_ERR );
		}
	    finally {
			displayData.insertElementAt(objMessage, 0);
	    }
		return displayData;
	}
//ADD 2005/02/10 END SUGAWARA

//ADD 2005/02/11 START SUGAWARA[LOM情報取得メソッド追加]
	/**
	 * 
	 */
	public Vector updateLomData(Hashtable params) {
		MessageData objMessage = null;
		Vector message = new Vector();
		
		try {
	        LomDataAccess dataAccess = new LomDataAccess();
	        if (!dataAccess.enrollDisplayData(((Vector) params.get(LO_ID)))) {
	            throw new Exception("LOM情報の登録に失敗しました。");
	        }
	    }
	    catch (Exception e) {
			// 例外発生時は、メッセージを格納
			DebugLog.write(this.getClass(), e,DebugLog.HIGHT);
			objMessage = getMessageData( SYSTEM_ERR );
		}
	    finally {
	        message.add(objMessage);
	    }
		return message;
	}
//	ADD 2005/02/11 END SUGAWARA

//	ADD 2005/02/12 START Katsuhko Kagami(UNITEC)[LO追加情報取得/更新/削除メソッド追加]
	/**
	 * LoExtendテーブルを検索して情報を取得します。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_ID                   LOID
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 検索条件パラメータ
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納し、２番目移行に
	 *                      リストを格納します。)
	 */
	public Vector selectLoExtend( Hashtable htData )
	{
		MessageData objMessage = null;
		Vector vecResult = new Vector();
		
		try {
			// パラメータのチェック
			String strLoID = (String)htData.get( LO_ID );

			String strMessage = LoExtendCheck.checkLOID( strLoID, true );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}

			// 検索条件の設定
			Hashtable htParams = makeParam(strLoID, null, null, 
					null, null, null, null, null, true);
			
			// LOExtendテーブル情報を取得します。
			LoExtendDataAccess objLoExtDataAccess= new LoExtendDataAccess();
			vecResult = objLoExtDataAccess.select(htParams);
	    }
	    catch (Exception e) {
			// 例外発生時は、メッセージを格納
			DebugLog.write(this.getClass(), e,DebugLog.HIGHT);
			objMessage = getMessageData( SYSTEM_ERR );
		}
	    finally {
	    	vecResult.add(0, objMessage);
	    }
		return vecResult;
	}
	
	/**
	 * LoExtendテーブルへ登録処理を行います。<BR>
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_ID                   LoID
	 *             LOEXTEND_BUY            購入ステータス
	 *             LOEXTEND_KEYWORD1       LO推奨キーワード1
	 *             LOEXTEND_KEYWORD2       LO推奨キーワード2
	 *             LOEXTEND_KEYWORD3       LO推奨キーワード3
	 *             LOEXTEND_KEYWORD4       LO推奨キーワード4
	 *             LOEXTEND_KEYWORD5       LO推奨キーワード5
	 *          ---------------------------------------------
	 * @param htData 検索条件パラメータ
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納し、２番目移行に
	 *                      リストを格納します。)
	 */
	public Vector insertLoExtend( Hashtable htData )
	{
		MessageData objMessage = null;
		Vector vecResult = new Vector();
		
		try {
			// パラメータのチェック
			String strLoID = (String)htData.get( LO_ID );
			String strBuy = (String)htData.get( LOEXTEND_BUY );
			String strKeyword1 = (String)htData.get( LOEXTEND_KEYWORD1 );
			String strKeyword2 = (String)htData.get( LOEXTEND_KEYWORD2 );
			String strKeyword3 = (String)htData.get( LOEXTEND_KEYWORD3 );
			String strKeyword4 = (String)htData.get( LOEXTEND_KEYWORD4 );
			String strKeyword5 = (String)htData.get( LOEXTEND_KEYWORD5 );

			String strMessage = LoExtendCheck.checkLOID( strLoID, true );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = LoExtendCheck.checkBuy( strBuy, true );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = LoExtendCheck.checkKeyword1( strKeyword1, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = LoExtendCheck.checkKeyword2( strKeyword2, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = LoExtendCheck.checkKeyword3( strKeyword3, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = LoExtendCheck.checkKeyword4( strKeyword4, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = LoExtendCheck.checkKeyword5( strKeyword5, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}

			// 格納する情報の設定
			Hashtable htParams = makeParam(strLoID, strLoID, strBuy, 
					strKeyword1, strKeyword2, strKeyword3, 
					strKeyword4, strKeyword5, false);
			
			// LOExtendテーブルへ情報を格納します。
			LoExtendDataAccess objLoExtDataAccess= new LoExtendDataAccess();
			objLoExtDataAccess.insert(htParams);
	    }
	    catch (Exception e) {
			// 例外発生時は、メッセージを格納
			DebugLog.write(this.getClass(), e,DebugLog.HIGHT);
			objMessage = getMessageData( SYSTEM_ERR );
		}
	    finally {
	    	vecResult.add(0, objMessage);
	    }
		return vecResult;
	}

	/**
	 * LoExtendテーブルへ更新処理を行います。<BR>
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             LO_ID                   LoID
	 *             LOEXTEND_BUY            購入ステータス
	 *             LOEXTEND_KEYWORD1       LO推奨キーワード1
	 *             LOEXTEND_KEYWORD2       LO推奨キーワード2
	 *             LOEXTEND_KEYWORD3       LO推奨キーワード3
	 *             LOEXTEND_KEYWORD4       LO推奨キーワード4
	 *             LOEXTEND_KEYWORD5       LO推奨キーワード5
	 *          ---------------------------------------------
	 * @param htData 検索条件パラメータ
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納し、２番目移行に
	 *                      リストを格納します。)
	 */
	public Vector updateLoExtend( Hashtable htData )
	{
		MessageData objMessage = null;
		Vector vecResult = new Vector();
		
		try {
			// パラメータのチェック
			String strLoID = (String)htData.get( LO_ID );
			String strBuy = (String)htData.get( LOEXTEND_BUY );
			String strKeyword1 = (String)htData.get( LOEXTEND_KEYWORD1 );
			String strKeyword2 = (String)htData.get( LOEXTEND_KEYWORD2 );
			String strKeyword3 = (String)htData.get( LOEXTEND_KEYWORD3 );
			String strKeyword4 = (String)htData.get( LOEXTEND_KEYWORD4 );
			String strKeyword5 = (String)htData.get( LOEXTEND_KEYWORD5 );
			
			String strMessage = LoExtendCheck.checkLOID( strLoID, true );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = LoExtendCheck.checkBuy( strBuy, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = LoExtendCheck.checkKeyword1( strKeyword1, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = LoExtendCheck.checkKeyword2( strKeyword2, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = LoExtendCheck.checkKeyword3( strKeyword3, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = LoExtendCheck.checkKeyword4( strKeyword4, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}
			strMessage = LoExtendCheck.checkKeyword5( strKeyword5, false );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}

			// 更新する情報の設定
			Hashtable htParams = makeParam(strLoID, null, strBuy,
					strKeyword1, strKeyword2, strKeyword3, 
					strKeyword4, strKeyword5, true);
			
			// LOExtendテーブルの情報を更新します。
			LoExtendDataAccess objLoExtDataAccess= new LoExtendDataAccess();
			objLoExtDataAccess.update(htParams);
	    }
	    catch (Exception e) {
			// 例外発生時は、メッセージを格納
			DebugLog.write(this.getClass(), e,DebugLog.HIGHT);
			objMessage = getMessageData( SYSTEM_ERR );
		}
	    finally {
	    	vecResult.add(0, objMessage);
	    }
		return vecResult;
	}

	/**
	 * LoExtendテーブルへ削除処理を行います。<BR>
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             DELETE_LOID             LOID
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 検索条件パラメータ
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納し、２番目移行に
	 *                      リストを格納します。)
	 */
	public Vector deleteLoExtend( Hashtable htData )
	{
		MessageData objMessage = null;
		Vector vecResult = new Vector();
		
		try {
			// パラメータのチェック
			String strLoID = (String)htData.get( DELETE_LOID );
			
			String strMessage = LoExtendCheck.checkLOID( strLoID, true );
			if( !strMessage.equals( "" ) ) {
				throw new Exception( strMessage );
			}

			// 削除する情報の設定
			Hashtable htParams = makeParam(strLoID, null, null,
					null, null, null, null, null, true);
			
			// LOExtendテーブルの情報を削除します。
			LoExtendDataAccess objLoExtDataAccess= new LoExtendDataAccess();
			objLoExtDataAccess.delete(htParams);
	    }
	    catch (Exception e) {
			// 例外発生時は、メッセージを格納
			DebugLog.write(this.getClass(), e,DebugLog.HIGHT);
			objMessage = getMessageData( SYSTEM_ERR );
		}
	    finally {
	    	vecResult.add(0, objMessage);
	    }
		return vecResult;
	}

	/**
	 * データの投入および検索に使用するパラメータを作成します。
	 * @param strTargetLoID		対象のLoID
	 * @param strLoID			LoID
	 * @param strBuy			購入ステータス
	 * @param strKeyword1		LO推奨検索キーワード1
	 * @param strKeyword2		LO推奨検索キーワード2
	 * @param strKeyword3		LO推奨検索キーワード3
	 * @param strKeyword4		LO推奨検索キーワード4
	 * @param strKeyword5		LO推奨検索キーワード5
	 * @param bWhere			LoIDを使用してWhere句を作成する:true/Where句無し:false
	 * @return Hashtable パラメータが設定されたオブジェクト
	 */
	private Hashtable makeParam(String strTargetLoID, String strLoID, 
			String strBuy, 
			String strKeyword1, String strKeyword2, 
			String strKeyword3, String strKeyword4,
			String strKeyword5,
			boolean bWhere)
	{
		Hashtable htParams = new Hashtable();

		if (strLoID != null) {
			// LoIDの設定
			htParams.put( LO_ID, strLoID );
		}
		if (strBuy != null) {
			// Buyの設定
			htParams.put( LOEXTEND_BUY, strBuy );
		}
		if (strKeyword1 != null) {
			// keyword1の設定
			htParams.put( LOEXTEND_KEYWORD1, strKeyword1 );
		}
		if (strKeyword2 != null) {
			// keyword2の設定
			htParams.put( LOEXTEND_KEYWORD2, strKeyword2 );
		}
		if (strKeyword3 != null) {
			// keyword3の設定
			htParams.put( LOEXTEND_KEYWORD3, strKeyword3 );
		}
		if (strKeyword4 != null) {
			// keyword4の設定
			htParams.put( LOEXTEND_KEYWORD4, strKeyword4 );
		}
		if (strKeyword5 != null) {
			// keyword5の設定
			htParams.put( LOEXTEND_KEYWORD5, strKeyword5 );
		}
			
		// Where句を作成する
		if (bWhere) {
			if (strTargetLoID != null) {
				// 検索条件の設定
				String strCondition = LO_ID + "= '" + StringEscapeUtils.escapeSql(strTargetLoID) + "' ";
				htParams.put( CONDITION_KEY, " WHERE " + strCondition );
			}
		}
		
		return htParams;
	}
//	ADD 2005/02/12 END Katsuhko Kagami(UNITEC)
//	ADD 2005/02/16 START SUGAWARA [LOM属性検索]
	/**
	 * LOM情報のテキスト項目の検索を行う。
	 * @param params
	 * @return
	 */
	public Vector searchLomText(Hashtable params) {
		MessageData objMessage = null;
		Vector loIDArray = new Vector();
		
		try {
	        LomDataAccess dataAccess = new LomDataAccess();
	        loIDArray = dataAccess.searchText((String)params.get(LO_ID));
	    }
	    catch (Exception e) {
			// 例外発生時は、メッセージを格納
			DebugLog.write(this.getClass(), e,DebugLog.HIGHT);
			objMessage = getMessageData( SYSTEM_ERR );
		}
	    finally {
			loIDArray.insertElementAt(objMessage, 0);
	    }
		return loIDArray;
	}
	
	/**
	 * LOM情報の選択項目の検索を行う。
	 * @param params
	 * @return
	 */
	public Vector searchLom(Hashtable params) {
		MessageData objMessage = null;
		Vector loIDArray = new Vector();
		
		try {
	        LomDataAccess dataAccess = new LomDataAccess();
	        loIDArray = dataAccess.searchLom((Vector) params.get(LO_ID));
	    }
	    catch (Exception e) {
			// 例外発生時は、メッセージを格納
			DebugLog.write(this.getClass(), e,DebugLog.HIGHT);
			objMessage = getMessageData( SYSTEM_ERR );
		}
	    finally {
			loIDArray.insertElementAt(objMessage, 0);
	    }
		return loIDArray;
	}
//	ADD 2005/02/16 END SUGAWARA [LOM属性検索]	
//	ADD 2005/02/23 START SUGAWARA [LOM学習時間取得]
	/**
	 * 学習時間の取得を行います。
	 * @param params
	 * @return
	 */
	public Vector getTimeSpan(Hashtable params) {
		MessageData objMessage = null;
		Vector loIDArray = new Vector();
		String loID = (String) params.get(LO_ID);
		try {
	        LomDataAccess dataAccess = new LomDataAccess();
	        loIDArray.add(dataAccess.getEductionalTimeSpan(loID));
	    }
	    catch (Exception e) {
			// 例外発生時は、メッセージを格納
			DebugLog.write(this.getClass(), e,DebugLog.HIGHT);
			objMessage = getMessageData( SYSTEM_ERR );
		}
	    finally {
			loIDArray.insertElementAt(objMessage, 0);
	    }
		return loIDArray;
	}
//	ADD 2005/02/23 END SUGAWARA [LOM学習時間取得]
}

