/*******************************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
********************************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*   モジュール名    ：JECC0021D010TPMA
*   ソースファイル名：JECC0021D010TPMA.java
*   作成者          ：富士通
*   日付            ：2011年05月20日
*＜機能概要＞
*   メール送信情報登録用独自処理部品です
*＜修正履歴＞
*   バージョン  修正日      修正者      修正内容
*   v1.00.00    2011/05/20  富士通      新規作成
*   v7.00.00    2014/03/25  FJ          OM-2014-0000782 メール送信が遅い
*   v8.00.00    2014/04/07  FJ          OM-2014-0000782 メール送信量制限チェックSQL修正
*   v18.00.00   2015/10/21  FJ)寺園     ANK-2631-00-00 ワンストップ案件（ＳＴＥＰ１）
*
**********************************************************************/

package eo.ejb.cbs.mainproc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;

import com.fujitsu.futurity.common.JCMConstants;
import com.fujitsu.futurity.common.JSYLogBase;
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.base.CAANRuntimeException;
import com.fujitsu.futurity.model.ejb.common.JSYejbConnection;
import com.fujitsu.futurity.model.ejb.common.JSYejbLog;
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.common.util.JCCSendMailUtil;
import eo.ejb.cbm.cbmmsg.CC0131CBMMsg;
import eo.ejb.cbm.entity.CC0021ETMsg;
import eo.ejb.cbm.entity.CC0121ETMsg;
import eo.ejb.cbm.entity.CC0161ETMsg;
import eo.ejb.cbm.entity.CC0181ETMsg;
import eo.ejb.cbs.cbsmsg.ECC0021D010CBSMsg;
import eo.ejb.cbs.cbsmsg.ECC0021D010CBSMsg1List;
import eo.ejb.cbs.cbsmsg.ECC0021D010CBSMsg2List;
import eo.ejb.cbs.cbsmsg.ECC0021D010CBSMsg3List;
import eo.ejb.cbs.cbsmsg.ECC0021D010CBSMsg4List;
import eo.ejb.cbs.cbsmsg.ECC0021D010CBSMsg5List;
import eo.ejb.common.JCCModelCommon;
import eo.ejb.common.JCCejbEFile;
import eo.ejb.common.db.JCCejbCC0041DBABase;
import eo.ejb.common.db.JCCejbCC0121DBABase;
import eo.ejb.common.db.JCCejbCC0161DBABase;
import eo.ejb.common.db.JCCejbCC0181DBABase;

/**
 * <p>
 * メール送信情報登録用独自処理部品クラスです。
 * </p>
 * @author 富士通
 */
public class JECC0021D010TPMA implements TemplateMainHandler
{
	/**
	 * コンストラクタです。
	 */
	public JECC0021D010TPMA()
	{
		super();
	}
	
	/**
	 * <p>
	 * メール送信情報登録登録の副次処理を呼び出します。
	 * </p>
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param inContext Agentから渡されたAgentDispatchContext
	 * @exception Throwable
	 */
	public static void invoke(CAANMsg inCBSMsg, AgentDispatchContext inContext)
	{
		// v7.00.00 出力ログ追加
		long dt1 = (new Date()).getTime();
		// メール組立て情報のセット領域
		HashMap<String, Object> sendMailInfo = new HashMap<String, Object>();
		
		// メールマスタ、メール明細マスタで使用するレコードの保存領域
		HashMap<String,Object> recordMap = new HashMap<String, Object>();
		CAANMsg mailRecord = new CAANMsg();
		ArrayList<CAANMsg> dtlRecordList = new ArrayList<CAANMsg>();
		recordMap.put("MAIL_RECORD", mailRecord);
		recordMap.put("MAIL_DTL_RECORD", dtlRecordList);
		try
		{
			// メール送信状態
			boolean chkSend = true;
			
			// 現在時刻の取得とアカウントの設定（処理終了まで更新しない）
			inCBSMsg.set(ECC0021D010CBSMsg.ADD_DTM, JCCModelCommon.getSysDateTimeStamp());
			inCBSMsg.set(ECC0021D010CBSMsg.ADD_OPEACNT, inCBSMsg.getString(ECC0021D010CBSMsg.OPERATORID));
			
			// 主処理側での単関連チェックを行う
			if(chkItemRelation(inCBSMsg) == false)
			{
				return;
			}
			
			// v7.00.00 出力ログ追加
			long dt2 = (new Date()).getTime();
			// メール送信情報関連チェック
			if(chkItemRelation(inCBSMsg, recordMap) == false)
			{
				return;
			}
			// v7.00.00 出力ログ追加
			long dt3 = (new Date()).getTime();

			// 概念スキーマ登録用情報生成
			createCbsInfo(inCBSMsg);
			
// 2011/09/21 メール情報組み立てをリアルタイム・ディレイド両方で行う。 start
			sendMailInfo = createSendMail(inCBSMsg, recordMap);
// 2011/09/21 メール情報組み立てをリアルタイム・ディレイドで行う。 end

			// v7.00.00 出力ログ追加
			long dt4 = (new Date()).getTime();

			// メール送信情報組立て(リアルタイム送信パターン指定時)
			// 送信パターンがリアルタイム時のチェック
			if("01".equals(inCBSMsg.getString(ECC0021D010CBSMsg.MAIL_SEND_PATTERN_CD))) 
			{
// 2011/09/21 メール情報組み立てをリアルタイム・ディレイドで行う。delete start
				//sendMailInfo = createSendMail(inCBSMsg, recordMap);
// 2011/09/21 メール情報組み立てをリアルタイム・ディレイドで行う。 delete end
				if(inCBSMsg.getInt(ECC0021D010CBSMsg.STATUS) == StatusCodes.RELATION_ERR)
				{
					return;
				}
			}
			// メール送信(機能番号1のみ)
			if("1".equals(inCBSMsg.getString(ECC0021D010CBSMsg.FUNC_CODE)))
			{
				// 2011/03/13 メール送信量制御判定追加 start
				if(chkMailtSendQuantity(inCBSMsg, inContext, sendMailInfo) == true)
				{
					chkSend = sendMail(inCBSMsg, inContext, sendMailInfo);
				}
				// 2011/03/13 メール送信量制御判定追加 end
				
				if(chkSend == false)
				{
					// 送信失敗フラグをセット
					inCBSMsg.set(ECC0021D010CBSMsg.MAIL_SEND_ERR_FLG, "1");	
					
					// 2012/03/13 メール送信バッチにて再送するための情報を登録 start
					// メール送信ステータスを送信エラーに変更
					inCBSMsg.set(ECC0021D010CBSMsg.MAIL_SEND_STAT, "003");
					// メール送信予定年月日時分秒を現在時刻で設定
					inCBSMsg.set(ECC0021D010CBSMsg.MAIL_SEND_RSV_DTM,JCCModelCommon.getSysDateTimeStamp());
					// 2012/03/13 メール送信バッチにて再送するための情報を登録 end
					
				}
				else
				{
					// メール送信ステータスを送信済みに変更
					inCBSMsg.set(ECC0021D010CBSMsg.MAIL_SEND_STAT, "002");
					// メール送信実施時刻に登録年月日を設定
					inCBSMsg.setPrivate("MAIL_SEND_JSSI_DTM",JCCModelCommon.getSysDateTimeStamp());
					// 送信成功
					inCBSMsg.set(ECC0021D010CBSMsg.MAIL_SEND_ERR_FLG, "0");
				}
			}
			else
			{
				// メール送信ステータスを未送信で設定
				inCBSMsg.set(ECC0021D010CBSMsg.MAIL_SEND_STAT, "001");
				// メール送信実施時刻は未設定
				inCBSMsg.setPrivate("MAIL_SEND_JSSI_DTM",null);
				
			}

			// v7.00.00 出力ログ追加
			long dt5 = (new Date()).getTime();
			JSYejbLog.println(JSYLogBase.EXECUTION, JECC0021D010TPMA.class,
					"JECC0021D010TPMA.invoke() 所要時間=" + (dt5 - dt1) + "( 開始〜テンプレ取得前=" + (dt2 - dt1)
					+ ", 関連チェック（テンプレ取得)=" + (dt3 - dt2) + ", メール本文作成=" + (dt4 - dt3)
					+ ", メール送信=" + (dt5 - dt4) + " )");
		}
		catch(Exception e)
		{
			throw new CAANRuntimeException(e);
		}
		return;
	}
	
	/**
	 * <p>
	 * メール送信情報の単関連チェック
	 * @param inMsg 処理対象のメッセージキャリア
	 * @return result チェック結果
	 * </p>
	 * @throws Exception 
	 */
	private static boolean chkItemRelation(CAANMsg inCBSMsg) throws Exception
	{
		boolean result = true;
		int stRet = 0;
		
		Object thisClass = new JECC0021D010TPMA();

		
		// ソースの自動生成で不可能な単関連チェックを行う
		if("01".equals(inCBSMsg.getString(ECC0021D010CBSMsg.MAIL_SEND_PATTERN_CD))) 
		{
			// メール送信パターンコードがリアルタイムで機能番号が2の場合"E0"
			if("2".equals(inCBSMsg.getString(ECC0021D010CBSMsg.FUNC_CODE)))
			{
				inCBSMsg.set(ECC0021D010CBSMsg.MAIL_SEND_PATTERN_CD_ERR, "E0");
				JSYejbLog.println(JSYejbLog.DEBUG,thisClass.getClass(),"mai_send_pattern_cd:E0");
				stRet = StatusCodes.ITEM_RELATION_ERR;
			}
		}
		else
		{
			// メール送信パターンコードがディレイドまたは同報で機能番号が"1"の場合"E1"
			if("1".equals(inCBSMsg.getString(ECC0021D010CBSMsg.FUNC_CODE)))
			{
				inCBSMsg.set(ECC0021D010CBSMsg.MAIL_SEND_PATTERN_CD_ERR, "E1");
				JSYejbLog.println(JSYejbLog.DEBUG,thisClass.getClass(),"mai_send_pattern_cd:E1");
				stRet =StatusCodes.ITEM_RELATION_ERR;
			}
		}
		
		//送信先一覧明細のnullチェック
		CAANMsg[] l_ecc0021d010cbsmsg1list = new CAANMsg[]{};
		if(!inCBSMsg.isNull(ECC0021D010CBSMsg.ECC0021D010CBSMSG1LIST)){
			l_ecc0021d010cbsmsg1list = inCBSMsg.getCAANMsgList(ECC0021D010CBSMsg.ECC0021D010CBSMSG1LIST);
		}

		//電子ファイル一覧明細のnullチェック
		CAANMsg[] l_ecc0021d010cbsmsg3list = new CAANMsg[]{};
		if(!inCBSMsg.isNull(ECC0021D010CBSMsg.ECC0021D010CBSMSG3LIST)){
			l_ecc0021d010cbsmsg3list = inCBSMsg.getCAANMsgList(ECC0021D010CBSMsg.ECC0021D010CBSMSG3LIST);
		}
		
		for(int i = 0; i < l_ecc0021d010cbsmsg1list.length; i++){
			//送信先メールアドレスがnullでない かつ メールアドレス設定フィールドコードがnull ：エラー
			if(!l_ecc0021d010cbsmsg1list[i].isNull(ECC0021D010CBSMsg1List.MLAD) && l_ecc0021d010cbsmsg1list[i].isNull(ECC0021D010CBSMsg1List.MLAD_SET_FIELD_CD)){
				l_ecc0021d010cbsmsg1list[i].set(ECC0021D010CBSMsg1List.MLAD_ERR, "E6");
				JSYejbLog.println(JSYejbLog.DEBUG,thisClass.getClass(),"mlad_err:E6");
				stRet = StatusCodes.ITEM_RELATION_ERR;
			}
		}

		for(int i = 0; i < l_ecc0021d010cbsmsg1list.length; i++){
			//メールアドレス設定フィールドコードがnullでない かつ 送信先メールアドレスがnull ：エラー
			if(!l_ecc0021d010cbsmsg1list[i].isNull(ECC0021D010CBSMsg1List.MLAD_SET_FIELD_CD) && l_ecc0021d010cbsmsg1list[i].isNull(ECC0021D010CBSMsg1List.MLAD)){
				l_ecc0021d010cbsmsg1list[i].set(ECC0021D010CBSMsg1List.MLAD_SET_FIELD_CD_ERR, "E6");
				JSYejbLog.println(JSYejbLog.DEBUG,thisClass.getClass(),"mlad_set_field_cd_err:E6");
				stRet = StatusCodes.ITEM_RELATION_ERR;
			}
		}

		for(int i = 0; i < l_ecc0021d010cbsmsg3list.length; i++){
			//電子ファイル管理番号がnullでない かつ ファイル名がnull ：エラー
			if(!l_ecc0021d010cbsmsg3list[i].isNull(ECC0021D010CBSMsg3List.EFILE_KANRI_NO) && l_ecc0021d010cbsmsg3list[i].isNull(ECC0021D010CBSMsg3List.FILE_NM)){
				l_ecc0021d010cbsmsg3list[i].set(ECC0021D010CBSMsg3List.EFILE_KANRI_NO_ERR, "E7");
				JSYejbLog.println(JSYejbLog.DEBUG,thisClass.getClass(),"efile_kanri_no_err:E7");
				stRet = StatusCodes.ITEM_RELATION_ERR;
			}
		}

		for(int i = 0; i < l_ecc0021d010cbsmsg3list.length; i++){
			//ファイル名がnullでない かつ 電子ファイル管理番号がnull ：エラー
			if(!l_ecc0021d010cbsmsg3list[i].isNull(ECC0021D010CBSMsg3List.FILE_NM) && l_ecc0021d010cbsmsg3list[i].isNull(ECC0021D010CBSMsg3List.EFILE_KANRI_NO)){
				l_ecc0021d010cbsmsg3list[i].set(ECC0021D010CBSMsg3List.FILE_NM_ERR, "E7");
				JSYejbLog.println(JSYejbLog.DEBUG,thisClass.getClass(),"file_nm_err:E7");
				stRet = StatusCodes.ITEM_RELATION_ERR;
			}
		}
		
		// ステータスの更新
		if(stRet != 0)
		{
			inCBSMsg.set(ECC0021D010CBSMsg.STATUS, StatusCodes.ITEM_RELATION_ERR);
			result = false;
		}
		
		return result;
	}
	
	
	/**
	 * <p>
	 * メール送信情報の関連チェック
	 * @param inMsg 処理対象のメッセージキャリア
	 * @return result チェック結果
	 * </p>
	 * @throws Exception 
	 */
	private static boolean chkItemRelation(CAANMsg inCBSMsg, HashMap<String,Object> recordMap) throws Exception
	{
		boolean result = true;
		String mailCode = null;
		String mailDtlCode = null;
		
		CAANMsg mailRecord = (CAANMsg)recordMap.get("MAIL_RECORD");
		ArrayList<CAANMsg> dtlRecordList = (ArrayList)recordMap.get("MAIL_DTL_RECORD");
		
		// 日付比較用に年月日時分秒を年月日形式に変更
		String strDate = null;
		if("01".equals(inCBSMsg.getString(ECC0021D010CBSMsg.MAIL_SEND_PATTERN_CD)))
		{
			strDate = JCCModelCommon.getOpeDate(inCBSMsg, null);
		}
		else
		{
			strDate = inCBSMsg.getString(ECC0021D010CBSMsg.MAIL_SEND_RSV_DTM).substring(0, 8);
		}
		
		// メールマスタ系関連チェック
		try
		{
			// 指定されたメールコードをローカルに取得
			mailCode = inCBSMsg.getString(ECC0021D010CBSMsg.MAIL_CD);
			// メールマスタアクセス部品のインスタンス化
			JCCejbCC0121DBABase dbaCC0121 = new JCCejbCC0121DBABase();
			
			// レコード取得用の領域
			CAANMsg currentRecord   = dbaCC0121.getCurrentRecord(mailCode, strDate);
			CAANMsg[] historyRecord = null;
			// 指定のメールコードがメールマスタに存在しない場合"EA"
			if(chkNull(currentRecord) == true)
			{
				if(dbaCC0121.isExistPrimaryKey(mailCode) == false)
				{
					inCBSMsg.set(ECC0021D010CBSMsg.MAIL_CD_ERR, "EA");
					result = false;
					return false;
				}
			}
// 2011/09/21 メール関連チェックをリアルタイム・ディレイド両方で行う。 start
			// メール送信パターンコードがリアルタイムで指定されている場合
//			if("01".equals(inCBSMsg.getString(ECC0021D010CBSMsg.MAIL_SEND_PATTERN_CD)))
//			{
// 2011/09/21 メール関連チェックをリアルタイム・ディレイド両方で行う。 end
				// カレントと履歴のレコードから現在有効なメールマスタのレコードを取得
				mailRecord = getAvailableRecord(strDate, currentRecord, null, CC0121ETMsg.MAIL_TSTAYMD, CC0121ETMsg.MAIL_TENDYMD);
				if(chkNull(mailRecord))
				{
					// カレントで該当しない場合は場合は履歴レコードを検索
					if(chkNull(historyRecord))
					{
						historyRecord = dbaCC0121.getHistoryRecord(mailCode, strDate);
					}
					mailRecord = getAvailableRecord(strDate, null, historyRecord, CC0121ETMsg.MAIL_TSTAYMD, CC0121ETMsg.MAIL_TENDYMD);
					if(chkNull(mailRecord))
					{
						// 現在有効なレコードが存在しない
						inCBSMsg.set(ECC0021D010CBSMsg.MAIL_CD_ERR, "EB");
						result = false;
					}
				}
				// 送信元メールアドレスが指定されていない場合
				if(chkNull(inCBSMsg.getString(ECC0021D010CBSMsg.SENDM_MLAD)))
				{
					// メールマスタにも送信元メールアドレスが存在しない"EC"
					if(chkNull(mailRecord.getString(CC0121ETMsg.SENDM_MLAD)))
					{
						inCBSMsg.set(ECC0021D010CBSMsg.SENDM_MLAD_ERR, "EC");
						result = false;
					}
					// 外部スキーマ項目に送信元アドレスと送信元アドレス表示名をセット
					inCBSMsg.set(ECC0021D010CBSMsg.SENDM_MLAD, mailRecord.getString(CC0121ETMsg.SENDM_MLAD));
					inCBSMsg.set(ECC0021D010CBSMsg.SENDM_MLAD_DSP_NM, mailRecord.getString(CC0121ETMsg.SENDM_MLAD_DSP_NM));
				}
				// SMTP識別コードが存在しない"ED"
				else if(chkNull(mailRecord.getString(CC0121ETMsg.SMTP_SKBT_CD)))
				{
					inCBSMsg.set(ECC0021D010CBSMsg.MAIL_SEND_PATTERN_CD_ERR, "ED");
					result = false;	
				}
				// 本文非定形置換文字列が指定されている場合
				CAANMsg[] l_ecc0021d010cbsmsg2list = new CAANMsg[]{};
				if(!inCBSMsg.isNull(ECC0021D010CBSMsg.ECC0021D010CBSMSG2LIST))
				{
					l_ecc0021d010cbsmsg2list = inCBSMsg.getCAANMsgList(ECC0021D010CBSMsg.ECC0021D010CBSMSG2LIST);
					if(l_ecc0021d010cbsmsg2list.length != getStrCnt(mailRecord.getString(CC0121ETMsg.MAIL_TEXT), "%"))
					{
						// メールマスタから取得した本文の置換文字と指定した本文非定形文字列の要素数が一致しない"EG"
						inCBSMsg.set(ECC0021D010CBSMsg.ECC0021D010CBSMSG2LIST_ERR, "EE");
						result = false;	
					}
				}
//			}
		}
		catch(SQLException e)
		{
			// JCCFrameworkExceptionをスロー
			throw new JCCFrameworkException("メールマスタ検索時にエラーが発生しました。", e);
		}
		finally
		{
			// 関連チェックエラー発生の場合はステータスを更新
			if(result == false)
			{
				inCBSMsg.set(ECC0021D010CBSMsg.STATUS, StatusCodes.RELATION_ERR);
				return false;
			}
		}
		// メール明細マスタ系関連チェック
		try
		{
			// メール明細コードが指定されている場合はチェックを行う
			CAANMsg[] l_ecc0021d010cbsmsg4list = new CAANMsg[]{};
			if(!inCBSMsg.isNull(ECC0021D010CBSMsg.ECC0021D010CBSMSG4LIST))
			{
				l_ecc0021d010cbsmsg4list = inCBSMsg.getCAANMsgList(ECC0021D010CBSMsg.ECC0021D010CBSMSG4LIST);
				// メール明細マスタとメール_メール明細テーブルアクセス部品のインスタンス化
				JCCejbCC0161DBABase dbaCC0161 = new JCCejbCC0161DBABase();
				JCCejbCC0181DBABase dbaCC0181 = new JCCejbCC0181DBABase();
				
				// メール明細マスタ情報格納用領域
				String tmpDtlCd = "";
				int chkCnt = 0;
				int dtlCnt = 0;
				int dtkCknCnt = 0;
				for(int i = 0; i < l_ecc0021d010cbsmsg4list.length; i++)
				{
					// メール明細コードを取得
					mailDtlCode = l_ecc0021d010cbsmsg4list[i].getString(ECC0021D010CBSMsg4List.MAIL_DTL_CD);
					
					// 明細本文非定型置換文字の数をカウント
					// 2011/12/14 nullはカウントしない（空文字はカウントする） start
					if(null != l_ecc0021d010cbsmsg4list[i].getString(ECC0021D010CBSMsg4List.DTL_TEXT_HTK_CKAM_MOJI))
					{
						dtkCknCnt++;
					}
					// 2011/12/14 nullはカウントしない（空文字はカウントする） end
					// 取得したメール明細コードが変わった場合はメールコードとメール明細コードに紐づいた検査を行う
					if(tmpDtlCd.equals(mailDtlCode) == false)
					{
						CAANMsg currentDtlRecord   = dbaCC0161.getCurrentRecord(mailDtlCode, strDate);
						CAANMsg[] historyDtlRecord = null;
						CAANMsg mailMailDtlRecord   = dbaCC0181.getPrimaryRecord(mailCode, mailDtlCode);
						
						// 指定のメール明細コードがメール明細マスタに存在しない場合"EF"
						if(chkNull(currentDtlRecord) == true)
						{
							if(dbaCC0161.isExistPrimaryKey(mailDtlCode) == false)
							{
								inCBSMsg.set(ECC0021D010CBSMsg.ECC0021D010CBSMSG4LIST_ERR, "EF");
								result = false;
								return false;
							}
						}
						// 指定のメールコードと明細コードに紐づく情報がメール_メール明細テーブルに存在しない場合は"EJ"
						if(chkNull(mailMailDtlRecord))
						{
							inCBSMsg.set(ECC0021D010CBSMsg.ECC0021D010CBSMSG4LIST_ERR, "EJ");
							result = false;	
							return false;
						}
// 2011/09/21 メール関連チェックをリアルタイム・ディレイド両方で行う。 start
						// メール送信パターンコードがリアルタイムで指定されている場合
//						if("01".equals(inCBSMsg.getString(ECC0021D010CBSMsg.MAIL_SEND_PATTERN_CD)))
//						{
// 2011/09/21 メール関連チェックをリアルタイム・ディレイド両方で行う。 end
							// カレントと履歴のレコードから現在有効なメール明細マスタのレコードを取得
							CAANMsg availableDtlRecord = getAvailableRecord(strDate, currentDtlRecord, null,CC0161ETMsg.MAIL_DTL_TSTAYMD, CC0161ETMsg.MAIL_DTL_TENDYMD);
							if(chkNull(availableDtlRecord))
							{
								// カレントで該当しない場合は場合は履歴レコードを検索
								if(chkNull(historyDtlRecord))
								{
									historyDtlRecord =dbaCC0161.getHistoryRecord(mailDtlCode, strDate);
								}
								availableDtlRecord = getAvailableRecord(strDate, null, historyDtlRecord, CC0161ETMsg.MAIL_DTL_TSTAYMD, CC0161ETMsg.MAIL_DTL_TENDYMD);
								if(chkNull(availableDtlRecord))
								{
									// 現在有効なレコードがメール明細マスタ明細マスタに存在しない
									inCBSMsg.set(ECC0021D010CBSMsg.ECC0021D010CBSMSG4LIST_ERR, "EG");
									result = false;	
									return false;
								}
							}
							dtlRecordList.add(availableDtlRecord);
							
							// メール_メール明細が有効かどうか確認する
							CAANMsg availableMailMailRecord = getAvailableRecord(strDate, mailMailDtlRecord, null, CC0181ETMsg.MAIL_MAIL_DTL_TSTAYMD, CC0181ETMsg.MAIL_MAIL_DTL_TENDYMD);
							if(chkNull(availableMailMailRecord))
							{
								// 現在有効なレコードがメール_メール明細に存在しない"EK"
								inCBSMsg.set(ECC0021D010CBSMsg.ECC0021D010CBSMSG4LIST_ERR, "EK");
								result = false;	
								return false;
							}
							
							// メール明細本文の"%"の数をカウント
							chkCnt = chkCnt + getStrCnt(availableDtlRecord.getString(CC0161ETMsg.MAIL_DTL_TEXT), "%");
//						}
						tmpDtlCd = mailDtlCode;
						// メール明細コードの数をカウント
						dtlCnt++;
					}
				}
// 2011/09/21 メール関連チェックをリアルタイム・ディレイド両方で行う。 start
//				if("01".equals(inCBSMsg.getString(ECC0021D010CBSMsg.MAIL_SEND_PATTERN_CD)))
//				{
// 2011/09/21 メール関連チェックをリアルタイム・ディレイド両方で行う。 end
					// メール明細マスタから取得した明細本文の置換文字と指定した明細本文非定形文字列の要素数が一致しない"EH"
					if(chkCnt != dtkCknCnt)
					{
						inCBSMsg.set(ECC0021D010CBSMsg.ECC0021D010CBSMSG4LIST_ERR, "EH");
						result = false;	
						return false;
					}
					
					// メール本文中のメール明細置換文字とメール明細コードの数が一致しない"EI"
					if(dtlCnt != getStrCnt(mailRecord.getString(CC0121ETMsg.MAIL_TEXT), "$"))
					{
						inCBSMsg.set(ECC0021D010CBSMsg.ECC0021D010CBSMSG4LIST_ERR, "EI");
						result = false;	
						return false;
					}
//				}
			}
		}
		catch(SQLException e)
		{
			// JCCFrameworkExceptionをスロー
			throw new JCCFrameworkException("メール明細マスタまたはメール_メール明細テーブル検索時にエラーが発生しました。", e);
		}
		finally
		{
			// 関連チェックエラー発生の場合はステータスを更新
			if(result == false)
			{
				inCBSMsg.set(ECC0021D010CBSMsg.STATUS, StatusCodes.RELATION_ERR);
				return false;
			}
		}
		// 電子ファイル管理テーブル系チェック(リアルタイム送信以外)
		// リアルタイム送信の場合は実ファイル取得時にチェックするためここでは未検査(SQL文とメモリの節約)
		if("01".equals(inCBSMsg.getString(ECC0021D010CBSMsg.MAIL_SEND_PATTERN_CD)) == false) 
		{
			CAANMsg[] l_ecc0021d010cbsmsg3list = new CAANMsg[]{};
			if(!inCBSMsg.isNull(ECC0021D010CBSMsg.ECC0021D010CBSMSG3LIST))
			{
				JCCejbCC0041DBABase dbaCC0041 = new JCCejbCC0041DBABase();
				l_ecc0021d010cbsmsg3list = inCBSMsg.getCAANMsgList(ECC0021D010CBSMsg.ECC0021D010CBSMSG3LIST);
				for(int i = 0; i < l_ecc0021d010cbsmsg3list.length; i++)
				{
					// 電子ファイル管理番号とファイル名の取得
					String eFileNo = l_ecc0021d010cbsmsg3list[i].getString(ECC0021D010CBSMsg3List.EFILE_KANRI_NO);				
					// 電子ファイル管理番号に紐づいた電子ファイルが存在する事を確認する
					if(eFileNo != null)
					{
						if(dbaCC0041.isExistRecord(eFileNo) == false)
						{
							// 2012/11/21 FST_mukuo)エラー設定値項目ミス修正 start
							//inCBSMsg.set(ECC0021D010CBSMsg.ECC0021D010CBSMSG3LIST_ERR, "EL");
							CAANMsg[] msgList = (CAANMsg[])inCBSMsg.getObject(ECC0021D010CBSMsg.ECC0021D010CBSMSG3LIST);
							CAANMsg msg = msgList[i];
							msg.set(ECC0021D010CBSMsg3List.EFILE_KANRI_NO_ERR, "EL");
							// 2012/11/21 FST_mukuo)エラー設定値項目ミス修正 start
							inCBSMsg.set(ECC0021D010CBSMsg.STATUS, StatusCodes.RELATION_ERR);
							result = false;
							break;
						}
					}
				}
			}
		
		}
		// 取得したレコードをHashMapに再セット
		recordMap.put("MAIL_RECORD", mailRecord);
		recordMap.put("MAIL_DTL_RECORD", dtlRecordList);

		return result;
	}
	
	/**
	 * <p>
	 * 概念スキーマ登録用情報生成
	 * @param inMsg 処理対象のメッセージキャリア
	 * </p>
	 * @throws Exception 
	 */
	
	private static void createCbsInfo(CAANMsg inCBSMsg) throws Exception
	{
		// メール送信番号採番
		try
		{
			String mailSendNo = JCCModelCommon.getFormatedNextSeq("SEQ_MAIL_SEND_NO", "S", 11);
			inCBSMsg.set(ECC0021D010CBSMsg.MAIL_SEND_NO, mailSendNo);
		}
		catch(JCCFrameworkException jcce)
		{
			throw new JCCFrameworkException("メール送信番号の採番に失敗しました。");
		}
		// メールアドレス番号採番
		try
		{
			// 送信元メールアドレス
			String sendmMladNo = JCCModelCommon.getFormatedNextSeq("SEQ_MLAD_NO", "A", 14);
			inCBSMsg.set(ECC0021D010CBSMsg.SENDM_MLAD_NO, sendmMladNo);
			
			// 送信先メールアドレス
			CAANMsg[] l_ecc0021d010cbsmsg1list = new CAANMsg[]{};
			if(!inCBSMsg.isNull(ECC0021D010CBSMsg.ECC0021D010CBSMSG1LIST))
			{
				l_ecc0021d010cbsmsg1list = inCBSMsg.getCAANMsgList(ECC0021D010CBSMsg.ECC0021D010CBSMSG1LIST);
			}
			for(int i = 0; i < l_ecc0021d010cbsmsg1list.length; i++)
			{
				String mladNo = JCCModelCommon.getFormatedNextSeq("SEQ_MLAD_NO", "A", 14);
				l_ecc0021d010cbsmsg1list[i].set(ECC0021D010CBSMsg1List.MLAD_NO, mladNo);
			}
		}
		catch(JCCFrameworkException jcce)
		{
			throw new JCCFrameworkException("メールアドレス番号の採番に失敗しました。");
		}
		// 添付ファイル番号採番
		try
		{
			// 添付ファイル
			CAANMsg[] l_ecc0021d010cbsmsg3list = new CAANMsg[]{};
			if(!inCBSMsg.isNull(ECC0021D010CBSMsg.ECC0021D010CBSMSG3LIST))
			{
				l_ecc0021d010cbsmsg3list = inCBSMsg.getCAANMsgList(ECC0021D010CBSMsg.ECC0021D010CBSMSG3LIST);
			}
			for(int i = 0; i < l_ecc0021d010cbsmsg3list.length; i++)
			{
				String tempFileNo = JCCModelCommon.getFormatedNextSeq("SEQ_TEMP_FILE_NO", "T", 14);
				l_ecc0021d010cbsmsg3list[i].set(ECC0021D010CBSMsg3List.TEMP_FILE_NO, tempFileNo);
			}
		}
		catch(JCCFrameworkException jcce)
		{
			throw new JCCFrameworkException("添付ファイル番号の採番に失敗しました。");
		}
	}
	
	/**
	 * <p>
	 * メール送信情報の組立て
	 * @param inMsg 処理対象のメッセージキャリア
	 * @return HashMap メール送信情報
	 * </p>
	 * @throws Exception 
	 */
	private static HashMap<String, Object> createSendMail(CAANMsg inCBSMsg, HashMap<String,Object> recordMap) throws Exception
	{
		HashMap<String, Object> sendMailInfo = new HashMap<String, Object>();
		
		CAANMsg mailRecord = (CAANMsg)recordMap.get("MAIL_RECORD");
		ArrayList<CAANMsg> dtlRecordList = (ArrayList)recordMap.get("MAIL_DTL_RECORD");
		
		try
		{
			// メールレコード検査
			if(chkNull(mailRecord))
			{
				throw new JCCFrameworkException("メールマスタの情報が取得できませんでした。");
			}
			
			// SMTPサーバー情報を取得
			String smtpInfo = JCCModelCommon.getApplicationConst(mailRecord.getString(CC0121ETMsg.SMTP_SKBT_CD));
			if(smtpInfo == null)
			{
				throw new JCCFrameworkException("アプリケーションプロパティファイルにSMTP識別コードに基づいた情報が存在しません。");
			}
			if(smtpInfo.indexOf(";") == -1)
			{
				throw new JCCFrameworkException("アプリケーションプロパティファイルのSMTP識別情報の書式に誤りがあります。");
			}
			
			// ホスト名、ポート番号、文字コードを送信情報に設定
			String hostName = smtpInfo.substring(0, smtpInfo.indexOf(";"));
			String portNo = smtpInfo.substring(smtpInfo.indexOf(";") + 1);
			String mojiCd = "ISO-2022-JP";
			if(portNo.indexOf(";") != -1)
			{
				mojiCd = portNo.substring(portNo.indexOf(";") + 1);
				portNo = portNo.substring(0, portNo.indexOf(";"));
			}
			sendMailInfo.put("SMTP_HOST", hostName);
			sendMailInfo.put("SMTP_PORT", portNo);
			sendMailInfo.put("MAIL_MOJI_CD", mojiCd);
			
			//送信先氏名格納用領域
			HashMap<String, Object> mladNm = new HashMap<String, Object>();
			HashMap<String, String> mladFromNm = new HashMap<String, String>();
			HashMap<String, String> mladToNm = new HashMap<String, String>();
			HashMap<String, String> mladCcNm = new HashMap<String, String>();
			HashMap<String, String> mladBccNm = new HashMap<String, String>();
			HashMap<String, String> mladReplyNm = new HashMap<String, String>();
			
			// 送信元メールアドレスの設定
			String sendmMlad = inCBSMsg.getString(ECC0021D010CBSMsg.SENDM_MLAD);
			String sendmMladNm = inCBSMsg.getString(ECC0021D010CBSMsg.SENDM_MLAD_DSP_NM);
			// 入力パラメータで指定されていない場合はメールマスタの情報を登録
			if(sendmMlad == null)
			{
				sendmMlad = mailRecord.getString(CC0121ETMsg.SENDM_MLAD);
				sendmMladNm = mailRecord.getString(CC0121ETMsg.SENDM_MLAD_DSP_NM);
			}
			sendMailInfo.put("MLAD_FROM", sendmMlad);
			mladFromNm.put(sendmMlad, sendmMladNm);
			mladNm.put("MLAD_FROM_NM",mladFromNm);
			
			// 送信先メールアドレス情報設定領域
			ArrayList<String> adrToList = new ArrayList<String>();
			ArrayList<String> adrCcList = new ArrayList<String>();
			ArrayList<String> adrBccList = new ArrayList<String>();
			// 送信先メールアドレス名及び表示名の設定
			CAANMsg[] l_ecc0021d010cbsmsg1list = new CAANMsg[]{};
			if(!inCBSMsg.isNull(ECC0021D010CBSMsg.ECC0021D010CBSMSG1LIST))
			{
				l_ecc0021d010cbsmsg1list = inCBSMsg.getCAANMsgList(ECC0021D010CBSMsg.ECC0021D010CBSMSG1LIST);
				for(int i = 0; i < l_ecc0021d010cbsmsg1list.length; i++)
				{
					String fieldCd = l_ecc0021d010cbsmsg1list[i].getString(ECC0021D010CBSMsg1List.MLAD_SET_FIELD_CD);
					String adr = l_ecc0021d010cbsmsg1list[i].getString(ECC0021D010CBSMsg1List.MLAD);
					String adrNm = l_ecc0021d010cbsmsg1list[i].getString(ECC0021D010CBSMsg1List.MLAD_DSP_NM);
					if("01".equals(fieldCd))
					{
						adrToList.add(adr);
						mladToNm.put(adr, adrNm);
					}
					else if("03".equals(fieldCd))
					{
						adrCcList.add(adr);
						mladCcNm.put(adr, adrNm);
					}
					else if("04".equals(fieldCd))
					{
						adrBccList.add(adr);
						mladBccNm.put(adr, adrNm);
					}
				}
			}
			sendMailInfo.put("MLAD_TO", (String[])adrToList.toArray(new String[0]));
			sendMailInfo.put("MLAD_CC", (String[])adrCcList.toArray(new String[0]));
			sendMailInfo.put("MLAD_BCC", (String[])adrBccList.toArray(new String[0]));
			mladNm.put("MLAD_TO_NM",mladToNm);
			mladNm.put("MLAD_CC_NM",mladCcNm);
			mladNm.put("MLAD_BCC_NM",mladBccNm);
			
			// 返信先メールアドレス名及び表示名の設定
			String replyMlad = mailRecord.getString(CC0121ETMsg.HNSIN_MLAD);
			String replyMladNm = mailRecord.getString(CC0121ETMsg.HNSIN_MLAD_DSP_NM);
			mladReplyNm.put(replyMlad, replyMladNm);
			sendMailInfo.put("MLAD_REPLY_TO", replyMlad);
			mladNm.put("MLAD_REPLY_NM",mladReplyNm);
			
			
			// エラーメール送信先の設定
			String returnPath = mailRecord.getString(CC0121ETMsg.ERR_MLAD);
			sendMailInfo.put("MLAD_RETURN_PATH", returnPath);
			
			// 表示名のHashMapを設定
			sendMailInfo.put("MLAD_NM", mladNm);
			
			// メールタイトルの設定
			String mailTitle = mailRecord.getString(CC0121ETMsg.MAIL_TITLE);
			if(null == mailTitle)
			{
				mailTitle = "";
			}
			sendMailInfo.put("MAIL_TITLE", mailTitle);
			
			// その他のヘッダー情報を設定
			HashMap<String, String> headIf = new HashMap<String, String>();
			CAANMsg[] l_ecc0021d010cbsmsg5list = new CAANMsg[]{};
			if(!inCBSMsg.isNull(ECC0021D010CBSMsg.ECC0021D010CBSMSG5LIST))
			{
				l_ecc0021d010cbsmsg5list = inCBSMsg.getCAANMsgList(ECC0021D010CBSMsg.ECC0021D010CBSMSG5LIST);
				for(int i = 0; i < l_ecc0021d010cbsmsg5list.length; i++)
				{
					String headKey = l_ecc0021d010cbsmsg5list[i].getString(ECC0021D010CBSMsg5List.MAIL_HEADER_KEY);
					String headValue = l_ecc0021d010cbsmsg5list[i].getString(ECC0021D010CBSMsg5List.MAIL_HEADER_VALUE);
					headIf.put(headKey, headValue);
				}
			}
			sendMailInfo.put("MAIL_HEADER_IF", headIf);
			
			// メール本文組立て用領域
			StringBuffer bodyText = new StringBuffer("");
			StringBuffer bodyMasterText = new StringBuffer("");
			
			// メール本文の取得
			String body = mailRecord.getString(CC0121ETMsg.MAIL_TEXT);
			if(chkNull(body))
			{
				body = "";
			}
			// 本文中の"%"を本文非定型部置換文字列に置き換えながら連結
			CAANMsg[] l_ecc0021d010cbsmsg2list = new CAANMsg[]{};
			l_ecc0021d010cbsmsg2list = inCBSMsg.getCAANMsgList(ECC0021D010CBSMsg.ECC0021D010CBSMSG2LIST);
			if(chkNull(l_ecc0021d010cbsmsg2list) == false)
			{
				for(int i = 0; i < l_ecc0021d010cbsmsg2list.length; i++)
				{
					String textHtkb = l_ecc0021d010cbsmsg2list[i].getString(ECC0021D010CBSMsg2List.TEXT_HTK_CKAM_MOJI);
					if(body.indexOf("%") == -1)
					{
						bodyText.append(body);
						break;
					}
					else
					{
						// "%"部分までを登録用本文にセット
						bodyText.append(body.substring(0, body.indexOf("%")));
						// 非定型置換文字列を連結
						// 2011/11/17 指定値がnullの場合は空文字に置換する start
						// 本文非定型部がnullの場合は空文字に置換
						if(null == textHtkb)
						{
							textHtkb = "";
						}
						// 2011/11/17 指定値がnullの場合は空文字に置換する end
						bodyText.append(textHtkb);
						// 登録した部分までをトリミング
						body = body.substring(body.indexOf("%") + 1);
						//"%"が無くなった場合は残り全てを連結してループ抜け
						if(body.indexOf("%") == -1)
						{
							bodyText.append(body);
						}
					}
				}
			}
			else
			{
				bodyText.append(body);
			}
			// メール明細コードが指定されている場合は更に置換
			CAANMsg[] l_ecc0021d010cbsmsg4list = new CAANMsg[]{};
			StringBuffer dtlBodyMaster = new StringBuffer();
			
			l_ecc0021d010cbsmsg4list = inCBSMsg.getCAANMsgList(ECC0021D010CBSMsg.ECC0021D010CBSMSG4LIST);
			if(chkNull(l_ecc0021d010cbsmsg4list) == false)
			{
				String tmpDtlCd = "";
				String dtlBody = "";
				String tmpBpdyText = bodyText.toString();
				String dtlTextHtkb = "";
				int setCnt = 0;
				
				for(int i = 0; i < l_ecc0021d010cbsmsg4list.length; i++)
				{
					// メール明細コードを取得
					String mailDtlCd = l_ecc0021d010cbsmsg4list[i].getString(ECC0021D010CBSMsg4List.MAIL_DTL_CD);
					// 取得したメール明細コードが変わった場合は、次の明細本文を取得
					if(tmpDtlCd.equals(mailDtlCd) == false)
					{
						// メール明細コードに紐付いたメール明細本文を取得
						CAANMsg dtlRecord = new CAANMsg(dtlRecordList.get(setCnt));
						if(chkNull(dtlRecord))
						{
							throw new JCCFrameworkException("メール明細マスタの情報が取得できませんでした。");
						}
						dtlBody = dtlRecord.getString(CC0161ETMsg.MAIL_DTL_TEXT);
						if(null == dtlBody)
						{
							dtlBody = "";
						}
						setCnt++;
					}
					dtlTextHtkb = l_ecc0021d010cbsmsg4list[i].getString(ECC0021D010CBSMsg4List.DTL_TEXT_HTK_CKAM_MOJI);
					if(dtlBody.indexOf("%") == -1)
					{
						dtlBodyMaster.append(dtlBody);
						// 本文中の"$"部分までを登録用本文にセット
						bodyMasterText.append(tmpBpdyText.substring(0, tmpBpdyText.indexOf("$")));
						// 非定型置換文字列を連結
						bodyMasterText.append(dtlBodyMaster);
						// 登録した部分までをトリミング
						tmpBpdyText = tmpBpdyText.substring(tmpBpdyText.indexOf("$") + 1);
						//"$"が無くなった場合は残り全てを連結してループ抜け
						if(tmpBpdyText.indexOf("$") == -1)
						{
							bodyMasterText.append(tmpBpdyText);
							break;
						}
						dtlBodyMaster.delete(0,dtlBodyMaster.length());
						continue;
					}
					else
					{
						// "%"部分までを登録用本文にセット
						dtlBodyMaster.append(dtlBody.substring(0, dtlBody.indexOf("%")));
						// 非定型置換文字列を連結
						// 2011/11/17 指定値がnullの場合は空文字に置換する start
						if(null == dtlTextHtkb)
						{
							dtlTextHtkb = "";
						}
						// 2011/11/17 指定値がnullの場合は空文字に置換する end
						dtlBodyMaster.append(dtlTextHtkb);
						// 登録した部分までをトリミング
						dtlBody = dtlBody.substring(dtlBody.indexOf("%") + 1);
						//"%"が無くなった場合は残り全てを連結
						if(dtlBody.indexOf("%") == -1)
						{
							// 明細本文の完成
							dtlBodyMaster.append(dtlBody);
							// 本文中の"$"部分までを登録用本文にセット
							bodyMasterText.append(tmpBpdyText.substring(0, tmpBpdyText.indexOf("$")));
							// 非定型置換文字列を連結
							bodyMasterText.append(dtlBodyMaster);
							// 登録した部分までをトリミング
							tmpBpdyText = tmpBpdyText.substring(tmpBpdyText.indexOf("$") + 1);
							//"$"が無くなった場合は残り全てを連結してループ抜け
							if(tmpBpdyText.indexOf("$") == -1)
							{
								bodyMasterText.append(tmpBpdyText);
								break;
							}
							dtlBodyMaster.delete(0,dtlBodyMaster.length());
							continue;
						}
					}					
					tmpDtlCd = mailDtlCd;
				}
			}
			else
			{
				bodyMasterText.append(bodyText.toString());
			}
			// 本文を送信情報に登録
			sendMailInfo.put("MAIL_TEXT", bodyMasterText.toString());
			
// 2011/09/21 メールタイトルおよびメール本文をアウトプットに設定　start
			inCBSMsg.set(ECC0021D010CBSMsg.MAIL_TITLE, sendMailInfo.get("MAIL_TITLE"));
			inCBSMsg.set(ECC0021D010CBSMsg.MAIL_TEXT, sendMailInfo.get("MAIL_TEXT"));
// 2011/09/21 メールタイトルおよびメール本文をアウトプットに設定　end
			
			// 電子ファイル管理番号が指定されている場合は添付ファイルを送信情報に登録
			CAANMsg[] l_ecc0021d010cbsmsg3list = new CAANMsg[]{};
			if(!inCBSMsg.isNull(ECC0021D010CBSMsg.ECC0021D010CBSMSG3LIST))
			{
				l_ecc0021d010cbsmsg3list = inCBSMsg.getCAANMsgList(ECC0021D010CBSMsg.ECC0021D010CBSMSG3LIST);
			}
			
			int fileSizeSum = 0;
			int fileSizeLimit = 0;
			String limitStr = null;
			
			// 2012/02/03 添付ファイル名の重複を許容する対応 start
			ArrayList<HashMap<String, Object>> eFileArray = new ArrayList<HashMap<String, Object>>();
			HashMap<String, Object> eFileMap = null;
			// 2012/02/03 添付ファイル名の重複を許容する対応 end

			if(l_ecc0021d010cbsmsg3list.length > 0)
			{
				limitStr = JCCModelCommon.getApplicationConst("SEND_MAIL_TEMP_MAX_SIZE");
				if(limitStr == null)
				{
					limitStr = "5";
				}
				fileSizeLimit = Integer.parseInt(limitStr);
				fileSizeLimit <<= 20;
			}
			for(int i = 0; i < l_ecc0021d010cbsmsg3list.length; i++)
			{
				// 電子ファイル管理番号とファイル名の取得
				String eFileNo = l_ecc0021d010cbsmsg3list[i].getString(ECC0021D010CBSMsg3List.EFILE_KANRI_NO);
				String fileName = l_ecc0021d010cbsmsg3list[i].getString(ECC0021D010CBSMsg3List.FILE_NM);
				
				// 電子ファイル管理番号使用して電子ファイルのバイナリデータを取得
				if(eFileNo != null)
				{
					try
					{
						byte[] eFile = JCCejbEFile.getEFile(eFileNo);
						// ファイルサイズを加算
						fileSizeSum += eFile.length;
						if(fileSizeSum > fileSizeLimit)
						{
							// 2012/11/21 FST_mukuo)ファイルサイズ超過は業務エラーとする start
							//throw new JCCFrameworkException("メールに添付できるファイルのサイズを超過しました");
							inCBSMsg.set(ECC0021D010CBSMsg.ECC0021D010CBSMSG3LIST_ERR, "EM");
							inCBSMsg.set(ECC0021D010CBSMsg.STATUS, StatusCodes.RELATION_ERR);
							return sendMailInfo;
							// 2012/11/21 FST_mukuo)ファイルサイズ超過は業務エラーとする end
						}
						// 2012/02/03 添付ファイル名の重複を許容する対応 start
						eFileMap = new HashMap<String, Object>();
						eFileMap.put(fileName, eFile);
						eFileArray.add(eFileMap);
						// 2012/02/03 添付ファイル名の重複を許容する対応 end
					}
					catch(JCCFrameworkException jcce)
					{
						Object obj = jcce.getCausedByObject();
						if(null != obj)
						{
							String str = obj.toString();
							String chk = "指定の電子ファイル管理番号に紐づく情報が取得できませんでした。";
							if(chkNull(str) == false)
							{
								if(str.indexOf(chk) >= 0)
								{
									// 2012/11/21 FST_mukuo)エラー設定値項目ミス修正 start
									//inCBSMsg.set(ECC0021D010CBSMsg.ECC0021D010CBSMSG3LIST_ERR, "EL");
									CAANMsg[] msgList = (CAANMsg[])inCBSMsg.getObject(ECC0021D010CBSMsg.ECC0021D010CBSMSG3LIST);
									CAANMsg msg = msgList[i];
									msg.set(ECC0021D010CBSMsg3List.EFILE_KANRI_NO_ERR, "EL");
									// 2012/11/21 FST_mukuo)エラー設定値項目ミス修正 end
									inCBSMsg.set(ECC0021D010CBSMsg.STATUS, StatusCodes.RELATION_ERR);
									return sendMailInfo;
								}
							}
						}
						throw jcce;
					}
				}
			}
			if(!chkNull(eFileMap))
			{
				// 2012/02/03 添付ファイル名の重複を許容する対応 start
				//sendMailInfo.put("TEMP_FILE_IF", eFileMap);
				sendMailInfo.put("TEMP_FILE_IF", eFileArray);
				// 2012/02/03 添付ファイル名の重複を許容する対応 end
			}
// ANK-2631-00-00 ADD START
			// メール送信ステータスフラグを取得
			String mailSendStatFlg = JCCModelCommon.getApplicationConst("MAIL_SEND_STAT_FLG");
			sendMailInfo.put("MAIL_SEND_STAT_FLG", mailSendStatFlg);
// ANK-2631-00-00 ADD END
		}
		catch (JCCFrameworkException jcce)
		{
			// JCCFrameworkExceptionをスロー
			throw new JCCFrameworkException("メールマスタ検索時にエラーが発生しました。", jcce);
		}
		return sendMailInfo;
	}
	
	/**
	 * <p>
	 * メール送信
	 * @param inMsg 処理対象のメッセージキャリア
	 * @param con コネクション
	 * @param sendMailInfo メール送信情報
	 * @return boolean
	 * </p>
	 * @throws Exception 
	 */
	private static boolean sendMail(CAANMsg inCBSMsg, AgentDispatchContext inContext, HashMap<String, Object> sendMailInfo) throws Exception
	{
		Integer ret = 0;
		boolean result = true;
		String retStr = "";
		if(sendMailInfo == null)
		{
			throw new JCCFrameworkException("メール送信情報が未設定です。");
		}

		// v5.00.00 2013/12/20 メール送信情報ログ出力用送信先アドレス
		String[] toList = (String[]) sendMailInfo.get("MLAD_TO");
		String toAd = inCBSMsg.getString(ECC0021D010CBSMsg.MAIL_SEND_NO);
		if (toList != null) {
			for (String to : toList) {
				toAd += " <" + to + ">";
			}
		}

		try
		{
			// v5.00.00 2013/12/20 メール送信情報ログ出力
			JSYejbLog.outlog(inContext, JSYejbLog.EXECUTION, JECC0021D010TPMA.class, "[JECC0021D010TPMA] メール送信部品呼出：" + toAd);
			ret = JCCSendMailUtil.sendMail(sendMailInfo);
			retStr = JCCSendMailUtil.getSendParamErrMsg(ret);
			if("".equals(retStr) == false)
			{
				throw new JCCFrameworkException(retStr);
			}
		}
		catch(Exception e)
		{
			String msg = e.toString();
			String chkSendErr1 = "SendFailedException";
			String chkSendErr2 = "MessagingException";
			
			// v5.00.00 2013/12/20 メール送信情報ログ出力
			JSYejbLog.outlog(inContext, JSYejbLog.EXECUTION, JECC0021D010TPMA.class, "[JECC0021D010TPMA] メール送信エラー：" + e.toString());
			
			if(msg.indexOf(chkSendErr1) >= 0 || msg.indexOf(chkSendErr2) >= 0)
			{
				// メール送信失敗（例外処理なし）
				return false;
			}
			else
			{
				throw e;
			}
		}
		// v5.00.00 2013/12/20 メール送信情報ログ出力
		JSYejbLog.outlog(inContext, JSYejbLog.EXECUTION, JECC0021D010TPMA.class, "[JECC0021D010TPMA] メール送信正常終了：" + inCBSMsg.getString(ECC0021D010CBSMsg.MAIL_SEND_NO));
		return result;
	}
	
	/**
	 * 現在時刻、カレント、履歴レコードから現在有効なレコードを取得します
	 * @param date 現在時刻
	 * @param cur カレントレコード
	 * @param his 履歴レコード
	 * @param beforeKey 適用年月日を取得するためのキー
	 * @param afterKey 終了年月日を取得するためのキー
	 * @return 該当レコード。存在しない場合はnull
	 */
	private static CAANMsg getAvailableRecord(String date, CAANMsg cur, CAANMsg[] his, String beforeKey, String afterKey)
	{
		int beforeDate = 0;
		int afterDate = 0;
		int nowDate = Integer.parseInt(date);
		String tmpStr = null;
		
		// カレントレコードの適用年月日と終了年月日を取得
		if(chkNull(cur) == false)
		{
			beforeDate = Integer.parseInt(cur.getString(beforeKey));
			tmpStr = cur.getString(afterKey);
			// 終了日は必須ではないので、指定無しの場合は最大存在しうる最大の日付を設定
			if(chkNull(tmpStr))
			{
				tmpStr = "99991231";
			}
			afterDate = Integer.parseInt(tmpStr);
			// 指定の日付がカレントレコードで有効な場合は、そのレコードを復帰
			if(nowDate >= beforeDate && nowDate <= afterDate)
			{
				return cur;
			}
		}
		// 見つからない場合は履歴レコードからも検索
		if(chkNull(his) == false)
		{
			for(int i = 0; i < his.length; i++)
			{
				// 適用、終了年月日を再取得
				beforeDate = Integer.parseInt(his[i].getString(beforeKey));
				tmpStr = his[i].getString(afterKey);
				if(chkNull(tmpStr))
				{
					tmpStr = "99991231";
				}
				afterDate = Integer.parseInt(tmpStr);
				// 指定の日付が有効な履歴レコードを復帰
				if(nowDate >= beforeDate && nowDate <= afterDate)
				{
					return his[i];
				}
			}
		}
		// 有効レコード無し
		return null;
	}
	
	/**
	 * メール送信量制限チェックを行う
	 * @param inCBSMsg 
	 * @param inContext 
	 * @param sendMailInfo メール送信情報
	 * @return boolean
	 */
	private static boolean chkMailtSendQuantity(CAANMsg inCBSMsg, AgentDispatchContext inContext, HashMap<String, Object> sendMailInfo) throws Exception
	{
// 20130417 FST)Yanagihara 送信量制御の対象外とするCallTypeを設定する。start
		String callType = (String)inContext.getClientHashMapObjectByKey(JCMConstants.CALL_TYPE_KEY);
		String mailSendNonTargetCalltype = JCCModelCommon.getApplicationConst("MAIL_SEND_NON_TARGET_CALLTYPE");
		if(null == mailSendNonTargetCalltype)
		{
			// デフォルトはバックヤードとバッチとする。
			mailSendNonTargetCalltype = "0,4";
		}
		String[] targetCalltype = (String[])mailSendNonTargetCalltype.split(",");
		for(int i=0;i<targetCalltype.length;i++)
		{
			if(targetCalltype[i].equals(callType))
			{
				// 対象外のCallTypeの場合はtrueを返却
				return true;
			}
		}
// 20130417 FST)Yanagihara 送信量制御の対象外とするCallTypeを設定する。end
		
		Connection con = JSYejbConnection.getConnection(CC0021ETMsg.getTableName());
		StringBuffer sql = new StringBuffer();
		
		ArrayList<String> chkAdrArray = new ArrayList<String>();
		
		// チェック間隔時間（秒）をAPLConstから取得（デフォルト60秒）
		String mailSendintervalTime = JCCModelCommon.getApplicationConst("MAIL_SEND_INTERVAL_TIME");
		if(null == mailSendintervalTime)
		{
			mailSendintervalTime = "60";
		}
		else if("0".equals(mailSendintervalTime))
		{
			return true;
		}
		
		// 最大送信量をAPLConstから取得（デフォルト2件）
		String maxMailSendNum = JCCModelCommon.getApplicationConst("MAX_MAIL_SEND_NUM");
		if(null == maxMailSendNum || "0".equals(maxMailSendNum))
		{
			// 20130417 FST)Yanagihara 送信量制御デフォルト値修正 start
			//maxMailSendNum = "2";
			maxMailSendNum = "10";
			// 20130417 FST)Yanagihara 送信量制御デフォルト値修正 end
		}
		
		// 現在時刻から間隔時間を引いた時間を基準時間とする
		String nowDtm = inCBSMsg.getString(ECC0021D010CBSMsg.OPERATEDATETIME);
		DateFormat nowDtmFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		Date nowDate = new Date(nowDtmFormat.parse(nowDtm).getTime() - (Long.parseLong(mailSendintervalTime) * 1000));
		String chkDtm = nowDtmFormat.format(nowDate);

		// 送信メールアドレスからIN句を組立て
		String[] toAdrList  = (String[])sendMailInfo.get("MLAD_TO");
		int mailCount = getLength(toAdrList);
		
		// SQL文の組み立て
		sql.append("SELECT CC0131.MLAD ")
			.append("FROM ")
			.append("    CC_T_MLAD CC0131 ")
			.append("    INNER JOIN CC_T_MAIL_SEND CC0021 ")
			.append("    ON CC0131.MAIL_SEND_NO = CC0021.MAIL_SEND_NO ")
			.append("    AND CC0021.MAIL_SEND_PATTERN_CD = '01' ")
			.append("    AND CC0021.MAIL_SEND_STAT = '002' ")
			.append("    AND CC0021.MAIL_SEND_JSSI_DTM >= ? ")
			.append("    AND CC0021.MK_FLG = '0'")
			.append("WHERE ")
			.append("CC0131.MLAD IN( ");
		for (int i = 0; i < mailCount; i++)
		{
			if (i != 0)
			{
				sql.append(",");
			}
			sql.append("?");
		}
		sql.append(")")
			.append(" AND CC0131.MLAD_SET_FIELD_CD = '01' ")
			.append(" AND CC0131.MK_FLG = '0'");

		PreparedStatement stmt = null;
		ResultSet rs = null;
		try
		{
			// PreparedStatementの設定
			stmt = con.prepareStatement(sql.toString());
			// v8.00.00 出力ログ追加
			JSYejbLog.println(JSYLogBase.DBACCESS, JECC0021D010TPMA.class, sql.toString());

			// バインド変数の設定
			CAANJDBCUtil.setParam(stmt, 1, chkDtm);
			for (int i = 0; i < getLength(toAdrList); i++)
			{
				int offset = i + 2;
				CAANJDBCUtil.setParam(stmt, offset, toAdrList[i]);
			}
			
			long dt = (new Date()).getTime();
			rs = stmt.executeQuery();
			// v8.00.00 出力ログ追加
			JSYejbLog.outlog(inContext, JSYejbLog.EXECUTION, JECC0021D010TPMA.class, "[JECC0021D010TPMA] メール送信量制限チェックSQL：所要時間=" + ((new Date()).getTime() - dt));

			// DBから取得したメールアドレスをチェック用のリストに格納
			while(rs.next())
			{
				chkAdrArray.add(rs.getString(CC0131CBMMsg.MLAD));
			}
			
			// 送信したい全メールアドレスのリストを作る
			ArrayList<String> allAdr = new ArrayList<String>();
			allAdr.addAll(new ArrayList<String>(Arrays.asList(toAdrList)));
			
			// 送信したいメールアドレスが許容の送信量の範囲内か確認する
			for(int i = 0; i < allAdr.size(); i++)
			{
				if(getStrListCnt(chkAdrArray, allAdr.get(i)) >= Integer.parseInt(maxMailSendNum))
				{
					Object JECC0021D010TPMA = new JECC0021D010TPMA();
					StringBuffer strbuf = new StringBuffer();
					strbuf.append("メールリアルタイム送信の送信量制限のため、メールが送信されませんでした。")
						.append("同一アドレスに送信できるメール送信量は")
						.append(mailSendintervalTime)
						.append("秒間に")
						.append(maxMailSendNum)
						.append("通までです。")
						.append("メール送信番号:[")
						.append(inCBSMsg.getString(ECC0021D010CBSMsg.MAIL_SEND_NO))
						.append("]／対象メールアドレス:")
						.append(allAdr.toString());
					JSYejbLog.outlog(inContext, JSYejbLog.ERROR, JECC0021D010TPMA.getClass(), strbuf.toString());
					return false;
				}
			}
		}
		// SQLExceptionが発生した場合
		catch (SQLException sqle)
		{
			// JCCFrameworkExceptionをスロー
			throw new JCCFrameworkException("メール送信量制御判定時のテーブルアクセスでエラーが発生しました。", sqle);
		}
		// クローズ
		finally
		{
			if (null != rs)
			{
				rs.close();
			}
			if (null != stmt)
			{
				stmt.close();
			}
			if(null != con)
			{
				CAANConnectionMgr.getInstance().close(con);
			}
		}
		
		return true;
	}
	
	/**
	 * 配列サイズの取得
	 * 
	 * @param メールアドレスの格納された配列
	 * @return 配列数
	 */
	private static int getLength(String[] mladList)
	{
		if(null == mladList)
		{
			return 0;
		}
		return mladList.length;
	}
	
	/**
	 * 配列中に任意の文字列の含まれている個数を取得する
	 * 
	 * @param srcStrList 検索元の配列
	 * @param searchStr 検索したい文字列
	 * @return 存在数
	 */
	private static int getStrListCnt(ArrayList<String> srcStrList, String searchStr)
	{
		int cnt = 0;
		if(srcStrList.contains(searchStr) == false)
		{
			return 0;
		}
		for(int i = 0; i < srcStrList.size(); i++)
		{
			if(srcStrList.get(i).equals(searchStr))
			{
				cnt++;
			}
		}
		return cnt;
	}
	
	/**
	 * 文字列中に存在するの任意の文字列の個数を取得する
	 * @param srcStr 検索元の文字列
	 * @param searchStr 検索したい文字列
	 * @return 存在数
	 */
	private static int getStrCnt(String srcStr, String searchStr)
	{
		int cnt = 0;
		if(chkNull(srcStr) || chkNull(searchStr))
		{
			return 0;
		}
		String tmpStr = srcStr;
		
		while(tmpStr.indexOf(searchStr) != -1)
		{
			cnt++;
			tmpStr = tmpStr.substring(tmpStr.indexOf(searchStr) + searchStr.length());
		}
		return cnt;
	}
	
	/**
	 * オブジェクトに値が設定されているか判定する
	 * <br>
	 * @param arg0 判定するオブジェクト
	 * @return オブジェクトに値が設定されていない場合はtrue
	 */
	private static boolean chkNull(Object arg0) 
	{
		if (arg0 == null) 
		{
			return true;
		}
		else
		{
			if(arg0 instanceof CAANMsg[])
			{
				CAANMsg[] arg1 = (CAANMsg[])arg0;
				if(arg1.length == 0)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			else if(arg0.toString().length() == 0)
			{
				return true;
			}
		}

		return 0 == arg0.toString().length();
	}
}