/////////////////////////////////////////////////////////////////
//Copyright (C) 2005 NTT CORPORATION.
//
//	LO構成変更ツールクラス
//
//		変更履歴
//			2005.02.17 新規作成  梅原 浩司
//			2005.04.30 Method用パラメータ追加　koji
//
//	機能
//
//	このクラスはLO構成変更ツールのクラスです。
//
////////////////////////////////////////////////////////////////

package jp.co.ntt.lms.xmf.tools.xmo.lorelation;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.util.*;

import jp.co.ntt.lms.xmf.tools.ToolBase;
import jp.co.ntt.lms.xmo.LoRelation.LoRelationClient;
import jp.co.ntt.lms.xmo.Lo.LoClient;
import jp.co.ntt.lms.xmo.util.HtmlEscape;
import jp.co.ntt.lms.xmo.Environment;
import jp.co.ntt.lms.lo.LoTopClient;
import jp.co.ntt.lms.lo.PropagateRelationRecord;
import jp.co.ntt.lms.xmo.MessageData;
import jp.co.ntt.lms.xmo.Base.XMSBaseClient;
import jp.co.ntt.lms.xmo.Lo.LoData;
import jp.co.ntt.lms.xmf.common.CommonFunction;

/**
 *  LO構成変更ツールクラス
 * 
 *  このクラスはLO構成変更ツールのクラスです。
 * 
 *  @author 梅原 浩司
 *  @version 1.0
 */
public class LoRelationTool extends ToolBase {

	/**
	 * ChildLO文字列を取得する。
	 * @param request リクエストオブジェクト
	 * @param response レスポンスオブジェクト
	 * @return String ChildLO文字列
	 * @throws Exception
	 */
	public String getChildLoString(HttpServletRequest request, HttpServletResponse response)
	throws Exception 
	{
		return getChildLoString(request, response, 0);
	}

	/**
	 * ChildLO文字列を取得する。
	 * @param request リクエストオブジェクト
	 * @param response レスポンスオブジェクト
	 * @param blnMethodFlag メソッドの場合 1
	 * @return String ChildLO文字列
	 * @throws Exception
	 */
	public String getChildLoString(HttpServletRequest request, HttpServletResponse response, int methodFlag)
	throws Exception 
	{
		boolean blnMethodFlag = (methodFlag == 1) ? true : false;
		
		// パラメータ取得
		String strParentID = request.getParameter( "ParentID" );

		LoRelationClient objXMO = null;
		int intLRResult = 0;	
		// Loサーバ名を取得する
		Environment objEnv = new Environment();
		String strLoServerName = objEnv.getLoServerName();

		try {
			// 送信文字列格納StringBuffer
			StringBuffer strGetLine = new StringBuffer();
			strGetLine.append( "<childlenlist>\n" );

			if(strParentID.equals(getContextString("LO_TREE_ROOT"))){
				// ログインしているユーザに管理アサインされているLOを取得します。
				// ログインユーザIDの取得
				String strUserID = (String)request.getSession().getAttribute(getContextString("USER_ID"));
				if(strUserID == null){
					return "err";
				}

				XMSBaseClient objXms = new XMSBaseClient();

				// ルートLOリスト検索処理(管理アサインされているものを検索)
				if(!objXms.searchRootLoList(strUserID, XMSBaseClient.MANAGE_TYPE )){
					return "err";
				}

				// 検索がうまくいった場合
				LoData[] objLoList = objXms.getRootLoList();

				// ルート直下のMemberShipIDをセッションに格納するためのHashtableをインスタンス化
				Hashtable htbRootInfo = new Hashtable();
				// セッションに格納します。
				request.getSession().setAttribute(getContextString("LO_ROOT_INFO"), htbRootInfo);
				for( int j = 0; j < objLoList.length; j++ ) {
					LoData objLoData = objLoList[j];

					String strLoID = objLoData.getLoID();
					String strParentLoID = objLoData.getParentID();
					String strLoType = objLoData.getLoType();
					// セッション情報にLOIDをキーにして、MemberShipIDを格納します
					htbRootInfo.put(strLoID, strParentLoID);


					String strConclusionFlg = "off";
					String strPropagateFlg  = "off";
					String strActivePrereFlg = "off";
					String strPassivePrereFlg = "off";

					// 完結要件を取得します。
					LoClient objLo = new LoClient();
					String strConclusion = "";
					String strPrere = "";

					// LOXMOクライアントのインスタンスを生成します
					LoClient objLoClient = new LoClient();
					// ChildLOIDを検索条件に設定します
					objLoClient.setWhereLoID( strLoID );

					// 検索処理実行
					if( !objLoClient.select() ) {
						// 検索処理に失敗した場合
						// ここにエラー処理を記述する
						// 今は特に何もしない
						return "err";
					}

					if( objLoClient.next() ) {
						// 完結要件の取得
						strConclusion = objLoClient.getConclusion();
						// 前提条件の取得
						strPrere = objLoClient.getPrere();
					}
					
					if ( strConclusion != null && strConclusion.equals("") == false ){
						strConclusionFlg = "on";
					}
					// LOタイプがコンテナの場合、配下に前提加設定LOや前提条件被設定LOがあるかチェックする。
					int intFlg = 0;
					if(strLoType.equals("0")){
						LoRelationClient objLoRelation = new LoRelationClient();
						objLoRelation.setMethodFlag(blnMethodFlag);
						String strMaterialID = strParentLoID + strLoID;
						boolean boolRet = objLoRelation.checkUnderPrere(strMaterialID);
						// 前提条件テーブル検索エラー
						if(!boolRet){
							return "err";
						}
						// 前提条件に設定されている場合、前提条件の被設定フラグを立てる。
						intFlg = objLoRelation.getCheckUnderPrere();
					}
					// 前提条件が設定されている場合、前提条件の加設定フラグを立てる。
					if (( strPrere != null && !strPrere.equals("") ) || intFlg == 1 || intFlg == 2 ){
						strActivePrereFlg = "on";
					}
					
					// 前提条件テーブルを検索して、前提条件に使用されているかチェックをします。
					objLo.clear();
					boolean boolRet = objLo.selectLOIDFromPrere(strLoID);
					// 前提条件テーブル検索エラー
					if(!boolRet){
						return "err";
					}
					// 前提条件に設定されている場合、前提条件の被設定フラグを立てる。
					String[] strLOIDList = objLo.getLOIDFromPrere();
					if(strLOIDList.length > 0 || intFlg == 1 || intFlg == 3){
						strPassivePrereFlg = "on";
					}

					LoTopClient objLoTop = new LoTopClient( strLoServerName, objLoData.getLoType() );

					// ステータス伝播レコード取得
					if ( !objLoTop.getPropagateRelation( strLoID ) ){
						// 検索がうまくいかなかった場合
						MessageData objMessage = objLoTop.getMessageData();
						response.sendRedirect( objMessage.getURL() );
					}
					PropagateRelationRecord[] records = objLoTop.getPropageteRecords();
					if ( records.length > 0 ){
						for( int i = 0; i < records.length; i++ ) {
							if( records[i].getLoID().equals( strParentLoID ) ) {
								strPropagateFlg = "on";
							}
						}
					}

					// 出力文字列の作成
					strGetLine.append( "<child title=\"" );
					strGetLine.append( HtmlEscape.escape(objLoData.getLoTytle()) );
					strGetLine.append( "\" iconid=\"group\" id=\"" );
					strGetLine.append( strLoID );
					strGetLine.append( "\" type=\"" );
					if(j == objLoList.length - 1){
						strGetLine.append( "L" + objLoData.getLoType() );
					}
					else{
						strGetLine.append( objLoData.getLoType() );
					}
					strGetLine.append( "\" conclusion=\"" );
					strGetLine.append( strConclusionFlg );
					strGetLine.append( "\" propagate=\"" );
					strGetLine.append( strPropagateFlg );
					strGetLine.append( "\" activeprere=\"" );
					strGetLine.append( strActivePrereFlg );
					strGetLine.append( "\" passiveprere=\"" );
					strGetLine.append( strPassivePrereFlg );
					strGetLine.append( "\" />\n" );
				}
			}
			else{
				// グループと人管理XMOの取得
				objXMO = new LoRelationClient();
				objXMO.setMethodFlag(blnMethodFlag);
				objXMO.setParentID( strParentID );

				if( !objXMO.select() ) {
					// 検索がうまくいかなかった場合
					if( objXMO.isErr() ) {
						// エラーの場合
						response.sendRedirect( objXMO.getURL() );
					}
					else {
						String strMessage =  objXMO.getMessage();
						response.sendRedirect( CommonFunction.getParamErrURL( strMessage, null, null ) );
					}
				}else{
					intLRResult = objXMO.getResultCount();	
				}
				// グループ管理XMOの取得
				LoClient objLo = new LoClient();
				String strLoType ="";

				int intCounter = 0;		
				while( objXMO.next() ) {
					intCounter++;		
					// グループIDの取得
					String strChildID = objXMO.getChildID();
					// グループIDを元にグループ名称を取得する
					objLo.clear();
					objLo.setWhereLoID( strChildID );
					if( objLo.select() ) {
						String strLoName = "";
						String strConclusionFlg = "off";
						String strPropagateFlg  = "off";
						String strActivePrereFlg = "off";
						String strPassivePrereFlg = "off";
						if( objLo.next() ) {
							strLoType = objLo.getLoType();
							strLoName = objLo.getLoTytle();

							// 完結要件を取得します。
							String strConclusion = "";
							String strPrere = "";
							// LOXMOクライアントのインスタンスを生成します
							LoClient objLoClient = new LoClient();
							// ChildLOIDを検索条件に設定します
							objLoClient.setWhereLoID( strChildID );

							// 検索処理実行
							if( !objLoClient.select() ) {
								// 検索処理に失敗した場合
								// ここにエラー処理を記述する
								// 今は特に何もしない
								return "err";
							}

							if( objLoClient.next() ) {
								// 完結要件の取得
								strConclusion = objLoClient.getConclusion();
								// 前提条件の取得
								strPrere = objLoClient.getPrere();
							}
							
							if ( strConclusion != null && strConclusion.equals("") == false ){
								strConclusionFlg = "on";
							}
							// LOタイプがコンテナの場合、配下に前提加設定LOや前提条件被設定LOがあるかチェックする。
							int intFlg = 0;
							if(strLoType.equals("0")){
								LoRelationClient objLoRelation = new LoRelationClient();
								objLoRelation.setMethodFlag(blnMethodFlag);
								String strMaterialID = strParentID + strChildID;
								boolean boolRet = objLoRelation.checkUnderPrere(strMaterialID);
								// 前提条件テーブル検索エラー
								if(!boolRet){
									return "err";
								}
								// 前提条件に設定されている場合、前提条件の被設定フラグを立てる。
								intFlg = objLoRelation.getCheckUnderPrere();
							}
							// 前提条件が設定されている場合、前提条件の加設定フラグを立てる。
							if (( strPrere != null && !strPrere.equals("") ) || intFlg == 1 || intFlg == 2 ){
								strActivePrereFlg = "on";
							}
							// 前提条件テーブルを検索して、前提条件に使用されているかチェックをします。
							objLo.clear();
							boolean boolRet = objLo.selectLOIDFromPrere(strChildID);
							// 前提条件テーブル検索エラー
							if(!boolRet){
								return "err";
							}
							// 前提条件に設定されている場合、前提条件の被設定フラグを立てる。
							String[] strLOIDList = objLo.getLOIDFromPrere();
							if(strLOIDList.length > 0 || intFlg == 1 || intFlg == 3){
								strPassivePrereFlg = "on";
							}

							LoTopClient objLoTop = new LoTopClient( strLoServerName, strLoType );

							// ステータス伝播レコード取得
							if ( !objLoTop.getPropagateRelation( strChildID ) ){
								// 検索がうまくいかなかった場合
								MessageData objMessage = objLoTop.getMessageData();
								response.sendRedirect( objMessage.getURL() );
							}
							PropagateRelationRecord[] records = objLoTop.getPropageteRecords();
							if ( records.length > 0 ){
								for( int i = 0; i < records.length; i++ ) {
									if( records[i].getLoID().equals( strParentID ) ) {
										strPropagateFlg = "on";
									}
								}
							}
						}
							//同階層の最終レコードの場合
							if(intCounter==intLRResult){
								strLoType = "L" + strLoType;
							}

						//コンテナとその他LOを区別するためstrLoTypeを追加
						strGetLine.append( "<child title=\"" );
						strGetLine.append( HtmlEscape.escape(strLoName) );
						strGetLine.append( "\" iconid=\"group\" id=\"" );
						strGetLine.append( strChildID );
						strGetLine.append( "\" type=\"" );
						strGetLine.append( strLoType );
						strGetLine.append( "\" conclusion=\"" );
						strGetLine.append( strConclusionFlg );
						strGetLine.append( "\" propagate=\"" );
						strGetLine.append( strPropagateFlg );
						strGetLine.append( "\" activeprere=\"" );
						strGetLine.append( strActivePrereFlg );
						strGetLine.append( "\" passiveprere=\"" );
						strGetLine.append( strPassivePrereFlg );
						strGetLine.append( "\" />\n" );
					}
					else {
						// 検索がうまくいかなかった場合
						if( objLo.isErr() ) {
							// エラーの場合
							response.sendRedirect( objLo.getURL() );
						}
						else {
							String strMessage =  objLo.getMessage();
							response.sendRedirect( CommonFunction.getParamErrURL( strMessage, null, null ) );
						}
					}
				}
			}	

			strGetLine.append( "</childlenlist>\n" );
			return strGetLine.toString();
		}
		catch( Exception e ) {
			e.printStackTrace();
			return "err";
		}
	}
	
	/**
	 * ChildMaterialの更新を行う。
	 * @param request リクエストオブジェクト
	 * @param response レスポンスオブジェクト
	 * @return String 成功："true"/失敗：エラーメッセージ
	 * @throws Exception
	 */
	public String updateChildMaterial(HttpServletRequest request, HttpServletResponse response)
	throws Exception 
	{
		return updateChildMaterial(request, response, 0);
	}
	
	/**
	 * ChildMaterialの更新を行う。
	 * @param request リクエストオブジェクト
	 * @param response レスポンスオブジェクト
	 * @param blnMethodFlag メソッドの場合true
	 * @return String 成功："true"/失敗：エラーメッセージ
	 * @throws Exception
	 */
	public String updateChildMaterial(HttpServletRequest request, HttpServletResponse response, int methodFlag)
	throws Exception 
	{
		boolean blnMethodFlag = (methodFlag == 1) ? true : false;
		//////////////////////////////////////////////////////////////////////////////////
		// パラメータ取得
		//	SendTargetRelationID	更新するMaterialID配列 必須
		//							配列内のMaterialIDは親ID^子IDのように"^"で区切られている
		//	ReceiveTargetRelationID	移動先のLoID	必須
		//							LoIDは親ID^子IDのように"^"で区切られている
		//	type					処理区分（1: 上へ 2: 中へ 3: 下へ) 必須
		//////////////////////////////////////////////////////////////////////////////////
		// 移動元マテリアルIDリストを取得する
		String[] strMaterialIDList = request.getParameterValues( "SendTargetRelationID" );
		// 移動先マテリアルIDを取得する
		String strReceiveMaterialID = request.getParameter("ReceiveTargetRelationID");
		// 処理区分を取得する
		String strType = request.getParameter("type");
		if( strMaterialIDList == null ) {
			String strMessage = "パラメータは不正です。";
			response.sendRedirect( CommonFunction.getParamErrURL( strMessage, null, null ) );
		}

		if( strReceiveMaterialID == null ) {
			String strMessage = "パラメータは不正です。";
			response.sendRedirect( CommonFunction.getParamErrURL( strMessage, null, null ) );
		}

		//処理区分が数値ではない場合
		int intType = 0;
		try{
			intType = new Integer(strType).intValue();
		}
		catch(NumberFormatException ne){
			String strMessage = "パラメータは不正です。";
			response.sendRedirect( CommonFunction.getParamErrURL( strMessage, null, null ) );
		}
		//処理区分が1、2、3ではない場合
		if( intType < 1 || intType > 3 ) {
			String strMessage = "パラメータは不正です。";
			response.sendRedirect( CommonFunction.getParamErrURL( strMessage, null, null ) );
		}

		// ダミーの親ID(lotreeroot)を見つけたらDBの親ID(LO〜)に変換する
		for( int i = 0; i < strMaterialIDList.length; i++ ) {
			String strMaterialID = strMaterialIDList[i];
			if(strMaterialID.indexOf(getContextString("LO_TREE_ROOT")) != -1) {
				int intIndex = getContextString("LO_TREE_ROOT").length();
				String strTempChildID = strMaterialID.substring(intIndex + 1);
				Hashtable htbRootInfo = (Hashtable)request.getSession().getAttribute(getContextString("LO_ROOT_INFO"));
				// DBの親ID + 子供ID = メンバID
				strMaterialID = (String)htbRootInfo.get(strTempChildID) + "^" + strTempChildID;
			}
			// 元の配列の値を新しく作成したマテリアルIDで置き換える
			strMaterialIDList[i] = strMaterialID;
		}
		// ダミーの親ID(grouptreeroot)を見つけたらDBの親ID(LO〜)に変換する
		if(strReceiveMaterialID.indexOf(getContextString("LO_TREE_ROOT")) != -1) {
			int intIndex = getContextString("LO_TREE_ROOT").length();
			String strTempChildID = strReceiveMaterialID.substring(intIndex + 1);
			Hashtable htbRootInfo = (Hashtable)request.getSession().getAttribute(getContextString("LO_ROOT_INFO"));
			// DBの親ID + 子供ID = マテリアルID
			strReceiveMaterialID = (String)htbRootInfo.get(strTempChildID) + "^" + strTempChildID;
		}

		LoRelationClient objRe = new LoRelationClient();
		objRe.setMethodFlag(blnMethodFlag);
		try {
			// グループと人XMOの移動処理をコールする
			if( !objRe.transfer(strMaterialIDList, strReceiveMaterialID, new Integer(strType).intValue() ) ) {
				// 削除がうまくいかなかった場合
				if( objRe.isErr() ) {
					// エラーの場合
					return "err";
				}
				else {
					String strMessage =  objRe.getMessage();
					return "warn^" + strMessage;
				}
			}
			return "true";
		}
		catch( Throwable e ) {
			return e.getMessage();
		}
	}
	
	/**
	 * LOの複製を行う。
	 * @param request リクエストオブジェクト
	 * @param response レスポンスオブジェクト
	 * @return String 成功："true"/失敗：エラーメッセージ
	 * @throws Exception
	 */
	public String copyLoRelation(HttpServletRequest request, HttpServletResponse response)
	throws Exception 
	{
		return copyLoRelation(request, response, 0);
	}
	
	/**
	 * LO/メソッドの複製を行う。
	 * @param request リクエストオブジェクト
	 * @param response レスポンスオブジェクト
	 * @param blnMethodFlag メソッドの場合true
	 * @return String 成功："true"/失敗：エラーメッセージ
	 * @throws Exception
	 */
	public String copyLoRelation(HttpServletRequest request, HttpServletResponse response, int methodFlag)
	throws Exception 
	{
		boolean blnMethodFlag = (methodFlag == 1) ? true : false;
		//////////////////////////////////////////////////////////////////////////////////
		// パラメータ取得
		//	SendTargetRelationID	更新するMaterialID配列 必須
		//							配列内のMaterialIDは親ID^子IDのように"^"で区切られている
		//	ReceiveTargetRelationID	移動先のLoID	必須
		//							LoIDは親ID^子IDのように"^"で区切られている
		//	type					処理区分（1: 上へ 2: 中へ 3: 下へ) 必須
		//////////////////////////////////////////////////////////////////////////////////
		// 複製元マテリアルIDリストを取得する
		String[] strMaterialIDList = request.getParameterValues( "SendTargetRelationID" );
		// 複製先マテリアルIDを取得する
		String strReceiveMaterialID = request.getParameter("ReceiveTargetRelationID");
		// 処理区分を取得する
		String strType = request.getParameter("type");
		if( strMaterialIDList == null ) {
			String strMessage = "パラメータは不正です。";
			response.sendRedirect( CommonFunction.getParamErrURL( strMessage, null, null ) );
		}

		if( strReceiveMaterialID == null ) {
			String strMessage = "パラメータは不正です。";
			response.sendRedirect( CommonFunction.getParamErrURL( strMessage, null, null ) );
		}

		//処理区分が数値ではない場合
		int intType = 0;
		try{
			intType = new Integer(strType).intValue();
		}
		catch(NumberFormatException ne){
			String strMessage = "パラメータは不正です。";
			response.sendRedirect( CommonFunction.getParamErrURL( strMessage, null, null ) );
		}
		//処理区分が1、2、3ではない場合
		if( intType < 1 || intType > 3 ) {
			String strMessage = "パラメータは不正です。";
			response.sendRedirect( CommonFunction.getParamErrURL( strMessage, null, null ) );
		}

		// ダミーの親ID(lotreeroot)を見つけたらDBの親ID(LO〜)に変換する
		for( int i = 0; i < strMaterialIDList.length; i++ ) {
			String strMaterialID = strMaterialIDList[i];
			if(strMaterialID.indexOf(getContextString("LO_TREE_ROOT")) != -1) {
				int intIndex = getContextString("LO_TREE_ROOT").length();
				String strTempChildID = strMaterialID.substring(intIndex + 1);
				Hashtable htbRootInfo = (Hashtable)request.getSession().getAttribute(getContextString("LO_ROOT_INFO"));
				// DBの親ID + 子供ID = メンバID
				strMaterialID = (String)htbRootInfo.get(strTempChildID) + "^" + strTempChildID;
			}
			// 元の配列の値を新しく作成したマテリアルIDで置き換える
			strMaterialIDList[i] = strMaterialID;
		}
		// ダミーの親ID(lotreeroot)を見つけたらDBの親ID(LO〜)に変換する
		if(strReceiveMaterialID.indexOf(getContextString("LO_TREE_ROOT")) != -1) {
			int intIndex = getContextString("LO_TREE_ROOT").length();
			String strTempChildID = strReceiveMaterialID.substring(intIndex + 1);
			Hashtable htbRootInfo = (Hashtable)request.getSession().getAttribute(getContextString("LO_ROOT_INFO"));
			// DBの親ID + 子供ID = マテリアルID
			strReceiveMaterialID = (String)htbRootInfo.get(strTempChildID) + "^" + strTempChildID;
		}

		LoRelationClient objRe = new LoRelationClient();
		objRe.setMethodFlag(blnMethodFlag);
		try {
			//	strMaterialIDList		複製元マテリアルIDリスト
			//	strReceiveMaterialID	複製先マテリアルID
			// LORealtionXMOの複製処理をコールする
			// ログインIDをパラメータに設定します。
			String strLoginUserID = (String)request.getSession().getAttribute("userId");		// ログインユーザID
			objRe.setLoginID(strLoginUserID);
			if( !objRe.copy(strMaterialIDList, strReceiveMaterialID, new Integer(strType).intValue() ) ) {
				// エラーの場合
				//out.write("err");

				String strMessage =  objRe.getMessage();
				return "warn^" + strMessage;
			}

			return "true";
		}
		catch( Throwable e ) {
			return e.getMessage();
		}
	}
}
