/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JCCsvlGetOperationDateUtil
*	ソースファイル名：JCCsvlGetOperationDateUtil.java
*	作成者			：富士通
*	日付			：2011年04月13日
*＜機能概要＞
*	Web層運用日付取得部品
*   キーに対応するオンライン運用日付またはバッチ運用日付を返却します。
*   キーとしてnullを指定した場合、共通のオンライン運用日付または
*   共通のバッチ運用日付を返却します。
*   キーに対応する運用日付が定義されていない場合、nullを返却します。
*   運用日付はアプリケーションプロパティファイルの定義に基づいて、
*   アプリケーションプロパティファイルまたはデータベースから取得します。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2011/04/13	富士通		新規作成
*   v7.00.00    2014/02/13  FJ          運用日付をシステムから取得
*   v18.00.00   2015/08/11  FJ) 阪口   【ANK-2631-00-00】ワンストップ案件（ＳＴＥＰ１）※koptWebBからkoptWebAへコピー
*
**********************************************************************/

package eo.web.webview.commonOneStop;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;

import com.fujitsu.futurity.model.common.JCMAPLConstMgr;
import com.fujitsu.futurity.web.x31.X31BWebBusinessLogic;
import com.fujitsu.futurity.web.x31.X31CHashMap;
import com.fujitsu.futurity.web.x31.X31CWebConst;

import eo.common.util.JCCFrameworkException;

/**
 * 運用日付を返却する。
 *
 * @author FST
 * @version 1.0 
 */
public class JCCsvlGetOperationDateUtil {
	/**
	 *  システムパラメータ分類コード（DB検索用）
	 */
	private static final String VALUE_SYS_PARAM_BUNRUI_CD = "CD99992";
	/**
	 * サービスインターフェイス呼出用テンプレートID
	 */
	private static final String TEMPLATE_ID = "EZM0311A010";
	/**
	 * サービスインターフェイス呼出用ユースケースID
	 */
	private static final String USECASE_ID = "CCSV0004";
	/**
	 * サービスインターフェイス呼出用オペレーションID
	 */
	private static final String OPERATION_ID = "CCSV0004OP";

	/** サービスインターフェイス呼出用機能コードキー */
	private static final String FUNC_CODE = "func_code";

	/** サービスインターフェイス呼出用入出力パラメータキー */
	private static final String KEY_PARAM = "CCSV000401SC";

	/** サービスインターフェイス呼出用情報取得キー */
	private static final String KEY_LIST = "EZM0311A010CBSMsg1List";
	
	/** サービスインターフェイス呼出用:システムパラメータ分類キー */
	private static final String KEY_SYS_PARAM_BUNRUI_CD = "key_sys_param_bunrui_cd";

	/** サービスインターフェイス呼出用:システムパラメータIDキー */
	private static final String KEY_SYS_PARAM_ID = "key_sys_param_id";

	/** システムパラメータ 設定値取得キー */
	private static final String COLUMN_SYS_PARAM_SETTE_VALUE_1 = "sys_param_sette_value_1";

	/** セッション格納キー */
	private static final String KEY_SESSION = "SESSION_JCCsvlGetOperationDateUtil";

	/**
	 * アプリ定義の取得キー
	 */
	private static final String KEY_APL_OPEDATE_ENV = "OPEDATE_ENV";
	/**
	 *  コード区分（共通のオンライン運用日付）
	 */
	private static final String CD_DIV_ONLINE = "ODATE";
	/**
	 *  コード区分（共通のバッチ運用日付）
	 */
	private static final String CD_DIV_BAT    = "BDATE";
	/**
	 *  コード区分（個別のオンライン運用日付）
	 */
	private static final String CD_DIV_HEAD_ONLINE = "ODATE.";
	/**
	 *  コード区分（個別のオンライン運用日付）
	 */
	private static final String CD_DIV_HEAD_BAT    = "BDATE.";

	/**
	 * 引数としてキーを指定し、キーに対応するオンライン運用日付を返却します。<br>
	 * キーとしてnullを指定した場合、共通のオンライン運用日付を返却します。<br>
	 * オンライン運用日付はアプリケーションプロパティファイルの定義に基づいて取得します。<br>
	 * コード区分に対応する運用日付が定義されていない場合、nullを返却します。
	 * @param bl 業務ロジック
	 * @param key コード区分の"ODATE."以降の文字列、またはnull
	 * @return 運用日付（YYYYMMDD形式）
	 * @throws JCCFrameworkException
	 *      <ul>
	 *         <li>アプリケーションプロパティファイルの定義誤り</li>
	 *         <li>データベースの内容誤り</li>
	 *      </ul>
	 * @author FST）伊藤
	 */
	public static String getOpeDate(X31BWebBusinessLogic bl, String key) throws Exception
	{
		String cdDiv;
		
		// 業務ロジックがnullの場合
		if ( bl == null)
		{
			throw new JCCFrameworkException("パラメータ異常：業務ロジックが設定されていません");
		}
		// キーがnullの場合、"ODATE"をコード区分とする。
		// 2011/11/04 運用日付取得の強制本番モード対応 FST start
		if ( key == null || "3".equals(JCMAPLConstMgr.getString(KEY_APL_OPEDATE_ENV)))
		{
			cdDiv = CD_DIV_ONLINE;
		}
		// 2011/11/04 運用日付取得の強制本番モード対応 FST end
		// 上記以外の場合、"ODATE."とキーを組み合わせたコード区分を生成する。
		else
		{
			cdDiv = CD_DIV_HEAD_ONLINE + key;
		}
		// コード区分に対応する運用日付を返却する。
		return getOperationDate(bl, cdDiv);
	}
	
	/**
	 * 引数としてキーを指定し、キーに対応するバッチ運用日付を返却します。<br>
	 * キーとしてnullを指定した場合、共通のバッチ運用日付を返却します。<br>
	 * バッチ運用日付はアプリケーションプロパティファイルの定義に基づいて取得します。<br>
	 * コード区分に対応する運用日付が定義されていない場合、nullを返却します。
	 * @param bl 業務ロジック
	 * @param key コード区分の"BDATE."以降の文字列、またはnull
	 * @return 運用日付（YYYYMMDD形式）
	 * @throws JCCFrameworkException
	 *      <ul>
	 *         <li>アプリケーションプロパティファイルの定義誤り</li>
	 *         <li>データベースの内容誤り</li>
	 *      </ul>
	 * @author FST）伊藤
	 */
	public static String getBatOpeDate(X31BWebBusinessLogic bl, String key) throws Exception
	{
		String cdDiv;
		
		// 業務ロジックがnullの場合
		if ( bl == null)
		{
			throw new JCCFrameworkException("パラメータ異常：業務ロジックが設定されていません");
		}
		// キーがnullの場合、"BDATE"をコード区分とする。
		// 2011/11/04 運用日付取得の強制本番モード対応 FST start
		if ( key == null || "3".equals(JCMAPLConstMgr.getString(KEY_APL_OPEDATE_ENV)))
		{
			cdDiv = CD_DIV_BAT;
		}
		// 2011/11/04 運用日付取得の強制本番モード対応 FST end
		// 上記以外の場合、"BDATE."とキーを組み合わせたコード区分を生成する。
		else
		{
			cdDiv = CD_DIV_HEAD_BAT + key;
		}
		// コード区分に対応する運用日付を返却する。
		return getOperationDate(bl, cdDiv);
	}
	/**
	 * 引数としてコード区分を受け取り、オンライン運用日付またはバッチ運用日付を返却します。<br>
	 * 運用日付はアプリケーションプロパティファイルの定義に基いて取得します。<br>
	 * コード区分に対応する運用日付が定義されていない場合、nullを返却します。
	 * @param bl 業務ロジック
	 * @param cdDiv コード区分
	 * @return 運用日付（YYYYMMDD形式）
	 * @throws JCCFrameworkException
	 *      <ul>
	 *         <li>アプリケーションプロパティファイルの定義誤り</li>
	 *         <li>データベースの内容誤り</li>
	 *      </ul>
	 * @author FST）伊藤
	 */
 	private static String getOperationDate(X31BWebBusinessLogic bl, String cdDiv) throws Exception
	{
 		SimpleDateFormat formatYMD = new SimpleDateFormat("yyyyMMdd"); // 日付の正当性確認用オブジェクト
		String sProductionDateEnv;		// アプリ定義の運用日付取得元
		int iProductionDateEnv;			// アプリ定義の運用日付取得元
		String sOpeDate=null ;				// 運用日付（String型）
		Date dateOpeDate;				// 運用日付（Date型）
		String sFrom;					// 例外メッセージに埋め込む取得元
		X31CHashMap		mapSession;		// セッション領域から取得した値
		Object			oValue;			// セッション領域から取得した値
		
		HashMap<String, String> usecaseMap = null;			// ユースケースID格納用マップ
		HashMap<String, Object> inputMap = null;			// 設定値格納用マップ
		HashMap<String, Object> outputMap = null;			// 検索結果格納用マップ
		HashMap<String, String> paramMap = null;			// パラメータ格納用マップ
		
		//------------------------------------------------
		// (1) パラメータチェック処理
		//------------------------------------------------
		// 業務ロジックがnullの場合
		if (null == bl)
		{
			// 本来は通過し得ないルート
			throw new JCCFrameworkException("パラメータ異常：業務ロジックが設定されていません");
		}
		// コード区分がnullの場合
		if (null == cdDiv)
		{
			// 本来は通過し得ないルート
			throw new JCCFrameworkException(
			"パラメータ異常：コード区分が設定されていません");
		}

		//------------------------------------------------
		// (2) セッション領域参照処理
		//------------------------------------------------
		mapSession = bl.getSessionObject(KEY_SESSION);
		if (null != mapSession)
		{
			HashMap map = (HashMap)mapSession.get(true);
			if (null != map && map.containsKey(cdDiv))
			{
				oValue = (Object)map.get(cdDiv);
				if (oValue instanceof String)
				{
					sOpeDate = (String)oValue;
				}
				else
				{
					throw new JCCFrameworkException(
							 "セッション領域の誤り：["+cdDiv+"]の設定値が文字列ではありません");
				}

				// セッション領域の値が空白""であれば、nullを返却する。
				if ("".equals(sOpeDate))
				{
					return null;
				}
				// 上記以外の場合、セッション領域の値を
				else
				{
					return sOpeDate;
				}
			}	
		}
		
		//------------------------------------------------
		// (3) 定義取得処理
		//------------------------------------------------
		// アプリ定義の「運用日付取得元」を取得する。
		sProductionDateEnv = JCMAPLConstMgr.getString(KEY_APL_OPEDATE_ENV);
		// アプリ定義の「運用日付取得元」がnull以外の場合
		if ( sProductionDateEnv == null )
		{
			throw new JCCFrameworkException(
					 "APLConstの["+KEY_APL_OPEDATE_ENV+"]は省略できません");
		}
		// アプリ定義値の前後の空白を除去する。
		sProductionDateEnv = sProductionDateEnv.trim();
		// 「運用日付取得元」が「1:アプリケーションプロパティファイルから取得」の場合
		if      ( "1".equals(sProductionDateEnv) )
		{
			iProductionDateEnv = 1;
		}
		// 「運用日付取得元」が「2:データベースから取得」の場合
		else if ( "2".equals(sProductionDateEnv) )
		{
			iProductionDateEnv = 2;
		}
		// 2011/11/04 運用日付取得の強制本番モード対応 FST start
		// 「運用日付取得元」が「3:データベースから取得かつシステム個別コード指定無効」の場合
		else if ( "3".equals(sProductionDateEnv) )
		{
			iProductionDateEnv = 3;
		}
		// 2011/11/04 運用日付取得の強制本番モード対応 FST end
		// 「運用日付取得元」が上記以外の場合
		// v7.00.00 運用日付をシステムから取得 start
		else if ( "4".equals(sProductionDateEnv) )
		{
			iProductionDateEnv = 4;
		}
		// v7.00.00 運用日付をシステムから取得 end
		else
		{
			throw new JCCFrameworkException(
				      "APLConstで設定された["+KEY_APL_OPEDATE_ENV+"]は無効な値です（" + sProductionDateEnv + "）");
		}
		
		//------------------------------------------------
		// (4) 運用日付取得処理
		//------------------------------------------------
		// (4)-1 「運用日付取得元」が「1:アプリケーションプロパティファイルから取得」の場合
		if ( 1 == iProductionDateEnv )
		{
			// コード区分を指定して、アプリ定義の運用日付を取得する。
			sOpeDate = JCMAPLConstMgr.getString( cdDiv );
		}
		// v7.00.00 運用日付をシステムから取得 start
		else if(4 == iProductionDateEnv)
		{
			sOpeDate = formatYMD.format(new Date(System.currentTimeMillis()));
		}
		// v7.00.00 運用日付をシステムから取得 end
		// (4)-2 「運用日付取得元」が「2:データベースから取得」の場合
		else
		{

			usecaseMap = new HashMap<String, String>();
			paramMap = new HashMap<String, String>();
			inputMap = new HashMap<String, Object>();
			outputMap = new HashMap<String, Object>();

			// ユースケースID格納
			usecaseMap.put(X31CWebConst.TELEGRAM_INFO_USECASE_ID, USECASE_ID);

			// 機能コード設定
			paramMap.put(FUNC_CODE, "1");
			// ＫＥＹ＿システムパラメータ分類コード
			paramMap.put(KEY_SYS_PARAM_BUNRUI_CD, VALUE_SYS_PARAM_BUNRUI_CD);
			// ＫＥＹ＿システムパラメータID
			paramMap.put(KEY_SYS_PARAM_ID, cdDiv);
			
			inputMap.put(KEY_PARAM, paramMap);

			bl.invokeService(usecaseMap, inputMap, outputMap);
			
			HashMap<String, Object> workMap = (HashMap<String, Object>)outputMap.get(KEY_PARAM);
	
			ArrayList<HashMap<String,String>> workList = (ArrayList<HashMap<String,String>>)workMap.get(KEY_LIST);
			if (0 == workList.size())
			{
				sOpeDate = null;
			}
			else
			{
				Iterator<HashMap<String, String>> itr = workList.iterator();
				if(itr.hasNext())
				{
					HashMap<String, String> recMap = (HashMap<String, String>)itr.next();
					sOpeDate = recMap.get(COLUMN_SYS_PARAM_SETTE_VALUE_1);
				}
			}
		}
		// (4)-3 取得した運用日付がnull以外の場合
		if ( sOpeDate != null)
		{
			// 前後の空白を除去する。
			sOpeDate = sOpeDate.trim();
			//  String→Date→Stringと再変換することによって、
			// 変換結果がYYYYMMDD形式の実在する日時であることを確認する。
			try
			{
				dateOpeDate = formatYMD.parse(sOpeDate);
			}
			catch (ParseException pe)
			{
				// 取得元によって例外通知のメッセージを切替
				if ( 1 == iProductionDateEnv )
				{
					sFrom = "APLConstで設定された[";
				}
				else
				{
					sFrom = "システムパラメータで設定された[";
				}
				throw new JCCFrameworkException(
					      sFrom + cdDiv
					      + "]はyyyyMMdd形式または実在する日付ではありません（"
					      + sOpeDate + "）");
			}
			// 変換結果が変換前と一致しない場合
			if ( ! sOpeDate.equals(formatYMD.format(dateOpeDate)) )
			{
				// 取得元によって例外通知のメッセージを切替
				if ( 1 == iProductionDateEnv )
				{
					sFrom = "APLConstで設定された[";
				}
				else
				{
					sFrom = "システムパラメータで設定された[";
				}
				throw new JCCFrameworkException(
					      sFrom + cdDiv
					      + "]はyyyyMMdd形式または実在する日付ではありません（"
					      + sOpeDate + "）");
			}
		}
		
		//------------------------------------------------
		// (5) セッション領域更新処理
		//------------------------------------------------
		X31CHashMap<String, String>	map = new X31CHashMap<String, String>();
		// (5)-1 (4)で取得した運用日付がnull以外の場合
		if (null != sOpeDate)
		{
			// 引数の「コード区分」と、取得した「運用日付」でセッション領域を更新する。
			map.put(cdDiv, sOpeDate);
		}
		// (5)-2 (4)で取得した運用日付がnullの場合
		else
		{
			// 引数の「コード区分」と、空白""でセッション領域を更新する。
			map.put(cdDiv, "");
		}
		bl.setSessionObject(KEY_SESSION, map);
		
		//------------------------------------------------
		// (6) 復帰処理
		//------------------------------------------------

		return sOpeDate;
	}

	/**
	 * セッションクリア処理<br>
	 * 本クラスで設定した運用日付データをセッションクリアします。<br>
	 * @param bl 業務ロジック
	 */
 	public static void clearSession(X31BWebBusinessLogic bl)
	{
 		X31CHashMap mapSession = bl.getSessionObject(KEY_SESSION);
		if (null != mapSession)
		{
			mapSession.clear();
	 		bl.setSessionObject(KEY_SESSION, mapSession);
		}
	}

}
