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

//
//	LumpTreeクラス
//			変更履歴
//				2004.01.08	新規作成	五木田 泰史
//
package jp.co.ntt.lms.xmo.LumpInsert;

import jp.co.ntt.lms.xmo.XMOException;
import jp.co.ntt.lms.xmo.DataAccess;
import jp.co.ntt.lms.xmo.XMOTree;
import jp.co.ntt.lms.xmo.XMONode;
import jp.co.ntt.lms.xmo.People.PeopleClient;
import jp.co.ntt.lms.xmo.util.IdGenerator;
import jp.co.ntt.lms.xmo.Groups.GroupsClient;
import jp.co.ntt.lms.xmo.GroupAndPeople.GroupAndPeople;

import java.util.Vector;

/**
 * LumpTreeクラスです。<BR>
 * 一括登録用のインタフェースを提供します。<BR>
 *
 * @author Y.Gokita
 * @version 0.0.0.1 2004/01/08
 */
public class LumpTree
	implements LumpInsertMessage
{
	/**
	 * LumpGroupAndPeopleクラス
	 */
	private LumpGroupAndPeople mTop;

	/**
	 * 一括登録中に使用するデータアクセスクラス
	 */
	private DataAccess mobjDa;

	/**
	 * 一括登録ユーザリスト
	 */
	private Vector mvctUserList;

	/**
	 * コンストラクタです。
	 */
	public LumpTree()
	{
	}

	/**
	 * 先頭LumpGroupAndPeople設定<BR>
	 * 先頭LumpGroupAndPeopleから一括登録クラス<BR>
	 * 全体を表すことができる。<BR>
	 *
	 * @param LumpGroupAndPeople 先頭LumpGroupAndPeopleクラス
	 * @return void
	 */
	public void setTop(LumpGroupAndPeople objTop)
	{
		mTop = objTop;
	}

	/**
	 * 先頭LumpGroupAndPeople取得<BR>
	 * 先頭LumpGroupAndPeopleから一括登録クラス<BR>
	 * 全体を表すことができる。<BR>
	 * @param LumpGroupAndPeople 先頭LumpGroupAndPeopleクラス
	 * @return void
	 */
	public LumpGroupAndPeople getTop()
	{
		return mTop;
	}


	/**
	 * 一括登録ユーザリスト設定<BR>
	 *
	 * @param vctUserList 一括登録ユーザリスト
	 * @return void
	 */
	public void setUserList(Vector vctUserList)
	{
		mvctUserList = vctUserList;
	}

	/**
	 * 先頭LumpGroupAndPeopleを取得し、<BR>
	 * ツリー構造をDBに追加していく。<BR>
	 *
	 * @param String 開始グループ
	 * @param mobjDa データアクセスクラス
	 * @return void
	 */
	public void insert(String strStartGroup, DataAccess objDa)
		throws XMOException
	{

		if( objDa == null ) {
			// データアクセスクラスがnullの場合はエラーとする
			throw new XMOException( PARAM_WAR );
		}
		else {
			// 内部変数に格納
			mobjDa = objDa;
		}

		// 登録処理を再帰呼び出しする。
		// 子供カウント取得(個人の場合は0)
		int intCount = mTop.getChildCount();
		for( int i = 0; i < intCount; i++ ) {
			insert(mTop.getChild(i), strStartGroup);
		}

		// 登録後にXMLに記述されていないグループ・ユーザを削除します。
		deleteTree(strStartGroup);
	}

	/**
	 * LumpGroupAndPeople登録<BR>
	 * ツリー構造をDBに追加していく。<BR>
	 * 再帰呼出し<BR>
	 *
	 * @param LumpGroupAndPeople LumpGroupAndPeopleクラス
	 * @param String 開始グループ
	 * @param String メールフラグ
	 * @return void
	 */
	private void insert(LumpGroupAndPeople objGap,
						String strStartGroup)
		throws XMOException
	{
		// グループあるい個人クラスは追加
		objGap.insert(mobjDa, mvctUserList, strStartGroup);

		// 登録に失敗した場合はその後の処理は行わない。
		if( objGap.boolFailFlag ) {
			return;
		}

		// 子供カウント取得(個人の場合は0)
		int intCount = objGap.getChildCount();

		for(int i = 0; i < intCount; i++)
		{
			// 子供追加処理(再帰呼出し)
			insert(objGap.getChild(i), strStartGroup);

		}
	}

	/**
	 * 登録後にXMLに記述されていないグループ・ユーザを削除します。
	 */
	private void deleteTree(String strStartGroupID)
		throws XMOException
	{

		XMOTree objXMOTree = GroupAndPeople.mobjTree;

		if( objXMOTree != null ) {
			// 一括登録で登録・更新されたグループ・ユーザのメンバシップIDを取得
			Vector vecLumpMemberList = ((LumpGroup)mTop).getMemberIDList();

			int intChildCount = mTop.getChildCount();
			for( int i = 0; i < intChildCount; i++ ) {
				LumpGroupAndPeople objChild = mTop.getChild( i );

				XMONode objRoot = null;
				if( objChild instanceof LumpGroup ) {
					objRoot = objXMOTree.searchNode( ((LumpGroup)objChild).getGroupID() );
				}
				else {
					objRoot = objXMOTree.searchNode( ((LumpPeople)objChild).getUserID() );
				}
				deleteMember(objRoot, vecLumpMemberList);
			}
		}
	}

	/**
	 * 指定されたノード配下のメンバーで、一括登録で作成されなかった
	 * グループ・ユーザを削除します。
	 * @param XMONode
	 * @return Vector
	 */
	private void deleteMember(XMONode objNode, Vector vecLumpMemberList)
		throws XMOException
	{

		if( objNode == null ) {
			return;
		}
		String strMemberShipID = objNode.getID();
		if( vecLumpMemberList.contains(strMemberShipID) ) {
			// 一括登録メンバーに含まれていたら、再帰呼び出し
			int intIndex = objNode.getChildCount();
			for( int i = intIndex; i > 0; i-- ) {
				XMONode objChild = objNode.getChildNode(i-1);
				deleteMember( objChild, vecLumpMemberList );
			}
		}
		else {
			// 一括登録メンバーに含まれていなかったら削除
			deleteMember( strMemberShipID );
		}

	}

	/**
	 * 指定されたメンバーシップのグループ・ユーザを削除します。
	 * @param strMemberShipID
	 */
	private void deleteMember( String strMemberShipID )
			throws XMOException
	{


		String strParentID = null;
		String strChildID = null;

		try {
			// メンバシップIDをIDのサイズで親IDと子IDに分割する。
			strParentID = strMemberShipID.substring(0, IdGenerator.FIGURE_ID);
			strChildID = strMemberShipID.substring(IdGenerator.FIGURE_ID);

			if( strChildID.startsWith( "PE" ) == true ) {


				// ユーザ削除
				PeopleClient objPeople = new PeopleClient();
				objPeople.setDeleteParentID( strParentID );
				objPeople.setDeleteUserID( strChildID );

				// トランザクションの共有
				objPeople.setConnectionIndex( mobjDa.getConnectionIndex() );

				if( !objPeople.delete() ) {
					// 削除失敗
					throw new XMOException( objPeople.getMessageData() );
				}
			}
			else {

				// グループ削除
				GroupsClient objGroups = new GroupsClient();
				objGroups.setDeleteParentID( strParentID );
				objGroups.setDeleteSelectID( strChildID );

				// トランザクションの共有
				objGroups.setConnectionIndex( mobjDa.getConnectionIndex() );

				if( !objGroups.delete() ) {
					// 削除失敗
					throw new XMOException( objGroups.getMessageData() );
				}
			}
		}
		catch( XMOException xe ) {
			throw xe;
		}
		catch( Exception e ) {
			throw new XMOException( SYSTEM_ERR );
		}
	}

}

