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

//
//	Roles 管理XMO データアクセスクラス
//			変更履歴
//				2004.01.08	新規作成	二條智文

package jp.co.ntt.lms.xmo.Roles;

import java.util.*;
import java.sql.*;

import org.apache.commons.lang.StringEscapeUtils;

import jp.co.ntt.lms.xmo.*;
import jp.co.ntt.lms.xmo.Roles.*;
import jp.co.ntt.lms.xmo.util.ChangeEncode;
import jp.co.ntt.lms.xmo.RoleAssignments.RoleAssignmentsClient;
import jp.co.ntt.lms.xmo.util.DebugLog;
import jp.co.ntt.lms.xmo.Message.Message;
import jp.co.ntt.lms.xmo.Environment;

/**
 * Roles 管理XMO データアクセスクラスです。<BR>
 * このクラスはRolesテーブルへの登録、修正、削除、検索処理を実行します。<BR>
 * DataAccessクラスを使用し、登録、修正、削除、検索処理単位で
 * トランザクション管理を行います。
 * @author T.Nijou
 * @version 0.0.0.1 2004.01.08
 */
public class RolesDataAccess
	implements RolesMessage, RolesTable
{

	/**
	 * コンストラクタです。<BR>
	 */
	public RolesDataAccess() {
	}

	/**
	 * Rolesテーブル,RolesFunctionテーブルへ登録処理を行います。<BR>
	 * 以下の情報をHashtableに格納して渡してください。<BR>
	 * なおテーブルの主キー以外を省略した場合は省略したフィールドには
	 * Null値が格納されます。
	 * <PRE>
	 *             key                     	説明
	 *          ---------------------------------------------
	 *             ROLENAME              	権限名称
	 *             DELETED                 	隠しフラグ
	 *             LEARNFLAG               	学習権限フラグ
	 *             FUNCTION                	機能(XMOID)
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 登録情報
	 * @return String 結果(正しく終了した場合のみ)
	 * @exception XMOException データベースエラーが発生した場合
	 */
	synchronized public String insert( Hashtable htParam )
		throws XMOException
	{
		// 権限データがnullのとき
		if( htParam == null ) {
			DebugLog.write( this.getClass(), new Exception(), DebugLog.HIGHT );	
			// パラメータエラーをスローする
			throw new XMOException( getMessageData( PARAM_WAR ) );
		}

		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME);
		try {
			// トランザクションを開始する
			objDataAccess.trans( htParam );

			// 登録処理実行
			insertAction( htParam, objDataAccess );

			// コミット処理
			objDataAccess.commit();
		}
		catch( Exception e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			// データベースエラーを設定
			throw new XMOException( getMessageData( DB_ERR ) );
		}
		// 正常時空文字返却
		return "";
	}

	/**
	 * 登録処理実行メソッドです。<BR>
	 * RolesテーブルとRolesFunctionテーブルに登録処理を行います<BR>
	 * パラメータのチェックおよびトランザクションの管理は
	 * 上位メソッド内で行ってください。<BR>
	 * @param htbParam 登録情報
	 * @exception XMOException XMO独自エラー
	 * @exception SQLException DBエラーが発生した場合
	 */
	private void insertAction( Hashtable htParam, DataAccess objDataAccess )
		throws XMOException, SQLException
	{

		// 最大のRoleID取得
		String strRoleID =  getMaxRoleID(objDataAccess);
		htParam.put( ROLEID, strRoleID );

		// 権限テーブル登録処理用のデータをセットします
		Hashtable htbData = getData( htParam );
		String strSQL = objDataAccess.getInsertSQL(htbData);

		objDataAccess.execute( strSQL );

		// 権限機能テーブル登録処理用のデータをセットします
		Vector vecFunctionList = new Vector();
		try{
			// 環境ファイルからDB種別情報取得
			Environment objEnv = new Environment();
			//DB種別情報が "0" の時　MS SQLServer
			//DB種別情報が "1" の時　Oracle
			//DB種別情報が "2" の時　PostgreSQL
			//SQLServerの場合
			if ( objEnv.getDBType().equals(objEnv.DB_SQLSERVER) ) {
				vecFunctionList = (Vector)htParam.get(FUNCTION);
			//Oracleの場合
			}else if(objEnv.getDBType().equals( objEnv.DB_ORACLE )){
				vecFunctionList = (Vector)htParam.get(ORACLE_FUNCTION);
			//PostgreSQLの場合
			}else if(objEnv.getDBType().equals( objEnv.DB_POSTGRE )){
				vecFunctionList = (Vector)htParam.get(POSTGRE_FUNCTION);
			}
		}
		catch( Exception e )
		{
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
		}
		if( vecFunctionList != null ) {
			int intFunctionCount = vecFunctionList.size();
			//1RoleIDにつき複数のFunctionが存在する可能性があるので、すべてRolesFunctionテーブルに登録します
			for(int i=0; i < intFunctionCount; i++){
				String strFunction = (String)vecFunctionList.get(i);
				// RolesFunctionテーブル登録処理用のデータをセットします
				Hashtable htbData2 = new Hashtable();
				htbData2.put( ROLEID, strRoleID );
				try{
					// 環境ファイルからDB種別情報取得
					Environment objEnv = new Environment();
					//DB種別情報が "0" の時　MS SQLServer
					//DB種別情報が "1" の時　Oracle
					//DB種別情報が "2" の時　PostgreSQL
					//SQLServerの場合
					if ( objEnv.getDBType().equals(objEnv.DB_SQLSERVER) ) {
						htbData2.put( FUNCTION, strFunction );
					//Oracleの場合
					}else if(objEnv.getDBType().equals( objEnv.DB_ORACLE )){
						htbData2.put( ORACLE_FUNCTION, strFunction );
					//PostgreSQLの場合
					}else if(objEnv.getDBType().equals( objEnv.DB_POSTGRE )){
						htbData2.put( POSTGRE_FUNCTION, strFunction );
					}
				}
				catch( Exception e )
				{
					DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
				}
				strSQL = objDataAccess.getInsertSQL(htbData2, TABLE_NAME2);
				//Function登録実行
				objDataAccess.execute( strSQL );
			}
		}
	}

	/**
	 * Rolesテーブル,RolesFunctionテーブルへ登録処理を行います。<BR>
	 * 以下の情報をHashtableに格納して渡してください。<BR>
	 * なおテーブルの主キー以外を省略した場合は省略したフィールドには
	 * Null値が格納されます。
	 * <PRE>
	 *             key                     	説明
	 *          ---------------------------------------------
	 *             ROLENAME              	権限名称
	 *             DELETED                 	隠しフラグ
	 *             LEARNFLAG               	学習権限フラグ
	 *             FUNCTION                	機能(XMOID)
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 登録情報
	 * @return String 結果(正しく終了した場合のみ)
	 * @exception XMOException データベースエラーが発生した場合
	 */
	synchronized public String update( Hashtable htParam )
		throws XMOException
	{
		// 権限データがnullのとき
		if( htParam == null ) {
			DebugLog.write( this.getClass(), new Exception(), DebugLog.HIGHT );	
			// パラメータエラーをスローする
			throw new XMOException( getMessageData( PARAM_WAR ) );
		}

		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME);
		try {
			// トランザクションを開始する
			objDataAccess.trans( htParam );

			// 登録処理実行
			updateAction( htParam, objDataAccess );

			// コミット処理
			objDataAccess.commit();
		}
		catch( XMOException xe ) {
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			throw xe;
		}
		catch( SQLException e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			// データベースエラーを設定
			throw new XMOException( getMessageData( DB_ERR ) );
		}
		// 正常時空文字返却
		return "";
	}

	/**
	 * 更新処理実行メソッドです。<BR>
	 * RolesテーブルとRolesFunctionテーブルに更新処理を行います<BR>
	 * パラメータのチェックおよびトランザクションの管理は
	 * 上位メソッド内で行ってください。<BR>
	 * @param htbParam 登録情報
	 * @exception XMOException XMO独自エラー
	 * @exception SQLException DBエラーが発生した場合
	 */
	private void updateAction( Hashtable htParam, DataAccess objDataAccess )
		throws XMOException, SQLException
	{
		// 権限テーブル登録処理用のデータをセットします
		Hashtable htbData = getData( htParam );
		String strSQL = objDataAccess.getUpdateSQL( htbData );

		// 条件文の取得
		String strCondition = (String)htParam.get( CONDITION_KEY );
		if( strCondition != null ) {
			strSQL += strCondition;
		}

		objDataAccess.execute( strSQL );

		// 権限機能テーブル登録処理用のデータをセットします
		Vector vecFunctionList = new Vector();
		try{
			// 環境ファイルからDB種別情報取得
			Environment objEnv = new Environment();
			//DB種別情報が "0" の時　MS SQLServer
			//DB種別情報が "1" の時　Oracle
			//DB種別情報が "2" の時　PostgreSQL
			//SQLServerの場合
			if ( objEnv.getDBType().equals(objEnv.DB_SQLSERVER) ) {
				vecFunctionList = (Vector)htParam.get(FUNCTION);
			//Oracleの場合
			}else if(objEnv.getDBType().equals( objEnv.DB_ORACLE )){
				vecFunctionList = (Vector)htParam.get(ORACLE_FUNCTION);
			//PostgreSQLの場合
			}else if(objEnv.getDBType().equals( objEnv.DB_POSTGRE )){
				vecFunctionList = (Vector)htParam.get(POSTGRE_FUNCTION);
			}
		}
		catch( Exception e )
		{
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
		}

		if( vecFunctionList != null ) {

			// RolesFunctionテーブルからRolesIDをキーにして、削除処理を行います
			strSQL = "DELETE FROM " + TABLE_NAME2 + strCondition;

			objDataAccess.execute( strSQL );

			// インサート処理を行います
			String strRoleID = (String)htParam.get( ROLEID );
			if( strRoleID == null ) {
				strSQL = "SELECT " + ROLEID + " FROM " + TABLE_NAME + strCondition;

				ResultSet rs = objDataAccess.executeQuery( strSQL );
				if( rs.next() ) {
					strRoleID = rs.getString( ROLEID );
				}
			}
			int intFunctionCount = vecFunctionList.size();
			//1RoleIDにつき複数のFunctionが存在する可能性があるので、すべてRolesFunctionテーブルに登録します
			for(int i=0; i < intFunctionCount; i++){
				String strFunction = (String)vecFunctionList.get(i);
				// RolesFunctionテーブル登録処理用のデータをセットします
				Hashtable htbData2 = new Hashtable();
				htbData2.put( ROLEID, strRoleID );
				try{
					// 環境ファイルからDB種別情報取得
					Environment objEnv = new Environment();
					//DB種別情報が "0" の時　MS SQLServer
					//DB種別情報が "1" の時　Oracle
					//DB種別情報が "2" の時　PostgreSQL
					//SQLServerの場合
					if ( objEnv.getDBType().equals(objEnv.DB_SQLSERVER) ) {
						htbData2.put( FUNCTION, strFunction );
					//Oracleの場合
					}else if(objEnv.getDBType().equals( objEnv.DB_ORACLE )){
						htbData2.put( ORACLE_FUNCTION, strFunction );
					//PostgreSQLの場合
					}else if(objEnv.getDBType().equals( objEnv.DB_POSTGRE )){
						htbData2.put( POSTGRE_FUNCTION, strFunction );
					}
				}
				catch( Exception e )
				{
					DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
				}
				strSQL = objDataAccess.getInsertSQL(htbData2, TABLE_NAME2);
				//Function登録実行
				objDataAccess.execute( strSQL );
			}
		}
	}


	/**
	 * Roles,RolesFunctionテーブルへ削除処理を行います。<BR>
	 * 以下の情報をHashtableに格納して渡してください。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           削除条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 削除情報
	 * @return String 結果(正しく終了した場合のみ)
	 * @exception XMOException データベースエラーが発生した場合
	 */
	synchronized public String delete( Hashtable htParam )
		throws XMOException
	{
		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME);
		try {

			// トランザクションを開始する
			objDataAccess.trans( htParam );

			// 削除処理実行メソッドを実行します
			deleteAction( htParam, objDataAccess );

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

	/**
	 * 削除処理実行メソッドです。<BR>
	 * まずRolsAssignmentsから削除を行い、その後Rolesから削除をします。
	 * パラメータのチェックおよびトランザクションの管理は
	 * 上位メソッド内で行ってください。<BR>
	 * @param htbParam 削除情報
	 * @exception XMOException XMO独自エラー
	 * @exception SQLException DBエラーが発生した場合
	 */
	private void deleteAction( Hashtable htbParam, DataAccess objDataAccess )
		throws XMOException, SQLException
	{

		// 条件文の取得
		String strCondition = (String)htbParam.get( "condition_key" );

		////////////////////////////////////////////////////////////////////////
		// RoleAssignmentsの削除処理
		////////////////////////////////////////////////////////////////////////
		// 削除対象のRolesIDリストを取得します
		Vector vecRolesList = getRolesList( strCondition, objDataAccess );
		try {

			for( int i = 0; i < vecRolesList.size(); i++ ) {
				// RolesAssignmentsデータの削除をします
				// RolesAssignmentsClientクラスをインスタンス化します
				RoleAssignmentsClient RolesAss = new RoleAssignmentsClient();

				// 現在のトランザクションを共有するため使用中のコネクションインデックスを
				// 設定します
				RolesAss.setConnectionIndex( objDataAccess.getConnectionIndex() );

				// 削除条件を設定します
				RolesAss.setWhereRoleID( (String)vecRolesList.get(i) );

				// RoleAssignmentsテーブルデータ削除処理を実行
				if( !RolesAss.delete() ) {
					throw new XMOException( RolesAss.getMessageData() );
				}
			}
		}
		catch( Exception e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			throw new XMOException( getMessageData( SYSTEM_ERR ) );
		}

		////////////////////////////////////////////////////////////////////////
		// Rolesの削除処理
		////////////////////////////////////////////////////////////////////////
		// Rolesテーブルデータ削除用SQLの組み立て
		StringBuffer sbSQL1 = new StringBuffer();
		sbSQL1.append( "DELETE FROM " + TABLE_NAME );

		if( strCondition != null ) {
			sbSQL1.append( strCondition );
		}

		// Rolesテーブルデータ削除処理を実行
		objDataAccess.execute( sbSQL1.toString() );

		// RolesFunctionテーブルデータ削除用SQLの組み立て
		StringBuffer sbSQL2 = new StringBuffer();
		sbSQL2.append( "DELETE FROM " + TABLE_NAME2 );

		// 条件文の取得
		if( strCondition != null ) {
			sbSQL2.append( strCondition );
		}

		// RolesFunctionテーブルデータ削除処理を実行
		objDataAccess.execute( sbSQL2.toString() );

	}


	/**
	 * Rolesテーブルへ検索処理を行います。<BR>
	 * 以下の情報をHashtableに格納して渡してください。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           検索条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 検索情報
	 * @return String 結果(正しく終了した場合のみ)
	 * @exception XMOException データベースエラーが発生した場合
	 */
	public Vector select( Hashtable htParam )
		throws XMOException
	{
		// 人データがnullのとき
		if( htParam == null ) {
			DebugLog.write( this.getClass(), new Exception(), DebugLog.HIGHT );	
			throw new XMOException( getMessageData( PARAM_WAR ) );
		}

		// SQLの組み立て(Roles.tb)
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append( "SELECT * FROM " + TABLE_NAME );
		// 条件文の取得
		String strCondition = (String)htParam.get( "condition_key" );
		if( strCondition != null ) {
			sbSQL.append( strCondition );
		}

		// 戻り値
		Vector vecReturn = new Vector();
		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME);
		try {
			// トランザクションを開始する
			objDataAccess.trans( htParam );

			ResultSet rs = objDataAccess.executeQuery(sbSQL.toString());

			while(rs.next()) {
				String strRoleID = ChangeEncode.setChar( rs.getString( ROLEID ) );
				String strRoleName = ChangeEncode.setChar( rs.getString( ROLENAME ) );
				String strDeleted = ChangeEncode.setChar( rs.getString( DELETED ) );
				RolesData objData = new RolesData();
				objData.setRoleID( strRoleID );
				objData.setRoleName( strRoleName );
				objData.setDeleted( strDeleted );
				vecReturn.add( objData );
			}

			// 検索条件のRoleIDに該当するFunctionをRolesFunction.tbより取得する
			Vector vecFunctionList = new Vector();
			int intCount = vecReturn.size();

			for( int i = 0; i < intCount; i++ ) {
				RolesData objRolesData = (RolesData)vecReturn.get(i);
				String strRoleID = objRolesData.getRoleID();

				// SQLの組み立て(RolesFunction.tb)
				StringBuffer sbSQL2 = new StringBuffer();
				sbSQL2.append( "SELECT * FROM " + TABLE_NAME2 );
				// 条件文の組み立て
				strCondition = " WHERE " + ROLEID + "='" + StringEscapeUtils.escapeSql(strRoleID) + "'";
				sbSQL2.append( strCondition );

				// 検索実行
				rs = objDataAccess.executeQuery(sbSQL2.toString());
				while(rs.next()) {
					String strFunction = ChangeEncode.setChar( rs.getString(GET_FUNCTION) );
					// 取得したFunctionのリストをVectorに保持する
					objRolesData.addFunction( strFunction );
				}
			}

			// コミット
			objDataAccess.commit();
		}
		catch( SQLException e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ){}
			throw new XMOException( getMessageData( DB_ERR ) );
		}
		return vecReturn;
	}

	/**
	 * RoleIDのリストを取得します
	 * @param strCondition 検索条件
	 * @param objDataAccess データアクセスオブジェクト
	 * @return Vector 検索結果　権限IDリスト
	 */
	private Vector getRolesList( String strCondition, DataAccess objDataAccess )
		throws SQLException
	{
		String strSQL = "SELECT " + ROLEID + " FROM " + TABLE_NAME + " ";

		if( strCondition != null ) {
			strSQL += strCondition;
		}

		Vector vecReturn = new Vector();

		// 検索処理
		ResultSet rs = objDataAccess.executeQuery(strSQL);

		while( rs.next() ) {
			vecReturn.add( rs.getString( ROLEID ) );
		}

		return vecReturn;
	}


	/**
	* 最大のRoleID取得
	* @return String 最大RoleID
	*/

	private String getMaxRoleID(DataAccess objDataAccess)
		throws SQLException
	{
		String strSQL = "";
		try
		{
			// 環境ファイルからDB種別情報取得
			Environment objEnv = new Environment();
			//DB種別情報が "0" の時　MS SQLServer
			//DB種別情報が "1" の時　Oracle
			//DB種別情報が "2" の時　PostgreSQL
			//SQLServerの場合
			if ( objEnv.getDBType().equals(objEnv.DB_SQLSERVER) ) {
				strSQL = "select MAX(CONVERT(INT,RoleID)) + 1 as maxroleid from Roles";
			}
			//Oracleの場合
			else if( objEnv.getDBType().equals(objEnv.DB_ORACLE) ) {
				strSQL = "select MAX (TO_NUMBER (RoleID) ) + 1 as maxroleid from Roles";
			//PostgreSQLの場合
			}else if( objEnv.getDBType().equals(objEnv.DB_POSTGRE) ) {
				strSQL = "select MAX (TO_NUMBER (RoleID,'9999999999') ) + 1 as maxroleid from Roles";
			}
		}
		catch( Exception e )
		{
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
		}
		Vector vecList = new Vector();
		String strMaxRoleID = "";

		DebugLog.write( this.getClass(), strSQL, DebugLog.ROW );
		ResultSet rs = objDataAccess.executeQuery(strSQL);

		while(rs.next()) {
			int intTemp = 0;
			intTemp = rs.getInt( "maxroleid" );
			strMaxRoleID = new Integer(intTemp).toString();
		}
		return strMaxRoleID;
	}

	/**
	 * XmoRelateionテーブルへ登録処理を行います。<BR>
	 * 以下の情報をHashtableに格納して渡してください。<BR>
	 * なおテーブルの主キー以外を省略した場合は省略したフィールドには
	 * Null値が格納されます。
	 * <PRE>
	 *             key                     	説明
	 *          ---------------------------------------------
	 *             XMOID					XMOID
	 *             RELATEDID               	関連XMOID
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 登録情報
	 * @return String 結果(正しく終了した場合のみ)
	 * @exception XMOException データベースエラーが発生した場合
	 */
	synchronized public String insertXmoRelation( Hashtable htParam )
		throws XMOException
	{
		// XmoRelationデータがnullのとき
		if( htParam == null ) {
			DebugLog.write( this.getClass(), new Exception(), DebugLog.HIGHT );	
			// パラメータエラーをスローする
			throw new XMOException( getMessageData( PARAM_WAR ) );
		}

		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME3);
		try {
			// トランザクションを開始する
			objDataAccess.trans( htParam );

			// 登録処理実行
			insertXmoRelationAction( htParam, objDataAccess );

			// コミット処理
			objDataAccess.commit();
		}
		catch( Exception e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			// データベースエラーを設定
			throw new XMOException( getMessageData( DB_ERR ) );
		}
		// 正常時空文字返却
		return "";
	}

	/**
	 * XmoRelation登録処理実行メソッドです。<BR>
	 * XmoRelationテーブルに登録処理を行います<BR>
	 * パラメータのチェックおよびトランザクションの管理は
	 * 上位メソッド内で行ってください。<BR>
	 * @param htbParam 登録情報
	 * @exception XMOException XMO独自エラー
	 * @exception SQLException DBエラーが発生した場合
	 */
	private void insertXmoRelationAction( Hashtable htParam, DataAccess objDataAccess )
		throws XMOException, SQLException
	{
		// XmoIDを取得します
		String strXmoID = (String)htParam.get(XMOID);
		// XmoRelationテーブル登録処理用のデータをセットします
		Vector vecRelationList = (Vector)htParam.get(RELATEDID);
		if( vecRelationList != null ) {
			int intRelationCount = vecRelationList.size();
			// 1XmoIDにつき複数のRelationIDが存在する可能性があるので、すべてXmoRelationテーブルに登録します
			for(int i=0; i < intRelationCount; i++){
				String strRelation = (String)vecRelationList.get(i);
				// XmoRelationテーブル登録処理用のデータをセットします
				Hashtable htbData = new Hashtable();
				htbData.put( XMOID, strXmoID );
				htbData.put( RELATEDID, strRelation );
				String strSQL = objDataAccess.getInsertSQL(htbData, TABLE_NAME3);
				//Function登録実行
				objDataAccess.execute( strSQL );
			}
		}
	}

	/**
	 * XmoRelationテーブルへ更新処理を行います。<BR>
	 * 以下の情報をHashtableに格納して渡してください。<BR>
	 * なおテーブルの主キー以外を省略した場合は省略したフィールドには
	 * Null値が格納されます。
	 * <PRE>
	 *             key                     	説明
	 *          ---------------------------------------------
	 *             XMOID               	    XMOID
	 *             RELATEDID                関連XMOID
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 更新情報
	 * @return String 結果(正しく終了した場合のみ)
	 * @exception XMOException データベースエラーが発生した場合
	 */
	synchronized public String updateXmoRelation( Hashtable htParam )
		throws XMOException
	{
		// XmoRelationデータがnullのとき
		if( htParam == null ) {
			DebugLog.write( this.getClass(), new Exception(), DebugLog.HIGHT );	
			// パラメータエラーをスローする
			throw new XMOException( getMessageData( PARAM_WAR ) );
		}

		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME3);
		try {
			// トランザクションを開始する
			objDataAccess.trans( htParam );

			// 登録処理実行
			updateXmoRelationAction( htParam, objDataAccess );

			// コミット処理
			objDataAccess.commit();
		}
		catch( XMOException xe ) {
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			throw xe;
		}
		catch( SQLException e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			// データベースエラーを設定
			throw new XMOException( getMessageData( DB_ERR ) );
		}
		// 正常時空文字返却
		return "";
	}

	/**
	 * XmoRelation更新処理実行メソッドです。<BR>
	 * XmoRelationテーブルに更新処理を行います<BR>
	 * パラメータのチェックおよびトランザクションの管理は
	 * 上位メソッド内で行ってください。<BR>
	 * @param Hashtable 更新情報
	 * @param DataAccess データアクセスクラス
	 * @exception XMOException XMO独自エラー
	 * @exception SQLException DBエラーが発生した場合
	 */
	private void updateXmoRelationAction( Hashtable htParam, DataAccess objDataAccess )
		throws XMOException, SQLException
	{
		// 条件文の取得
		String strCondition = (String)htParam.get( CONDITION_KEY );
		// XmoRelationテーブル登録処理用のデータをセットします
		Vector vecRelationList = (Vector)htParam.get(RELATEDID);
		if( vecRelationList != null ) {

			// XmoRelationテーブルからXmoIDをキーにして、削除処理を行います
			String strSQL = "DELETE FROM " + TABLE_NAME3 + strCondition;

			objDataAccess.execute( strSQL );

			// インサート処理を行います
			String strXmoID = (String)htParam.get( XMOID );
			if( strXmoID == null ) {
				strSQL = "SELECT " + XMOID + " FROM " + TABLE_NAME3 + strCondition;

				ResultSet rs = objDataAccess.executeQuery( strSQL );
				if( rs.next() ) {
					strXmoID = rs.getString( XMOID );
				}
			}
			int intRelationCount = vecRelationList.size();
			// 1XmoIDにつき複数のRelationIDが存在する可能性があるので、すべてXmoRelationテーブルに登録します
			for(int i=0; i < intRelationCount; i++){
				String strRelation = (String)vecRelationList.get(i);
				// XmoRelationテーブル登録処理用のデータをセットします
				Hashtable htbData = new Hashtable();
				htbData.put( XMOID, strXmoID );
				htbData.put( RELATEDID, strRelation );
				strSQL = objDataAccess.getInsertSQL(htbData, TABLE_NAME3);
				//Function登録実行
				objDataAccess.execute( strSQL );
			}
		}
	}


	/**
	 * XmoRelationテーブルへ削除処理を行います。<BR>
	 * 以下の情報をHashtableに格納して渡してください。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           削除条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 削除情報
	 * @return String 結果(正しく終了した場合のみ)
	 * @exception XMOException データベースエラーが発生した場合
	 */
	synchronized public String deleteXmoRelation( Hashtable htParam )
		throws XMOException
	{
		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME3);
		try {

			// トランザクションを開始する
			objDataAccess.trans( htParam );

			// 削除処理実行メソッドを実行します
			deleteXmoRelationAction( htParam, objDataAccess );

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

	/**
	 * XmoRelation削除処理実行メソッドです。<BR>
	 * パラメータのチェックおよびトランザクションの管理は
	 * 上位メソッド内で行ってください。<BR>
	 * @param htbParam 削除情報
	 * @exception XMOException XMO独自エラー
	 * @exception SQLException DBエラーが発生した場合
	 */
	private void deleteXmoRelationAction( Hashtable htbParam, DataAccess objDataAccess )
		throws XMOException, SQLException
	{

		// 条件文の取得
		String strCondition = (String)htbParam.get( "condition_key" );
		// XmoRelationテーブルデータ削除用SQLの組み立て
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append( "DELETE FROM " + TABLE_NAME3 );

		if( strCondition != null ) {
			sbSQL.append( strCondition );
		}

		// XmoRelationテーブルデータ削除処理を実行
		objDataAccess.execute( sbSQL.toString() );

	}

	/**
	 * XmoRelationテーブルへ検索処理を行います。<BR>
	 * 以下の情報をHashtableに格納して渡してください。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           検索条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 検索情報
	 * @return String 結果(正しく終了した場合のみ)
	 * @exception XMOException データベースエラーが発生した場合
	 */
	public Vector selectXmoRelation( Hashtable htParam )
		throws XMOException
	{
		// XmoRelationデータがnullのとき
		if( htParam == null ) {
			DebugLog.write( this.getClass(), new Exception(), DebugLog.HIGHT );	
			throw new XMOException( getMessageData( PARAM_WAR ) );
		}

		// SQLの組み立て(XmoRelation.tbl)
		StringBuffer sbSQL = new StringBuffer();
		sbSQL.append( "SELECT * FROM " + TABLE_NAME3 );
		// 条件文の取得
		String strCondition = (String)htParam.get( "condition_key" );
		if( strCondition != null ) {
			sbSQL.append( strCondition );
		}
		
		// 戻り値
		Vector vecReturn = new Vector();
		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME3);
		try {
			// トランザクションを開始する
			objDataAccess.trans( htParam );

			ResultSet rs = objDataAccess.executeQuery(sbSQL.toString());

			while(rs.next())
			{
				String strXmoID = ChangeEncode.setChar( rs.getString( XMOID ) );
				RolesData objData = new RolesData();
				objData.setXmoID( strXmoID );
				vecReturn.add( objData );
			}
			
			// 検索条件のXmoIDに該当するRelateionIDをXmoRelateion.tblより取得する
			Vector vecRelationList = new Vector();
			int intCount = vecReturn.size();

			for( int i = 0; i < intCount; i++ )
			{
				RolesData objRolesData = (RolesData)vecReturn.get(i);
				String strXmoID = objRolesData.getXmoID();

				// SQLの組み立て(RolesFunction.tb)
				StringBuffer sbSQL2 = new StringBuffer();
				sbSQL2.append( "SELECT * FROM " + TABLE_NAME3 );
				// 条件文の組み立て
				strCondition = " WHERE " + XMOID + "='" + StringEscapeUtils.escapeSql(strXmoID) + "'";
				sbSQL2.append( strCondition );

				// 検索実行
				rs = objDataAccess.executeQuery(sbSQL2.toString());
				while(rs.next()) {
					String strRelation = ChangeEncode.setChar( rs.getString( RELATEDID ) );
					// 取得したRelationIDのリストをVectorに保持する
					objRolesData.addRelatedID( strRelation );
				}
			}

			// コミット
			objDataAccess.commit();
		}
		catch( SQLException e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ){}
			throw new XMOException( getMessageData( DB_ERR ) );
		}
		return vecReturn;
	}

	/**
	 * Functionを元にロールIDを検索します。<BR>
	 * @param htData 検索情報
	 * @return Vector 結果(正しく終了した場合のみ)
	 * @exception XMOException データベースエラーが発生した場合
	 */
	public Vector selectFunction( Hashtable htParam )
		throws XMOException
	{
		// XmoRelationデータがnullのとき
		if( htParam == null ) {
			DebugLog.write( this.getClass(), new Exception(), DebugLog.HIGHT );	
			throw new XMOException( getMessageData( PARAM_WAR ) );
		}

		Vector vecFuncList = (Vector)htParam.get(TARGET_ID);
		StringBuffer sbSQL = new StringBuffer();
		try
		{
			// 環境ファイルからDB種別情報取得
			Environment objEnv = new Environment();
			//DB種別情報が "0" の時　MS SQLServer
			//DB種別情報が "1" の時　Oracle
			//DB種別情報が "2" の時　PostgreSQL
			//SQLServerの場合
			if ( objEnv.getDBType().equals(objEnv.DB_SQLSERVER) ) {
				// SQLの組み立て(XmoRelation.tbl)
				sbSQL.append( "SELECT DISTINCT(Roles.RoleID) AS ROLEID ");
				sbSQL.append( "FROM Roles INNER JOIN RolesFunction ON Roles.RoleID = RolesFunction.RoleID WHERE " );
				
				for(int i=0; i<vecFuncList.size(); i++){
					if ( i == 0 ){
						sbSQL.append( "[FUNCTION]=" );
						sbSQL.append( (String)vecFuncList.get(i) );
					}
					else{
						sbSQL.append( " OR [FUNCTION]=" );
						sbSQL.append( (String)vecFuncList.get(i) );
					}
				}
			//Oracleの場合 OR PostgreSQLの場合
			}else if (objEnv.getDBType().equals( objEnv.DB_ORACLE ) || objEnv.getDBType().equals( objEnv.DB_POSTGRE )){
				// SQLの組み立て(XmoRelation.tbl)
				sbSQL.append( "SELECT DISTINCT(Roles.RoleID) AS ROLEID ");
				sbSQL.append( "FROM Roles INNER JOIN RolesFunction ON Roles.RoleID = RolesFunction.RoleID WHERE " );
				
				for(int i=0; i<vecFuncList.size(); i++){
					if ( i == 0 ){
						sbSQL.append( "FUNCTION=" );
						sbSQL.append( (String)vecFuncList.get(i) );
					}
					else{
						sbSQL.append( " OR FUNCTION=" );
						sbSQL.append( (String)vecFuncList.get(i) );
					}
				}
			}
		}
		catch( Exception e )
		{
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
		}

		// 戻り値
		Vector vecReturn = new Vector();
		Vector vecList   = new Vector();
		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess();
		try {
			// トランザクションを開始する
			objDataAccess.trans();

			DebugLog.write( this.getClass(), sbSQL.toString(), DebugLog.ROW );
			ResultSet rs = objDataAccess.executeQuery(sbSQL.toString());

			while(rs.next())
			{
				String strRoleID = ChangeEncode.setChar( rs.getString( ROLEID ) );
				vecList.add( strRoleID );
			}
			
			// コミット
			objDataAccess.commit();
			
			String[] strList = new String[vecList.size()];
			vecList.copyInto( strList );
			vecReturn.add( strList );
		}
		catch( SQLException e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ){}
			throw new XMOException( getMessageData( DB_ERR ) );
		}
		return vecReturn;
	}


	/**
	 * 登録、更新処理時のデータを組み立てます
	 * @param htData
	 * @return Hashtable
	 */
	private Hashtable getData( Hashtable htbParam ) {
		Hashtable htbData = new Hashtable();
		putData( htbData, htbParam, ROLEID );
		putData( htbData, htbParam, ROLENAME );
		putData( htbData, htbParam, DELETED );
		return htbData;
	}

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

	/**
	 * メッセージオブジェクトを作成します
	 * @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;
	}

//	ADD 2005/02/02 START MASUDA [LO一覧(履修済み/中)対応]
	/**
	 * RoleAssignmentsテーブルへ検索処理を行います。<BR>
	 * 以下の情報をHashtableに格納して渡してください。
	 * <PRE>
	 *             key                     説明
	 *          ---------------------------------------------
	 *             CONDITION_KEY           検索条件文
	 *          ---------------------------------------------
	 * </PRE>
	 * @param htData 検索情報
	 * @return String 結果(正しく終了した場合のみ)
	 * @exception XMOException データベースエラーが発生した場合
	 */
	public Vector selectRolesFunction( String strRoleID )
		throws XMOException
	{

		// 権限割当データがnullのとき
		if( strRoleID == null ) {
			DebugLog.write( this.getClass(), new Exception(), DebugLog.HIGHT );	
			throw new XMOException( getMessageData( PARAM_WAR ) );
		}

		// 戻り値
		Vector vecRoleIDList = new Vector();

		// データアクセスクラスをインスタンス化します
		DataAccess objDataAccess = new DataAccess(TABLE_NAME2);
		try {
			// トランザクションを開始する
			objDataAccess.trans();

			// SQL組み立て
			StringBuffer sbSQL = new StringBuffer();

			// 環境ファイルからDB種別情報取得
			Environment objEnv = new Environment();
			//DB種別情報が "0" の時　MS SQLServer
			//DB種別情報が "1" の時　Oracle
			//DB種別情報が "2" の時　PostgreSQL
			//SQLServerの場合
			if ( objEnv.getDBType().equals(objEnv.DB_SQLSERVER) ) {
				sbSQL.append("SELECT " + FUNCTION + " FROM ");
			//Oracleの場合
			}else if(objEnv.getDBType().equals( objEnv.DB_ORACLE )){
				sbSQL.append("SELECT " + ORACLE_FUNCTION + " FROM ");
			//PostgreSQLの場合
			}else if(objEnv.getDBType().equals( objEnv.DB_POSTGRE )){
				sbSQL.append("SELECT " + POSTGRE_FUNCTION + " FROM ");
			}
			sbSQL.append(TABLE_NAME2);
			sbSQL.append(" WHERE ");
			sbSQL.append( ROLEID );
			sbSQL.append( "='" );
			sbSQL.append( StringEscapeUtils.escapeSql(strRoleID) );
			sbSQL.append( "'" );
			
			// 検索処理を実行します
			ResultSet rs = objDataAccess.executeQuery(sbSQL.toString());
			while(rs.next()) {
				vecRoleIDList.add(rs.getString( "FUNCTION" )) ;
			}
			// コミット
			objDataAccess.commit();
		}
		catch( SQLException e ) {
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ) {}
			// データベースエラーを設定
			throw new XMOException( getMessageData( DB_ERR ) );
		}
		catch( Exception e )
		{
			DebugLog.write( this.getClass(), e, DebugLog.HIGHT );
		}


		return vecRoleIDList;
	}
//	ADD 2005/02/02 END MASUDA

}

