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

//
// 期限回数つきアサインの最初に呼ばれるアクションクラス。
// 
//
//	変更履歴
//	2004/01/08 新規作成	T.Nishiki 

package jp.co.ntt.lms.xms.assign;

import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import jp.co.ntt.lms.xmo.Assignments.AssignmentsClient;
import jp.co.ntt.lms.xmo.Mail.MailConst;
import jp.co.ntt.lms.xms.framework.XmsBusinessAction;
import jp.co.ntt.lms.xms.framework.XmsException;
import jp.co.ntt.lms.xms.framework.XmsInnerException;
import jp.co.ntt.lms.xms.framework.XmsRequest;
import jp.co.ntt.lms.xms.framework.XmsResponse;
import jp.co.ntt.lms.xms.framework.XmsSystemException;
import jp.co.ntt.lms.xms.framework.XmsWarningException;
import jp.co.ntt.lms.xms.common.util.CommonUtil;
import jp.co.ntt.lms.xms.common.util.StringUtil;

/**
 * 期限回数つきアサインの最初に呼ばれるアクションクラス。<br>
 * @author T.Nishiki
 */
public class CustomAssignFirstAction extends XmsBusinessAction {

	/**
	 * リクエスト処理初期化メソッド<BR>
	 * @param xmsRequest リクエスト・オブジェクト。<br>
	 * @param xmsResponse レスポンス・オブジェクト。<br>
	 * @throws XmsException 処理中に例外が発生した場合
	 */
	protected void initProcessRequest(XmsRequest xmsRequest) throws XmsException {
	}

	/**
	 * リクエスト処理メソッド<BR>
	 * @param xmsRequest リクエスト・オブジェクト。<br>
	 * @param xmsResponse レスポンス・オブジェクト。<br>
	 * @throws XmsException 処理中に例外が発生した場合
	 */
	protected void processRequest(XmsRequest xmsRequest, XmsResponse xmsResponse)
		throws XmsException {

		CustomAssignParameterBean bean = null;
		CustomAssignInputBean inputBean = null;
		try {
			// セッションのクリア
			clearSession(xmsRequest);
			// パラメータBeanの生成
			bean = createBean(xmsRequest);
			// 指定パラメータに基づく値チェック
			inputBean = checkAssignment(bean);
			if (inputBean != null) {
				setInitialInputBean(xmsRequest, inputBean);
			}
			// Beanの設定
			xmsResponse.setBusinessBean(bean);
			// メールテンプレートに対する設定
			setInformationForTemplate(xmsRequest);
		} catch (XmsException e) {
			throw e;
		} catch (Exception e) {
			throw new XmsInnerException(e);
		}
	}

	/**
	 * リクエストパラメータから、CustomAssignParameterBeanを生成する。
	 * @param xmsRequest リクエスト・オブジェクト。
	 * @param xmsResponse
	 * @return 生成したオブジェクト。
	 * @throws XmsException パラメータに不足がある場合。
	 */
	private CustomAssignParameterBean createBean(XmsRequest xmsRequest) throws XmsException {
		// ＨＴＴＰリクエスト。
		HttpServletRequest request = null;
		// 対象教材親ＩＤ
		String parentLoId = null;
		// 教材ＩＤ
		String loId = null;
		// グループ／人パス
		String personnelPath = null;
		// グループ／人ＩＤ
		String personnelId = null;
		// グループ／人親ＩＤ
		String parentGroupId = null;
		// 教材パス
		String loPath = null;
		// 新規更新区別
		String operation = null;
		int intOperation = 0;

		// ＨＴＴＰセッションオブジェクト
		HttpSession session = null;
		// 仮想ルートコンテナ／グループＩＤ情報保持オブジェクト
		Hashtable htbRootInfo = null;

		// このメソッドの戻り値
		CustomAssignParameterBean bean = null;

		try {
			bean = new CustomAssignParameterBean();

			request = xmsRequest.getRequest();
			////////////////////////////////////////////////////////////////////
			// パラメータの取得
			// =================================================================
			// グループ／ユーザ、コンテナ／ＬＯのＩＤを取得
			parentLoId = request.getParameter(CustomAssignConstant.PARENT_LO_ID);
			loId = request.getParameter(CustomAssignConstant.LO_ID);
			personnelPath = request.getParameter(CustomAssignConstant.PERSONNEL_PATH);
			parentGroupId = request.getParameter(CustomAssignConstant.PARENT_GROUP_ID);
			personnelId = request.getParameter(CustomAssignConstant.PERSONNEL_ID);
			loPath = request.getParameter(CustomAssignConstant.LO_PATH);
			// =================================================================
			// グループ／人パスの組か教材パスがあれば、値を解釈する。
			if (StringUtil.isNullString(personnelPath) == false) {
				List personnelIdList = StringUtil.split(personnelPath, "/");
				parentGroupId = (String) personnelIdList.get(personnelIdList.size() - 2);
				personnelId = (String) personnelIdList.get(personnelIdList.size() - 1);
			} else if (StringUtil.isNullString(loPath) == false) {
				List loIdList = StringUtil.split(loPath, "/");
				parentLoId = (String) loIdList.get(loIdList.size() - 2);
				loId = (String) loIdList.get(loIdList.size() - 1);

			}
			// =================================================================
			// 送信したデータに欠損がある場合、Exception。
			if ((StringUtil.isNullString(parentLoId) == true)
				&& (StringUtil.isNullString(loId) == true)
				&& (StringUtil.isNullString(parentGroupId) == true)
				&& (StringUtil.isNullString(personnelId) == true)) {
				throw new XmsWarningException(CustomAssignConstant.KEY_MESSAGE_INVALID_PARAMETER);
			}
			// =================================================================
			// 仮想ルートコンテナ／グループを指定された場合の対応
			if ((parentGroupId.equals(CustomAssignConstant.GROUP_ID_TREE_ROOT) == true)
				|| (parentLoId.equals(CustomAssignConstant.LO_ID_TREE_ROOT) == true)) {

				// セッションの取得
				session = request.getSession(false);
				// 仮想ルート情報オブジェクトをセッションから取得
				htbRootInfo = (Hashtable)session.getAttribute(
							CustomAssignConstant.KEY_ASSIGN_ROOT_INFO);
				// 仮想ルートグループ
				if (parentGroupId.equals(CustomAssignConstant.GROUP_ID_TREE_ROOT)) {
					parentGroupId = (String)htbRootInfo.get(personnelId);
				}
				// 仮想ルートコンテナ
				if (parentLoId.equals(CustomAssignConstant.LO_ID_TREE_ROOT)) {
					parentLoId = (String)htbRootInfo.get(loId);
				}
			}

			////////////////////////////////////////////////////////////////////
			// 新規／更新区別
			operation = request.getParameter(CustomAssignConstant.NAME_OPERATE);
			intOperation = StringUtil.parseInt(operation, CustomAssignConstant.OPERATION_NEW);
			////////////////////////////////////////////////////////////////////
			// beanに設定
			bean.setOperation(intOperation);
			bean.setParentLoId(parentLoId);
			bean.setLoId(loId);
			bean.setParentGroupId(parentGroupId);
			bean.setPersonnelId(personnelId);

		} catch (XmsException e) {
			throw e;
		} catch (Exception e) {
			throw new XmsInnerException(e);
		}
		return bean;
	}

	/**
	 * 初期表示にあたり、あらかじめセッションの内容をクリアする。<br>
	 * @param xmsRequest リクエスト・オブジェクト。
	 */
	private void clearSession(XmsRequest xmsRequest) throws XmsException {

		try {
			// セッション情報の削除
			CommonUtil.removeSessionData(xmsRequest, CustomAssignConstant.KEYS_SESSION);
		} catch (XmsException e) {
			throw e;
		} catch (Exception e) {
			throw new XmsInnerException(e);
		}
	}

	/**
	 * パラメータの値に基づき、DBにデータがあるかチェックする。<br>
	 * 処理が新規に関わらず、データが存在する場合、処理は更新として入力情報Beanを戻します。
	 * @param bean パラメータ情報を含むデータオブジェクト。
	 * @return パラメータに基づき検索した結果、データオブジェクトが存在し、
	 *          処理区別が更新の場合、そのデータに基づく入力情報Bean。
	 * @throws XmsException 処理中に例外が発生した場合。
	 *                       処理が更新に関わらず、データが存在しない場合。
	 */
	private CustomAssignInputBean checkAssignment(CustomAssignParameterBean bean)
		throws XmsException {
		// メソッドの戻り値
		CustomAssignInputBean inputBean = null;
		// データアクセス用
		AssignmentsClient client = null;
		// 対象教材親ＩＤ
		String parentLoId = null;
		// 教材ＩＤ
		String loId = null;
		// グループ／人ＩＤ
		String personnelId = null;
		// グループ／人親ＩＤ
		String parentGroupId = null;
		// 新規更新区別
		int operation = 0;

		// マテリアルID（親教材ID＋教材ID)
		String materialId = null;
		// メンバシップID（親グループID+グループ／人ID)
		String memberShipId = null;
		try {
			// リクエストの情報を取得
			parentLoId = bean.getParentLoId();
			loId = bean.getLoId();
			parentGroupId = bean.getParentGroupId();
			personnelId = bean.getPersonnelId();
			operation = bean.getOperation();
			// クライアント生成
			materialId = parentLoId + loId;
			memberShipId = parentGroupId + personnelId;
			client = new AssignmentsClient();
			client.setWhereMaterialID(materialId);
			client.setWhereMemberShipID(memberShipId);
			client.select();

			if (client.next() == false) {
				// =============================================================
				// アサインデータが存在しない。
				// =============================================================
				// 更新の場合は、例外
				if (operation == CustomAssignConstant.OPERATION_UPDATE) {
					throw new XmsWarningException(
						CustomAssignConstant.KEY_MESSAGE_ASSIGN_NO_EXISTS);
				}
				inputBean = null;
			} else {
				// =============================================================
				// アサインデータが存在する。
				// =============================================================
				// 新規作成の場合は、更新処理に改める。
				if (operation == CustomAssignConstant.OPERATION_NEW) {
// 新規でデータがある場合、エラーとしていたロジックを、更新処理として継続する。
					operation = CustomAssignConstant.OPERATION_UPDATE;
					bean.setOperation(operation);
				}
				// 取得したアサインデータを初期値として設定
				inputBean = makeInputBean(client, bean);
			}
		} catch (XmsException e) {
			throw e;
		} catch (Exception e) {
			throw new XmsSystemException(e);
		}
		return inputBean;
	}

	/**
	 * データアクセス結果に基づき、入力画面Beanを作成する。<br>
	 * @param client データアクセス結果。
	 * @param parameterBean パラメータデータBean。
	 * @return 入力画面Bean。この値が画面の初期値として利用される。 
	 * @throws XmsException 処理中に例外が発生した場合。
	 */
	private CustomAssignInputBean makeInputBean(
		AssignmentsClient client,
		CustomAssignParameterBean parameterBean)
		throws XmsException {
		// メソッドの戻り値
		CustomAssignInputBean inputBean = null;
		// アサイン種別
		int assortType = 0;

		// 検索結果：学習権限
		String resultLearnAuthority = null;
		int intResultLearnAuthority = 0;
		// 検索結果：管理権限
		String resultManagementAuthority = null;
		int intManagementAuthority = 0;
		// 検索結果：学習開始日時
		Date resultOpeningDate = null;
		// 検索結果：学習終了日時
		Date resultClosingDate = null;
		// 検索結果：学習回数
		String resultStudyLimitCount = null;
		// 対象教材親ＩＤ
		String parentLoId = null;
		// 教材ＩＤ
		String loId = null;
		// グループ／人ＩＤ
		String personnelId = null;
		// グループ／人親ＩＤ
		String parentGroupId = null;
		// 新規更新区別
		int operation = 0;
		try {
			inputBean = new CustomAssignInputBean();
			inputBean.setPropertiesAsNew();
			//==================================================================
			// アサイン種別
			// 学習権限
			resultLearnAuthority = client.getLearnAuthority();
			intResultLearnAuthority =
				StringUtil.parseInt(
					resultLearnAuthority,
					CustomAssignConstant.CULUMN_VALUE_NO_AUTH_INT);
			// 管理権限
			resultManagementAuthority = client.getManagementAuthority();
			intManagementAuthority =
				StringUtil.parseInt(
					resultManagementAuthority,
					CustomAssignConstant.CULUMN_VALUE_NO_AUTH_INT);
			if (intManagementAuthority != 1) {
				// 管理権限がない場合、「学習」とする。
				assortType = CustomAssignConstant.ASSORT_TYPE_LEARN;
			} else if (intResultLearnAuthority == 1) {
				// 管理権限があり学習権限もある場合、「管理と学習」とする。
				assortType = CustomAssignConstant.ASSORT_TYPE_LEARN_MANAGE;
			} else {
				// 管理権限があり学習権限がない場合、「管理」とする。
				assortType = CustomAssignConstant.ASSORT_TYPE_MANAGE;
			}
			inputBean.setAssortType(assortType);
			//==================================================================
			// 学習開始日時
			resultOpeningDate = client.getOpeningDate();
			inputBean.setPeriodStartDate(resultOpeningDate);
			inputBean.setPeriodStartLimited(resultOpeningDate != null);
			//==================================================================
			// 学習終了日時
			resultClosingDate = client.getClosingDate();
			inputBean.setPeriodEndDate(resultClosingDate);
			inputBean.setPeriodEndLimited(resultClosingDate != null);
			//==================================================================
			// 学習回数
			resultStudyLimitCount = client.getStudyLimitCount();
			inputBean.setCountLimited(resultStudyLimitCount != null);
			inputBean.setStudyCount(resultStudyLimitCount);
			////////////////////////////////////////////////////////////////////
			// リクエストの情報を取得
			parentLoId = parameterBean.getParentLoId();
			loId = parameterBean.getLoId();
			parentGroupId = parameterBean.getParentGroupId();
			personnelId = parameterBean.getPersonnelId();
			operation = parameterBean.getOperation();
			//==================================================================
			// 入力画面Beanに設定
			inputBean.setParentLoId(parentLoId);
			inputBean.setLoId(loId);
			inputBean.setParentGroupId(parentGroupId);
			inputBean.setPersonnelId(personnelId);
			inputBean.setOperation(operation);

		} catch (Exception e) {
			throw new XmsSystemException(e);
		}
		return inputBean;
	}
	/**
	 * メールテンプレート用に情報を設定する。<br>
	 * 
	 * @param xmsRequest リクエスト・オブジェクト。
	 * @throws XmsException 処理中に例外が発生した場合。
	 */
	private void setInformationForTemplate(XmsRequest xmsRequest) throws XmsException {

		// HTTPリクエスト。
		HttpServletRequest request = null;
		// HTTセッション。
		HttpSession session = null;

		try {
			request = xmsRequest.getRequest();
			session = request.getSession(false);

			// メール種別を設定
			if (session != null) {
				session.setAttribute(
					CustomAssignConstant.KEY_MAIL_TYPE,
					MailConst.TYPE_ASSIGNMENTS);
			}
		} catch (Exception e) {
			throw new XmsInnerException(e);
		}
	}

	/**
	 * 入力フレームの初期値用にデータクラスをセッションに登録する。<br>
	 * @param xmsRequest リクエスト・オブジェクト。
	 * @param inputBean 入力項目データクラス。
	 * @throws XmsException 処理中に例外が発生した場合。
	 */
	private void setInitialInputBean(XmsRequest xmsRequest, CustomAssignInputBean inputBean)
		throws XmsException {
		HttpServletRequest request = null;
		HttpSession session = null;

		try {
			request = xmsRequest.getRequest();
			session = request.getSession(false);
			if (session != null) {
				session.setAttribute(CustomAssignConstant.KEY_INPUT_BEAN, inputBean);
			}
		} catch (Exception e) {
			throw new XmsInnerException(e);
		}
	}

}
