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

//
//	AD同期処理 Peopleマッピングクラス
//			変更履歴
//				2004.01.08	新規作成	            二條智文
//
package jp.co.ntt.lms.xmo.Ad;

import java.util.*;
import javax.naming.*;
import javax.naming.directory.*;

import jp.co.ntt.lms.xmo.util.*;
import jp.co.ntt.lms.xmo.People.PeopleTable;

/**
 * AD同期処理 Peopleマッピングクラス<BR>
 * @author T.Nijou
 * @version 2.0.1.0 2004/01/08
 */
public class ADCorpPeople extends ADCorpNode {

	// フィールド
	/** ユーザ名 */
	private String mstrUserName;
	/** パスワード */
	private String mstrPassword;
	/** 住所 */
	private String mstrAddress;
	/** 性別 */
	private String mstrSex;
	/** Eメール */
	private String mstrEMail;
	/** Eメール2 */
	private String mstrEMail2;
	/** 読みかた */
	private String mstrReadingName;
	/** 誕生日 */
	private String mstrBirthday;
	/** 電話番号 */
	private String mstrTel;
	/** コメント */
	private String mstrCustumMsgDir;
	/** 外部ID */
	private String mstrForeignID;
	/** ログインID */
	private String mstrLoginID;
	/** ADユーザID */
	private String mstrADUserID;

	// 性別コード定義
	private static final int SEX_MAN = 1;		// 男性
	private static final int SEX_WOMAN = 2;		// 女性
	private static final int SEX_UNKNOWN = 3;	// 不明

	// このエントリの連番
	private int mintIndex = 0;

	// 設定項目
	private ADCorpSetupData mobjSetup;

	// エントリ
	private SearchResult mobjResult;

	// デフォルト値定義
	private static final String AD_DEFAULT = "AD";

	/**
	 * コンストラクタです。<BR>
	 * @param SearchResult エントリ
	 * @param objSetup 設定データ
	 * @param intIndex 連番
	 * @exception ADCorpException
	 */
	public ADCorpPeople( SearchResult objResult, ADCorpSetupData objSetup, int intIndex )
		throws ADCorpException
	{
		if( objResult == null || objSetup == null ) {
			// パラメータ不正時は内部エラー
			throw new ADCorpException( ADCorpMessage.INNER_ERR );
		}

		mobjResult = objResult;
		mobjSetup = objSetup;
		mintIndex = intIndex;

		// フィールドマッピング処理
		fieldMapping();
	}

	/**
	 * 同期XMLを取得します。
	 * @return String 同期XML
	 */
	public String getXML() {

		// 桁あふれ対応
		roundB();

		StringBuffer sbXML = new StringBuffer();

		if( mobjParent == null ) {
			// 親ノードがnullのものはルートノード
			sbXML.append( "<?xml version=\"1.0\" encoding=\"Windows-31J\"?>\n" );
			sbXML.append( "<lump type=\"2\">\n" );
		}

		sbXML.append( "<people>\n" );

		// 必須フィールド
		// login_id、foreign_id、user_name、passwordの属性が設定されていない場合は
		// 更新フラグを設定する。
		sbXML.append( "<login_id" + makeUpFlag( mobjSetup.getPLoginID() ) + ">" + mstrLoginID + "</login_id>\n" );	// ログイン
		sbXML.append( "<foreign_id" + makeUpFlag( mobjSetup.getPForeignID() ) + ">" + mstrForeignID + "</foreign_id>\n" );			// 外部ID
		sbXML.append( "<user_name" + makeUpFlag( mobjSetup.getPName() ) + ">" + mstrUserName + "</user_name>\n" );			// ユーザ名
		sbXML.append( "<password" + makeUpFlag( mobjSetup.getPPassword() ) + ">" + mstrPassword + "</password>\n" );				// パスワード
		sbXML.append( "<ad_dn>" + mstrDN + "</ad_dn>\n" );							// DN
		sbXML.append( "<oid>" + mstrOid + "</oid>\n" );								// オブジェクトID

		// 任意フィールド
		if( mstrAddress != null ) {
			sbXML.append( "<contact_address>" + mstrAddress + "</contact_address>\n" );	// 住所
		}
		if( mstrSex != null ) {
			sbXML.append( "<sex>" + mstrSex + "</sex>\n" );								// 性別
		}
		if( mstrEMail != null ) {
			sbXML.append( "<contact_email>" + mstrEMail + "</contact_email>\n" );		// Eメール
		}
		if( mstrEMail2 != null ) {
			sbXML.append( "<contact_email2>" + mstrEMail2 + "</contact_email2>\n" );	// Eメール２
		}
		if( mstrReadingName != null ) {
			sbXML.append( "<reading_name>" + mstrReadingName + "</reading_name>\n" );	// 読みかた
		}
		if( mstrBirthday != null ) {
			sbXML.append( "<birthday>" + mstrBirthday + "</birthday>\n" );				// 誕生日
		}
		if( mstrTel != null ) {
			sbXML.append( "<contact_tel>" + mstrTel + "</contact_tel>\n" );				// 電話番号
		}
		if( mstrCustumMsgDir != null ) {
			sbXML.append( "<comment>" + mstrCustumMsgDir + "</comment>\n" );			// コメント
		}
		if( mstrADUserID != null ) {
			sbXML.append( "<ad_user_id>" + mstrADUserID + "</ad_user_id>\n" );			// ADユーザID
		}

		sbXML.append( "</people>\n" );

		if( mobjParent == null ) {
			// 親ノードがnullのものはルートノード
			sbXML.append( "</lump>\n" );
		}
		return new String(sbXML);
	}

	/**
	 * ユーザ名 を取得します。
	 * @return strUserName
	 */
	public String getUserName() {
		return mstrUserName;
	}

	/**
	 * パスワード を取得します。
	 * @return strPassword
	 */
	public String getPassword() {
		return mstrPassword;
	}

	/**
	 * 住所 を取得します。
	 * @return strAddress
	 */
	public String getAddress() {
		return mstrAddress;
	}

	/**
	 * 性別 を取得します。
	 * @return strSex
	 */
	public String getSex() {
		return mstrSex;
	}

	/**
	 * Eメール を取得します。
	 * @return strEMail
	 */
	public String getEMail() {
		return mstrEMail;
	}

	/**
	 * Eメール2 を取得します。
	 * @return strEMail2
	 */
	public String getEMail2() {
		return mstrEMail2;
	}

	/**
	 * 読みかた を取得します。
	 * @return strReadingName
	 */
	public String getReadingName() {
		return mstrReadingName;
	}

	/**
	 * 誕生日 を取得します。
	 * @return strBirthday
	 */
	public String getBirthday() {
		return mstrBirthday;
	}

	/**
	 * 電話番号 を取得します。
	 * @return strTel
	 */
	public String getTel() {
		return mstrTel;
	}

	/**
	 * コメント を取得します。
	 * @return strCustumMsgDir
	 */
	public String getCustumMsgDir() {
		return mstrCustumMsgDir;
	}

	/**
	 * 外部ID を取得します。
	 * @return strForeignID
	 */
	public String getForeignID() {
		return mstrForeignID;
	}

	/**
	 * ログインID を取得します。
	 * @return strLoginID
	 */
	public String getLoginID() {
		return mstrLoginID;
	}

	/**
	 * ADユーザID を取得します。
	 * @return strADUserID
	 */
	public String getADUserID() {
		return mstrADUserID;
	}

//---------------------------内部関数 ------------------------------------------
	/**
	 * フィールドマッピング処理
	 */
	private void fieldMapping()
		throws ADCorpException
	{

		try{
			Attributes attrs = mobjResult.getAttributes();
			if (attrs == null) {
				// 検索エラー
				throw new ADCorpSearchException();
			}

			Attribute attr = null;

			// ユーザ名の取得
			if( mobjSetup.getPName() != null &&
				!mobjSetup.getPName().equals("") ) {
				attr = attrs.get( mobjSetup.getPName() );
				if( attr != null ) {
					mstrUserName = getValue(attr);
				}
			}

			// パスワード名の取得
			if( mobjSetup.getPPassword() != null &&
				!mobjSetup.getPPassword().equals("") ) {
				attr = attrs.get( mobjSetup.getPPassword() );
				if( attr != null ) {
					mstrPassword = getValue(attr);
				}
			}

			// 住所名の取得(住所はカンマ(,)区切りで複数指定)
			if( mobjSetup.getPContactAddress() != null &&
				!mobjSetup.getPContactAddress().equals("") ) {

				StringTokenizer token = new StringTokenizer( mobjSetup.getPContactAddress(), "," );
				String strTemp = null;
				while( token.hasMoreElements() ) {
					attr = attrs.get( token.nextToken() );
					if( attr != null ) {
						strTemp = getValue(attr);
						if( strTemp != null && !strTemp.equals( "" ) ) {
							if( mstrAddress == null ) mstrAddress = "";
							mstrAddress += strTemp + ",";
						}
					}
				}
				if( mstrAddress != null && mstrAddress.length() > 0 ) {
					mstrAddress = mstrAddress.substring( 0, mstrAddress.length() - 1 );
				}

			}

			// 性別の取得
			if( mobjSetup.getPSex() != null &&
				!mobjSetup.getPSex().equals("") ) {
				attr = attrs.get( mobjSetup.getPSex() );
				if( attr != null ) {
					mstrSex = getValue(attr);
				}
			}

			// Eメールの取得
			if( mobjSetup.getPContactEmail() != null &&
				!mobjSetup.getPContactEmail().equals("") ) {
				attr = attrs.get( mobjSetup.getPContactEmail() );
				if( attr != null ) {
					mstrEMail = getValue(attr);
				}
			}

			// Eメール2の取得
			if( mobjSetup.getPContactEmail2() != null &&
				!mobjSetup.getPContactEmail2().equals("") ) {
				attr = attrs.get( mobjSetup.getPContactEmail2() );
				if( attr != null ) {
					mstrEMail2 = getValue(attr);
				}
			}

			// 読みかたの取得
			if( mobjSetup.getPReadingName() != null &&
				!mobjSetup.getPReadingName().equals("") ) {
				attr = attrs.get( mobjSetup.getPReadingName() );
				if( attr != null ) {
					mstrReadingName = getValue(attr);
				}
			}

			// 誕生日
			if( mobjSetup.getPBirthday() != null &&
				!mobjSetup.getPBirthday().equals("") ) {
				attr = attrs.get( mobjSetup.getPBirthday() );
				if( attr != null ) {
					mstrBirthday = getValue(attr);
				}
			}

			// 電話番号
			if( mobjSetup.getPContactTel() != null &&
				!mobjSetup.getPContactTel().equals("") ) {
				attr = attrs.get( mobjSetup.getPContactTel() );
				if( attr != null ) {
					mstrTel = getValue(attr);
				}
			}

			// コメント
			if( mobjSetup.getPCustumMsgDir() != null &&
				!mobjSetup.getPCustumMsgDir().equals("") ) {
				attr = attrs.get( mobjSetup.getPCustumMsgDir() );
				if( attr != null ) {
					mstrCustumMsgDir = getValue(attr);
				}
			}

			// 外部ID
			if( mobjSetup.getPForeignID() != null &&
				!mobjSetup.getPForeignID().equals("") ) {
				attr = attrs.get( mobjSetup.getPForeignID() );
				if( attr != null ) {
					mstrForeignID = getValue(attr);
				}
			}

			// ログインID
			if( mobjSetup.getPLoginID() != null &&
				!mobjSetup.getPLoginID().equals("") ) {
				attr = attrs.get( mobjSetup.getPLoginID() );
				if( attr != null ) {
					mstrLoginID = getValue(attr);
				}
			}

			// ADユーザID
			if( mobjSetup.getUserObjKey() != null &&
				!mobjSetup.getUserObjKey().equals("") ) {
				attr = attrs.get( mobjSetup.getUserObjKey() );
				if( attr != null ) {
					mstrADUserID = getValue(attr);
				}
			}

			// オブジェクトID
			if( mobjSetup.getObjKey() != null &&
				!mobjSetup.getObjKey().equals("") ) {
				attr = attrs.get( mobjSetup.getObjKey() );
				if( attr != null ) {
					// 属性値の取り出し
					mstrOid = getValue( attr );
				}
			}

			// DN
			if( mobjSetup.getDN() != null &&
				!mobjSetup.getDN().equals("") ) {
				attr = attrs.get( mobjSetup.getDN() );
				if( attr != null ) {
					mstrDN = getValue(attr);
				}
			}

		}
		catch(NamingException ne) {
			// 検索エラー
			ADCorpSearchException ase = new ADCorpSearchException();
			// @LOG >err >1 検索エラー
			DebugLog.write( this.getClass(), ase.getMessage(), DebugLog.HIGHT );
			DebugLog.write( this.getClass(), ne, DebugLog.HIGHT );
			throw ase;
		}

		// 必須項目チェック
		// DN必須チェック
		if( mstrDN == null || mstrDN.equals("") ) {
			// @LOG >err >1 AD同期処理:DNに設定する属性が存在しません。
			DebugLog.write( this.getClass(), "AD同期処理:DNに設定する属性が存在しません。", DebugLog.MID );
			throw new ADCorpException( ADCorpMessage.AD_NOATTRIBUTE_ERR );
		}
		// Oid必須チェック
		if( mstrOid == null || mstrOid.equals("") ) {
			// @LOG >err >1 AD同期処理:オブジェクトIDに設定する属性が存在しません。
			DebugLog.write( this.getClass(), "AD同期処理:オブジェクトIDに設定する属性が存在しません。", DebugLog.MID );
			throw new ADCorpException( ADCorpMessage.AD_NOATTRIBUTE_ERR );
		}


		// デフォルト値チェック
		// ユーザ名
		if( mstrUserName == null || mstrUserName.equals( "" ) ) {
			mstrUserName = AD_DEFAULT + mobjSetup.getDomainNo() + "_" + mintIndex;
		}
		// パスワード
		if( mstrPassword == null || mstrPassword.equals( "" ) ) {
			mstrPassword = generatePass(14);
		}
		// 性別
		if( mstrSex == null || mstrSex.equals( "" ) ) {
			mstrSex = new Integer(SEX_UNKNOWN).toString();
		}
		else {
			try {
				int intSex = Integer.parseInt( mstrSex );
				if( intSex != SEX_MAN && intSex != SEX_WOMAN && intSex != SEX_UNKNOWN ) {
					mstrSex = new Integer(SEX_UNKNOWN).toString();
				}
			}
			catch( NumberFormatException ne ) {
				mstrSex = new Integer(SEX_UNKNOWN).toString();
			}
		}
		// 外部ID
		if( mstrForeignID == null || mstrForeignID.equals( "" ) ) {
			mstrForeignID = AD_DEFAULT + mobjSetup.getDomainNo() + "_" + mintIndex;
		}
		// ログインID
		if( mstrLoginID == null || mstrLoginID.equals( "" ) ) {
			mstrLoginID = AD_DEFAULT + mobjSetup.getDomainNo() + "_" + mintIndex;
		}


	}

	/**
	 * 桁あふれ対応
	 * 各フィールドに対して桁あふれ対応を行います。
	 */
	private void roundB() {

		// ユーザ名
		mstrUserName = XMOString.roundB(mstrUserName, PeopleTable.USERNAME_LENB);
		// パスワード
		mstrPassword = XMOString.roundB(mstrPassword, PeopleTable.PASSWORD_LENB);
		// 住所
		mstrAddress = XMOString.roundB(mstrAddress, PeopleTable.ADDRESS_LENB);
		// 性別
		mstrSex = XMOString.roundB(mstrSex, PeopleTable.SEX_LENB);
		// Eメール
		mstrEMail = XMOString.roundB(mstrEMail, PeopleTable.EMAIL_LENB);
		// Eメール2
		mstrEMail2 = XMOString.roundB(mstrEMail2, PeopleTable.EMAIL2_LENB);
		// 読みかた
		mstrReadingName = XMOString.roundB(mstrReadingName, PeopleTable.READINGNAME_LENB);
		// 誕生日
		mstrBirthday = XMOString.roundB(mstrBirthday, PeopleTable.BIRTHDAY_LENB);
		// 電話番号
		mstrTel = XMOString.roundB(mstrTel, PeopleTable.TEL_LENB);
		// コメント
		mstrCustumMsgDir = XMOString.roundB(mstrCustumMsgDir, PeopleTable.CUSTOM_LENB);
		// 外部ID
		mstrForeignID = XMOString.roundB(mstrForeignID, PeopleTable.FOREIGNID_LENB);
		// ログインID
		mstrLoginID = XMOString.roundB(mstrLoginID, PeopleTable.LOGINID_LENB);
		// ADユーザID
		mstrADUserID = XMOString.roundB(mstrADUserID, PeopleTable.ADUSERID_LENB);
		// ADDN
		mstrDN = XMOString.roundB(mstrDN, PeopleTable.ADDN_LENB);
		// OID
		mstrOid = XMOString.roundB(mstrOid, PeopleTable.OID_LENB);
	}

	/**
	 * 更新フラグを返します。
	 * @param strSetData 設定データ
	 * @return 更新フラグ 設定データがnullか空文字なら upflag="off"
	 *                    それ以外なら空文字を返す。
	 */
	private String makeUpFlag(String strSetData) {

		return (strSetData == null || strSetData.equals("") ? " up_flag=\"off\"" : "");

	}

	/**
	 * 指定された桁数の英数字のランダムなパスワードを生成して返します。
	 * @param intCount 桁数
	 * @return String パスワード
	 */
	private static String generatePass(int intCount) {
		StringBuffer sb = new StringBuffer();
		for( int i = 0; i < intCount; i++ ) {
			int intRan = (int)(Math.floor(Math.random() * 75) + 48);
			if(58 <= intRan && intRan <= 64){
				intRan = intRan + 7;
			}
			if(91 <= intRan && intRan <= 96){
				intRan = intRan + 6;
			}
			sb.append( (char)intRan );
		}
		return new String(sb);
	}

//---------------------------内部関数 ------------------------------------------
}
