/*******************************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
********************************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*   モジュール名    ：JECC0081D010TPMA
*   ソースファイル名：JECC0081D010TPMA.java
*   作成者          ：富士通
*   日付            ：2011年05月29日
*＜機能概要＞
*   主処理(共通)<BR>
*   ワンタイムパスワード登録独自処理部品クラス.
*＜修正履歴＞
*   バージョン  修正日      修正者      修正内容
*   v1.00.00    2011/05/29  富士通      新規作成
*   v32.00.00   2017/05/26  FJ)河邊    【OM-2017-0000488】オープンカーソルエラー
*
**********************************************************************/

package eo.ejb.cbs.mainproc;


import java.rmi.server.UID;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.fujitsu.futurity.model.base.CAANConnectionMgr;
import com.fujitsu.futurity.model.base.CAANJDBCUtil;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.ejb.common.JSYejbConnection;
import com.fujitsu.futurity.model.ejb.common.StatusCodes;
import com.fujitsu.futurity.model.ejb.common.fw.AgentDispatchContext;
import com.fujitsu.futurity.model.ejb.common.fw.TemplateMainHandler;

import eo.common.util.JCCFrameworkException;
import eo.ejb.cbm.entity.CC0081ETMsg;
import eo.ejb.cbm.entity.JSYejbCC0081ETDA;
import eo.ejb.cbs.cbsmsg.ECC0081D010CBSMsg;
import eo.ejb.common.JCCModelCommon;
import eo.ejb.common.JPCejbSysParam;

import com.fujitsu.futurity.common.JCMConstants;


/**
 * <p>
 * ワンタイムパスワード登録独自処理部品クラスです。
 * </p>
 * @author 富士通
 */
public class JECC0081D010TPMA implements TemplateMainHandler {

	/**
	 * コンストラクタ.
	 */
	public JECC0081D010TPMA()
	{
		super();
	}
	
	/**
	 * ワンタイムパスワード登録.
	 * ユーザー情報の確認、ワンタイムパスワードの発行、<BR>
	 * ワンタイムパスワード管理テーブルへの登録を行なう。
	 * @param inMsg 
	 * @param inContext 
	 * @throws JCCFrameworkException 
	 */
	public static void invoke(CAANMsg inCBSMsg, AgentDispatchContext inContext) throws Exception
	{
		// サービスIFの呼出区分を取得
		String callType = (String)inContext.getClientHashMapObj().get(JCMConstants.CALL_TYPE_KEY);
		
		// ユーザID、組織コード、立場コードをローカル変数にコピー
		String userID = inCBSMsg.getString(ECC0081D010CBSMsg.USER_ID);
		String orgCd = inCBSMsg.getString(ECC0081D010CBSMsg.ORG_CD);
		String posCd = inCBSMsg.getString(ECC0081D010CBSMsg.POSITION_CD);
		
		//----------------------------------------------------
		// 単関連チェック処理 (20110823 FST add)
		//----------------------------------------------------
		if(chkItemRelation(inCBSMsg, callType) == false)
		{
			return;
		}
		//-------------------------------------------------------------------------------------
		// 外部呼出の場合はユーザ／組織／立場全て無しの場合APLConstから取得 (20110823 FST add)
		//-------------------------------------------------------------------------------------
		// 2011/02/21 ユーザーIDなしのパターンは許容しない start
//		if("3".equals(callType) == true)
//		{
//			if(chkNull(userID) == true && chkNull(orgCd) == true && chkNull(posCd) == true)
//			{
//				//アプリケーションプロパティファイルからユーザーIDを取得
//				userID = JCCModelCommon.getApplicationConst("OPW_DEFAULT_USER_ID");
//				if(chkNull(userID))
//				{
//					throw new JCCFrameworkException("アプリケーションプロパティファイルにデフォルトユーザIDが設定されていません。");
//				}
//			}
//		}
		// 2011/02/21 ユーザーIDなしのパターンは許容しない end
		//----------------------------------------------------
		// ユーザー情報の確認
		//----------------------------------------------------
		// Connection の取得
		Connection con = JSYejbConnection.getConnection("ZM_M_USER");
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		// 運用日付の取得 2012/02/21 スキーマ変更対応(ユーザーの有効期限) start
		String opeDate = JCCModelCommon.getOpeDate(inCBSMsg, null);
		// 2012/02/21 end
		
		String oneTimePasswordUid = "";
		try
		{
			// SQL文の組立て
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append(" SELECT ")
					.append("   COUNT(*) ")
					.append(" FROM  ZM_M_USER ZM0051 ")
					.append(" WHERE ZM0051.USER_ID = ? ")
					//2012/02/21 スキーマ変更対応(ユーザーの有効期限) start
					.append(" AND ZM0051.USER_TSTAYMD <= ? ")
					.append(" AND ZM0051.USER_TENDYMD >= ? ")
					//2012/02/21 スキーマ変更対応(ユーザーの有効期限) end
					.append(" AND   ZM0051.MK_FLG = '0' ");
			
			pstmt = con.prepareStatement(sql_Buff.toString());
			
			// inCBSMsgからオペレーターIDを取得して設定
			CAANJDBCUtil.setParam(pstmt, 1, userID);
			
			// 運用日付の設定 2011/02/21 start
			CAANJDBCUtil.setParam(pstmt, 2, opeDate);
			CAANJDBCUtil.setParam(pstmt, 3, opeDate);
			// 2011/02/21 end
			
			// SQL実行
			rs = pstmt.executeQuery();
			
			// データが取得できなかった場合
			if (rs.next())
			{
				if ("0".equals(rs.getString("COUNT(*)")))
				{
					// inCBSMsg（ユーザーIDエラー）に"EA"を設定
					inCBSMsg.set(ECC0081D010CBSMsg.USER_ID_ERR, "EA");
					// inCBSMsg（ステータス）に「関連チェックでエラー」を設定
					inCBSMsg.set(ECC0081D010CBSMsg.STATUS, StatusCodes.RELATION_ERR);
					return;
				}
			}
			
			
			//-------------------------------------------------------------------------------------------------
			// 外部呼出の場合、ユーザーIDのみの指定ならば組織／立場コードをテーブルから取得 (20110823 FST add)
			//-------------------------------------------------------------------------------------------------
			if("3".equals(callType) == true)
			{
				// 2011/02/21 組織、立場が指定されていない場合の判定方法、エラー条件を変更 start
				//if(chkNull(userID) == false && chkNull(orgCd) == true && chkNull(posCd) == true)
				if(chkNull(posCd) == true)
				{
					// SQL文の組立て
					StringBuffer selectCode = new StringBuffer();
					selectCode.append("SELECT ");
					selectCode.append("ZM0051.USER_ID, ");
					selectCode.append("ZM0051.SHUMU_SHOZK_ORG_CD, ");
					selectCode.append("ZM0051.SHUMU_SHOZK_POSITION_CD  ");
					selectCode.append("FROM ");
					selectCode.append("ZM_M_USER ZM0051 ");
					selectCode.append("WHERE ");
					selectCode.append("ZM0051.USER_ID = ? " );
					//2012/02/21 スキーマ変更対応(ユーザーの有効期限) start
					selectCode.append("AND ZM0051.USER_TSTAYMD <= ? ");
					selectCode.append("AND ZM0051.USER_TENDYMD >= ? ");
					//2012/02/21 スキーマ変更対応(ユーザーの有効期限) end
					selectCode.append("AND ");
					selectCode.append("MK_FLG = '0'");
					
					//2012/03/21 prepareStatementをクローズする start
					if(null != pstmt)
					{
						pstmt.close();
					}
					//2012/03/21 prepareStatementをクローズする end

					pstmt = con.prepareStatement(selectCode.toString());
					
					// バインド変数にユーザーIDをセット
					CAANJDBCUtil.setParam(pstmt, 1, userID);
					
					// 運用日付の設定 2011/02/21 start
					CAANJDBCUtil.setParam(pstmt, 2, opeDate);
					CAANJDBCUtil.setParam(pstmt, 3, opeDate);
					// 2011/02/21 end
					
					//2012/03/21 ResultSetをクローズする start
					if(null != rs)
					{
						rs.close();
					}
					//2012/03/21 ResultSetをクローズする start
					
					// SQL実行
					rs = pstmt.executeQuery();
					// 取得件数が0件の場合
					if (rs.next() == false)
					{
						// ユーザーID関連チェックエラー"EA"
						inCBSMsg.set(ECC0081D010CBSMsg.USER_ID_ERR, "EA");
						inCBSMsg.set(ECC0081D010CBSMsg.STATUS, StatusCodes.RELATION_ERR);
						return;
					}
					
					// 組織コードと立場コードを取得
					// 2011/02/21 組織コードは指定入力パラメータで指定なしの場合DBから取得 start
					if(chkNull(orgCd) == true)
					{
						orgCd = rs.getString("SHUMU_SHOZK_ORG_CD");
					}
					// 2011/02/21 end
					posCd = rs.getString("SHUMU_SHOZK_POSITION_CD");
					
					// 組織コード関連チェックエラー"EB"
					if(chkNull(orgCd) == true)
					{
						inCBSMsg.set(ECC0081D010CBSMsg.ORG_CD_ERR, "EB");
						inCBSMsg.set(ECC0081D010CBSMsg.STATUS, StatusCodes.RELATION_ERR);
						return;
					}
					// 立場コード関連チェックエラー"EC"
					if(chkNull(posCd) == true)
					{
						inCBSMsg.set(ECC0081D010CBSMsg.POSITION_CD_ERR, "EC");
						inCBSMsg.set(ECC0081D010CBSMsg.STATUS, StatusCodes.RELATION_ERR);
						return;
					}
				}
				// 2011/02/21 組織、立場が指定されていない場合の判定方法を変更 end
			}
			//----------------------------------------------------
			// ワンタイムパスワード発行
			//----------------------------------------------------
// OM-2017-0000488 2017/05/26 ADD START
			if (con != null)
			{
				CAANConnectionMgr.getInstance().close(con);
			}
// OM-2017-0000488 2017/05/26 ADD END
			con = JSYejbConnection.getConnection(CC0081ETMsg.getTableName());
			
			JPCejbSysParam reTry = new JPCejbSysParam();
			// システムパラメータ分類コード、システムパラメータID、設定値1を引数にリトライ回数を取得
			String rtCnt = reTry.getParam("ONE_TIME_PASSWORD", "RETRY_COUNT", JPCejbSysParam.PARAM1);
			
			// SQL文の組立て
			sql_Buff.delete(0,sql_Buff.length());
			sql_Buff.append(" SELECT ")
					.append("   COUNT(*) ")
					.append(" FROM  CC_T_ONET_PWD CC0081 ")
					.append(" WHERE CC0081.ONET_PWD = ? ")
					.append(" AND   CC0081.OUT_SYS_CD = ? ");
			
			
			//2012/03/21 prepareStatementをクローズする start
			if(null != pstmt)
			{
				pstmt.close();
			}
			//2012/03/21 prepareStatementをクローズする end
			pstmt = con.prepareStatement(sql_Buff.toString());
			
			int reTryCont = Integer.parseInt(rtCnt);
			boolean retryflg = false;
			// リトライ回数分処理
			for (int i = 0; i < reTryCont; i++)
			{
				// ワンタイムパスワードの生成
				oneTimePasswordUid = new UID().toString(); 
				
				// ワンタイムパスワードの重複確認
				// 生成したワンタイムパスワードを設定
				CAANJDBCUtil.setParam(pstmt, 1, oneTimePasswordUid);
				// inCBSMsgからシステムコードを取得して設定
				CAANJDBCUtil.setParam(pstmt, 2, inCBSMsg.getString(ECC0081D010CBSMsg.SYSID));
				
				//2012/03/21 ResultSetをクローズする start
				if(null != rs)
				{
					rs.close();
				}
				//2012/03/21 ResultSetをクローズする start
				
				// SQL実行
				rs = pstmt.executeQuery();
				
				// 重複が見つからなかった場合
				if (rs.next())
				{
					if ("0".equals(rs.getString("COUNT(*)")))
					{
						retryflg = true;
						break;
					}
				}
			}
			// リトライ回数分処理を繰り返しても、重複の無いワンタイムパスワードを取得できない場合
			if (!retryflg)
			{
				// inCBSMsg（ユーザーIDエラー）に"EA"を設定
				inCBSMsg.set(ECC0081D010CBSMsg.ONE_TIME_PWD_ERR, "EA");
				// inCBSMsg（ステータス）に「関連チェックでエラー」を設定
				inCBSMsg.set(ECC0081D010CBSMsg.STATUS, StatusCodes.RELATION_ERR);
				return;
			}
		}
		catch (NumberFormatException ne)
		{
			throw new JCCFrameworkException("リトライ回数の数値変換に失敗しました。", ne);
		}
		catch (SQLException e)
		{
				throw new JCCFrameworkException(e);
		}
		finally
		{
			if (rs != null)
			{
				rs.close();
			}
			if (pstmt != null)
			{
				pstmt.close();
			}
// OM-2017-0000488 2017/05/26 ADD START
			if (con != null)
			{
				CAANConnectionMgr.getInstance().close(con);
			}
// OM-2017-0000488 2017/05/26 ADD END
		}
		
		
		//----------------------------------------------------
		// ワンタイムパスワード管理テーブルへの登録
		//----------------------------------------------------
		try
		{
			// ETMsgを新規に作成
			CAANMsg inETMsg = new CAANMsg("eo.ejb.cbm.entity.CC0081ETMsg");
			String sys_dtm = JCCModelCommon.getSysDateTimeStamp();
			
			// 生成したETMsgに以下の値を設定
			// イベントID
			inETMsg.set(CC0081ETMsg.EVENTID, "ICC0081D001");
			// テンプレートID
			inETMsg.set(CC0081ETMsg.TEMPLATEID, inCBSMsg.getString(ECC0081D010CBSMsg.TEMPLATEID));
			// 識別コード
			inETMsg.set(CC0081ETMsg.IDENTIFYCD, inCBSMsg.getString(ECC0081D010CBSMsg.IDENTIFYCD));
			// ステータス
			inETMsg.set(CC0081ETMsg.STATUS, inCBSMsg.getInt(ECC0081D010CBSMsg.STATUS));
			// オペレータID
			inETMsg.set(CC0081ETMsg.OPERATORID, inCBSMsg.getString(ECC0081D010CBSMsg.OPERATORID));
			// 運用日付
			inETMsg.set(CC0081ETMsg.OPERATEDATE, inCBSMsg.getString(ECC0081D010CBSMsg.OPERATEDATE));
			// 運用日時
			inETMsg.set(CC0081ETMsg.OPERATEDATETIME, inCBSMsg.getString(ECC0081D010CBSMsg.OPERATEDATETIME));
			// 権限制御用項目
			inETMsg.set(CC0081ETMsg.AC_GROUP_CD, inCBSMsg.getString(ECC0081D010CBSMsg.AC_GROUP_CD));
			// 機能コード
			inETMsg.set(CC0081ETMsg.FUNC_CODE, inCBSMsg.getString(ECC0081D010CBSMsg.FUNC_CODE));
			// ワンタイムパスワード
			inETMsg.set(CC0081ETMsg.ONET_PWD, oneTimePasswordUid);
			// 外部システムコード
			inETMsg.set(CC0081ETMsg.OUT_SYS_CD, inCBSMsg.getString(ECC0081D010CBSMsg.SYSID));
			// ユーザID
			inETMsg.set(CC0081ETMsg.USER_ID, userID);
			// 組織コード
			inETMsg.set(CC0081ETMsg.ORG_CD, orgCd);
			// 立場コード
			inETMsg.set(CC0081ETMsg.POSITION_CD, posCd);
			// 登録年月日時分秒
			inETMsg.set(CC0081ETMsg.ADD_DTM, sys_dtm);
			// 登録オペレータアカウント
			inETMsg.set(CC0081ETMsg.ADD_OPEACNT, inCBSMsg.getString(ECC0081D010CBSMsg.OPERATORID));
			// 更新年月時分秒
			inETMsg.set(CC0081ETMsg.UPD_DTM, sys_dtm);
			// 更新オペレータアカウント
			inETMsg.set(CC0081ETMsg.UPD_OPEACNT, inCBSMsg.getString(ECC0081D010CBSMsg.OPERATORID));
			// 無効フラグ
			inETMsg.set(CC0081ETMsg.MK_FLG, "0");
			
			JSYejbCC0081ETDA addETMsg = new JSYejbCC0081ETDA();
			// 登録処理の実行
			addETMsg.invoke(inETMsg, inContext);
			
			
			//----------------------------------------------------
			// 各項目の設定
			//----------------------------------------------------
			// ワンタイムパスワード
			inCBSMsg.set(ECC0081D010CBSMsg.ONE_TIME_PWD, oneTimePasswordUid);
			// 登録年月日時分秒
			inCBSMsg.set(ECC0081D010CBSMsg.ADD_DTM, sys_dtm);
			// 登録オペレータアカウント
			inCBSMsg.set(ECC0081D010CBSMsg.ADD_OPEACNT, inCBSMsg.getString(ECC0081D010CBSMsg.OPERATORID));
			// 更新年月日時分秒
			inCBSMsg.set(ECC0081D010CBSMsg.UPD_DTM, sys_dtm);
			// 更新オペレータアカウント
			inCBSMsg.set(ECC0081D010CBSMsg.UPD_OPEACNT, inCBSMsg.getString(ECC0081D010CBSMsg.OPERATORID));
		}
		catch (Exception ex)
		{
			throw new JCCFrameworkException(ex);
		}
	}
	
	
	/**
	 * パラメータの単関連チェックを行う(20110823 FST add)
	 * 
	 * @param inMsg 
	 * @param callType 呼出区分
	 * @return boolean
	 */
	private static boolean chkItemRelation(CAANMsg inCBSMsg, String callType)
	{
		boolean state = true;
		
		// チェックパラメータの取得
		String userID = inCBSMsg.getString(ECC0081D010CBSMsg.USER_ID);
		String orgCd = inCBSMsg.getString(ECC0081D010CBSMsg.ORG_CD);
		String posCd = inCBSMsg.getString(ECC0081D010CBSMsg.POSITION_CD);
		
		// 外部システムからの呼出の場合
		if("3".equals(callType) == true)
		{
			// 組織コードを指定している場合はユーザIDと立場コードは必須
			// 2011/02/21 ユーザーと組織のみの指定は許容する start
//			if(chkNull(orgCd) == false)
//			{
//				if(chkNull(userID) == true || chkNull(posCd) == true)
//				{
//					inCBSMsg.set(ECC0081D010CBSMsg.ORG_CD_ERR, "E1");
//					return false;
//				}
//			}
			// 2011/02/21 ユーザーと組織のみの指定は許容する end
			
			// 立場コードを指定している場合はユーザIDと組織コードは必須
			if(chkNull(posCd) == false)
			{
				if(chkNull(userID) == true || chkNull(orgCd) == true)
				{
					inCBSMsg.set(ECC0081D010CBSMsg.POSITION_CD_ERR, "E2");
					return false;
				}
			}
		}
		// 外部呼出しではない場合
		else
		{
			// ユーザID、立場コード、組織コード全てが必須
			// 2011/02/21 ユーザーIDは必須チェックに変更 start
			//if(chkNull(userID) == true)
			//{
			//	inCBSMsg.set(ECC0081D010CBSMsg.USER_ID_ERR, "E3");
			//	state = false;
			//}
			// 2011/02/21 ユーザーIDは必須チェックに変更 end
			if(chkNull(orgCd) == true)
			{
				inCBSMsg.set(ECC0081D010CBSMsg.ORG_CD_ERR, "E4");
				state = false;
			}
			if(chkNull(posCd) == true)
			{
				inCBSMsg.set(ECC0081D010CBSMsg.POSITION_CD_ERR, "E5");
				state = false;
			}
			
		}
		if(state == false)
		{
			inCBSMsg.set(ECC0081D010CBSMsg.STATUS, StatusCodes.ITEM_RELATION_ERR);
		}
		return state;
	}
	
	/**
	 * Stringに値が設定されているか判定する(20110823 FST add)
	 * <br>
	 * @param arg0 判定する文字列
	 * @return オブジェクトに値が設定されていない場合はtrue
	 */
	private static boolean chkNull(String arg0) 
	{
		if (null == arg0) 
		{
			return true;
		}
		if(arg0.length() == 0)
		{
			return true;
		}
		return false;
	}
}
