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

//
//	メール送信機能 XMO サーバクラス
//	変更履歴
//	2004.01.08	新規作成	中山雅文

package jp.co.ntt.lms.xmo.Mail;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Hashtable;
import java.util.Vector;

import jp.co.ntt.lms.xmo.MenuData;
import jp.co.ntt.lms.xmo.XMO;
import jp.co.ntt.lms.xmo.util.DebugLog;

/**
 * メール送信機能 XMO サーバクラスです。<BR>
 * メール送信情報を受け取り、テンプレートファイルから題名、本文を読み込み
 * キーワードを置換しメールを送信します。<BR>
 * 送信自体の失敗の場合エラーコードを、個々のメール作成エラーの時は未送信、
 * 個々のメール送信エラーの時は、異常を設定し返却します。<BR>
 * RMIサーバとして動作するためRemoteインタフェースであるXMOインタフェースを実装し、
 * 永続的な起動状態を確保するためjava.rmi.server.UnicastRemoteObjectクラスを継承します。
 */
public class Mail extends UnicastRemoteObject implements XMO {

	//////////////////////////////////////////////////////////////////
	// メソッド名定義
	//////////////////////////////////////////////////////////////////
	/** メッセージオブジェクトの取得メソッド名です */
	private static final String METHOD1 = "sendMail";
	private static final String METHOD_GETTEMPLIST = "getTemplateList";
	private static final String METHOD_GETTEMPINFO = "getTemplateInfo";
	private static final String METHOD_GETKEYLIST = "getKeywordList";
	private static final String METHOD_SENDMAIL = "sendCustomizeMail";
	private static final String METHOD_GETTEMPDIRPATH = "getTemplateDirectoryPath";

	private static TemplateControl m_TemplateCtl = null;


	/**
	 * コンストラクタです。
	 */
	public Mail() throws RemoteException {
		// リモートオブジェクトをエクスポートする
		// java.rmi.server.UnicastRemoteObject の
		// 引数なしのコンストラクタを呼び出す
		super();
// テンプレート制御インスタンスを作成します（シングルトン）
		m_TemplateCtl = TemplateControl.getInstance( );
	}


	/**
	 * メニュー一覧を返します
	 * @return Vector メニュー一覧
	 */
	public Vector getMenuList(Hashtable htbParam) {
		Vector vecMenuList = new Vector();
		return vecMenuList;
	}

	/**
	 * メソッド一覧を返します
	 * @return Vector
	 */
	public Vector getMethodList() {
		Vector vecMethod = new Vector();
		vecMethod.add( METHOD1 );
		vecMethod.add( METHOD_GETTEMPLIST );
		vecMethod.add( METHOD_GETTEMPINFO );
		vecMethod.add( METHOD_GETKEYLIST );
		vecMethod.add( METHOD_SENDMAIL );
		vecMethod.add( METHOD_GETTEMPDIRPATH );
		return vecMethod;
	}

	/**
	 * デフォルトメニューを返します
	 * @return String
	 */
	public MenuData getDefaultMenu() {
		return null;
	}

	/**
	 * このXMOで定義された、メソッドのクライアント側からの入り口になるメソッドです。
	 * @param strMethodName 実行するメソッド名を指定します
	 * @param htData メソッドで実行するパラメータを指定します<BR>
	 *				 なお必要なキーと値は各DAOの処理メソッドの説明を参照して下さい。
	 * @retunr Object 戻り値（さまざまな戻り値に対応するためObject型としてあります)<BR>
	 *				  受け取り側では適切な値にキャストする必要があります。
	 */
	public Object execute( String strMethodName, Hashtable htData ) {

		Object objReturn = null;

		if( strMethodName.equals( METHOD1 ) ) {
			objReturn = sendMail( htData );
		}
// 追加したリモートメソッドを呼び出すように修正
		else if( strMethodName.equals( METHOD_GETTEMPLIST ) ) {
			objReturn = getTemplateList( htData );
		}
		else if( strMethodName.equals( METHOD_GETTEMPINFO ) ) {
			objReturn = getTemplateInfo( htData );
		}
		else if( strMethodName.equals( METHOD_GETKEYLIST ) ) {
			objReturn = getKeywordList( htData );
		}
		else if( strMethodName.equals( METHOD_SENDMAIL ) ) {
			objReturn = sendCustomizeMail( htData );
		}
		else if( strMethodName.equals( METHOD_GETTEMPDIRPATH ) ) {
			objReturn = getTemplateDirectoryPath( htData );
		}
		return objReturn;
	}

	/**
	 * 起動確認（必ずtrueを返す）
	 * @return boolean 必ずtrueが返ります
	 */
	public boolean isLaunch() {
		return true;
	}


	/**
	 * メール送信処理 <BR>
	 * @param Hashtable 入力パラメータ
	 * @return Vector メール送信結果
	 */
	private Vector sendMail( Hashtable htData ) {
		String		strSubject = null;
		String		strBody = null;
		String		strFrom = null;
		Vector		vtResult = null;

		// テンプレートファイルオープンと題名、本文の取得
		try {
			MailParser objParser = new MailParser( (String)htData.get(MailConst.TEMPLATE_PATH) );
			strSubject = objParser.getSubject();
			strBody = objParser.getBody();
			strFrom = objParser.getFrom();
			if ( strSubject.equals("") == true || strBody.equals("") == true ){
				// テンプレートファイル読み込みエラーメッセージ返却
				DebugLog.write( this.getClass(), "TEMPLATE_FILE read error", DebugLog.ROW );
				vtResult = new Vector();
				vtResult.add( new Integer( MailConst.RESULT_TEMPREAD_ERR ) );
				return vtResult;
			}
		}
		catch( Exception ex ){
			// テンプレートファイル読み込みエラーメッセージ返却
			vtResult = new Vector();
			vtResult.add( new Integer( MailConst.RESULT_TEMPREAD_ERR ) );
			DebugLog.write( this.getClass(), ex, DebugLog.HIGHT );
			return vtResult;
		}

		/* メール送信実行 */
		vtResult = sendAllRecipients( (Hashtable[])htData.get( MailConst.MAILINFOS ), strSubject, strBody, strFrom, (Hashtable)htData.get(MailConst.KEYWORDS) );
		return vtResult;
	}


	/**
	 * メール送信情報の全ユーザ宛へのメール送信処理 <BR>
	 * @param Hashtable[] メール送信情報テーブル群
	 * @param String メールサブジェクト
	 * @param String メール本文
	 * @param htKeywords キーワード置換定義。
	 * @return Vector メール送信結果
	 */
	private Vector sendAllRecipients(Hashtable[] htMailInfos, String strSubject, String strSrcBody, String strFromField, Hashtable htKeywords)
	{
		int			iCnt;
		MailSender	objSender;
		Vector		vtResult = new Vector(0);
		String		strHost;
		String		strFrom;
		Integer		iPort;
		String		strBody;


		MailEnv objMailSgInfo = MailEnv.getInstance();
		try{
			/* 環境設定ファイルからメール送信情報を取得 */
			strHost = MailEnv.getSmtpHost();
			iPort = MailEnv.getSmtpPort();
			strFrom = MailEnv.getMailFrom();
			if ( strHost.equals("") == true || strFrom.equals("") || iPort == null || strFrom.equals("") ){
				// 環境設定ファイル読み込みエラーのメッセージ返却
				DebugLog.write( this.getClass(), "SmtpServerInfo get error.", DebugLog.HIGHT );
				vtResult.add( new Integer( MailConst.RESULT_SGREAD_ERR ) );
				return vtResult;
			}

			/* 環境設定ファイルから置換文字列情報を取得し置換 */
			strBody = replaceSgInfo( objMailSgInfo, strSrcBody );
			strFromField = replaceSgInfo( objMailSgInfo, strFromField );
			strSubject = replaceSgInfo( objMailSgInfo, strSubject );
			if ( strBody == null || strFromField == null || strSubject == null ){
				// 設定ファイル置換エラーのメッセージ返却
				DebugLog.write( this.getClass(), "TEMPLATE_FILE replace error.", DebugLog.HIGHT );
				htMailInfos[0].put( MailConst.RESULT, MailConst.NOTSEND );
				vtResult.add( htMailInfos );
				return vtResult;
			}
			
			// 指定キーワード置換
			if (htKeywords != null)
			{
				strBody = TemplateFormatter.replaceTemplate(strBody, htKeywords);
				strFromField = TemplateFormatter.replaceTemplate(strFromField, htKeywords);
				strSubject = TemplateFormatter.replaceTemplate(strSubject, htKeywords);
			}
		}catch( Exception ex1 ){
			// 環境設定ファイル読み込みエラーのメッセージ返却
			DebugLog.write( this.getClass(), ex1, DebugLog.HIGHT );
			vtResult.add( new Integer( MailConst.RESULT_SGREAD_ERR ) );
			return vtResult;
		}

		/* SMTPサーバにコネクトする */
		try{
			objSender = new MailSender();
			objSender.connect( strHost, iPort.intValue() );
		}catch( Exception ex2 ){
			// サーバ接続エラーのメッセージ返却
			DebugLog.write( this.getClass(), ex2, DebugLog.HIGHT );
			vtResult.add( new Integer( MailConst.RESULT_CONNECT_ERR ) );
			return vtResult;
		}

		/* Hashtableのサイズ分メールを送信する */
		iCnt = htMailInfos.length;
		for (int i=0; i<iCnt; i++ ){

			/* 送信先アドレスの取得 */
			String[] to = getRecipients( htMailInfos[i] );
			if ( to == null || to.length == 0 ){
				//　送信先アドレスが存在しないため未送信とする
				htMailInfos[i].put( MailConst.RESULT, MailConst.NOTSEND );
				continue;
			}
			/* テンプレートの置換 */
			// USER_IDが置換されないための対処
			String strUserId = (String)htMailInfos[i].get( MailConst.USER_ID );
			htMailInfos[i].remove( MailConst.USER_ID );
			String strChangeBody = TemplateFormatter.replaceTemplate( strBody, (Hashtable)htMailInfos[i] );
			String strChangeFromField = TemplateFormatter.replaceTemplate( strFromField, (Hashtable)htMailInfos[i] );
			String strChangeSubject = TemplateFormatter.replaceTemplate( strSubject, (Hashtable)htMailInfos[i] );
			htMailInfos[i].put( MailConst.USER_ID, strUserId );
			if ( strChangeBody == null || strChangeFromField == null || strChangeSubject == null ){
				// テンプレート置換エラーの為未送信とする
				DebugLog.write( this.getClass(), "USER_INFO replace error.", DebugLog.ROW );
				htMailInfos[i].put( MailConst.RESULT, MailConst.NOTSEND );
				continue;
			}

			/* メールの作成/送信 */
			try{
				objSender.sendOneMail(to, strFrom, strChangeFromField, strChangeSubject, strChangeBody);
			}catch( Exception ex3 ){
				//エラーログ出力
				DebugLog.write( this.getClass(), ex3, DebugLog.HIGHT );
				htMailInfos[i].put( MailConst.RESULT, MailConst.NG );
				continue;
			}

			htMailInfos[i].put( MailConst.RESULT, MailConst.OK );
		}

		objSender.disconnect();
		vtResult.add( htMailInfos );
		return vtResult;
	}

	/**
	 * メール送信情報テーブルからメールアドレス取得します。<BR>
 	 * MailConst.MAIL_TO1、MailConst.MAIL_TO2をキーとして
 	 * 取得できる値を要素する配列を戻します。
 	 * @param メール送信情報マップ。
	 * @return メールアドレスを要素とする配列を戻す。
	 *          メールアドレスがnullまたは長さ０の場合、配列から除外し、
	 *          すべてのメールアドレスがnullまたは長さ０の場合、
	 *          要素数０の配列を戻します。
	 * @see MailConst#MAIL_TO1
	 * @see MailConst#MAIL_TO2
	 */
	private String[] getRecipients( Hashtable htInfo ) {
		// このメソッドの戻り値		
		String[] arrystrTo = null;
		// メールアドレス１
		String email1 = null;
		// メールアドレス２
		String email2 = null;
		////////////////////////////////////////////////////////////////////////
		// パラメータからメールアドレスを取得
		email1 = (String)htInfo.get( MailConst.MAIL_TO1 );
		email2 = (String)htInfo.get( MailConst.MAIL_TO2 );
		////////////////////////////////////////////////////////////////////////
		// 存在しているメールアドレスを要素とする配列を生成
		// =====================================================================
		// 前者のメールアドレスの確認
		if ( email1 != null && email1.length() > 0 ){
			// 後者のメールアドレスの確認
			if ( email2 != null && email2.length() > 0 ){
				// 両者とも存在する場合は、両者を要素とする配列
				arrystrTo = new String[] { email1, email2 };
			} else {
				// 前者のみ存在する場合、前者を要素とする配列
				arrystrTo = new String[] { email1 };
			}
		} else {
			// 後者のメールアドレスの確認
			if ( email2 != null && email2.length() > 0 ){
				// 後者のみ存在する場合、後者を要素とする配列
				arrystrTo = new String[] { email2 };
			} else {
				// 両者とも存在しない場合は、空要素とする配列
				arrystrTo = new String[] {};
			}
		}
		return arrystrTo;
	}


	/**
	 * SG情報をテンプレートファイル本文に埋め込みます。<BR>
	 * @param MailEnv SG情報
	 * @param strSrc テンプレートファイル本文文字列
	 * @return String 変換後テンプレートファイル本文文字列
	 */
	private String replaceSgInfo( MailEnv objMailSgInfo, String strSrc ) throws Exception
	{
		String strSiteAdminMail = MailEnv.getSiteAdministratorMail();
		String strHeader		= MailEnv.getHeadertext();
		String strFooter		= MailEnv.getFootertext();
		String strSiteMailer	= MailEnv.getSiteMailerMail();
		String strHelpDesk		= MailEnv.getHelpdeskMail();

		/* 設定ファイル情報を置換する */
		Hashtable htSgInfo = new Hashtable(5);

		htSgInfo.put( MailConst.SITE_ADMINISTRATOR_MAIL, strSiteAdminMail);
		htSgInfo.put( MailConst.HEADERTEXT, strHeader);
		htSgInfo.put( MailConst.FOOTERTEXT, strFooter);
		htSgInfo.put( MailConst.SITE_MAILER_MAIL, strSiteMailer);
		htSgInfo.put( MailConst.HELPDESK_MAIL, strHelpDesk);

		return TemplateFormatter.replaceTemplate( strSrc, htSgInfo );
	}

	/**
	 * 指定されたメール種別のテンプレートファイル一覧を取得します。<BR>
	 * @param strMailType メールタイプ
	 * @return Vector テンプレートファイルリスト
	 */
	public Vector getTemplateList( Hashtable htData )
	{
		Vector vcTemplateList = null;
		try
		{
			// パラメータ情報からメール種別を取り出します
			String strMailType = (String)htData.get(MailConst.MAIL_TYPE);

			// シングルトンのクラスを呼び出します。
			TemplateControl objCtl = TemplateControl.getInstance();

			// 指定メール種別のメールテンプレートファイルリストを取得します。
			vcTemplateList = objCtl.getTemplateList( strMailType );
			
		}
		catch( Exception e ) {
			return new Vector();
		}
		return vcTemplateList;
	}

	/**
	 * 指定されたテンプレートファイルの内容を取得します。<BR>
	 * @param strTemplatePath メールテンプレートファイルパス
	 * @return MailTemplateVO テンプレート情報（VO）
	 */
	public Vector getTemplateInfo( Hashtable htData ) 
	{
		Vector vcTemplateInfo = new Vector();
		MailTemplateVO voMailInfo = null;

		try {

			// パラメータ情報からテンプレートファイルパスを取り出します
			String strTemplatePath = 
				(String)htData.get( MailConst.TEMPLATE_PATH );


			// シングルトンのクラスを呼び出します。
			TemplateControl objCtl = TemplateControl.getInstance();

			// 指定メールテンプレートファイルの内容を取得します。
			voMailInfo = objCtl.getTemplateInfo( strTemplatePath );
			vcTemplateInfo.add(voMailInfo);
		}
		catch( Exception e ) {
			vcTemplateInfo.add(new MailTemplateVO());
		}
		return vcTemplateInfo;
	}

	/**
	 * メール送信処理 <BR>
	 * @param Hashtable 入力パラメータ
	 * @return Vector メール送信結果
	 */
	public Vector sendCustomizeMail( Hashtable htData ) {
		String		strSubject = null;
		String		strBody = null;
		String		strFrom = null;
		Vector		vtResult = null;

		MailTemplateVO voMailInfo = (MailTemplateVO)htData.get( MailConst.TEMPLATE_INFO );


		// テンプレート情報の取得
		strSubject = voMailInfo.getSubject();	// 題名
		strBody = voMailInfo.getBody();			// 本文
		strFrom = voMailInfo.getFromAddress();	// 送信元メールアドレス
		if ( strSubject.equals("") == true || strBody.equals("") == true )
		{
			// テンプレートファイル読み込みエラーメッセージ返却
			DebugLog.write( this.getClass(), "TEMPLATE_INFO input error", DebugLog.ROW );
			vtResult = new Vector();
			vtResult.add( new Integer( MailConst.RESULT_TEMPINPUT_ERR ) );
			return vtResult;
		}

		/* メール送信実行 */
		vtResult = sendAllRecipients( (Hashtable[])htData.get( MailConst.MAILINFOS ), strSubject, strBody, strFrom, (Hashtable)htData.get(MailConst.KEYWORDS) );
		return vtResult;
	}

	/**
	 * 指定されたメール種別のテンプレートフォルダパスを取得します。<BR>
	 * @param strMailType メールタイプ
	 * @return Vector テンプレートファイルリスト
	 */
	public String getTemplateDirectoryPath( Hashtable htData )	{

		String strTemplateDirectoryPath = null;
		try {
			// パラメータ情報からメール種別を取り出します。
			String strMailType = (String)htData.get(MailConst.MAIL_TYPE);

			// シングルトンのクラスを呼び出します。
			TemplateControl objCtl = TemplateControl.getInstance();

			// メール種別毎に対応するフォルダパスを取得します。
			strTemplateDirectoryPath = objCtl.getTemplateDirectoryPath(strMailType);

		} catch (Exception ex) {
			return null;
		}
		return strTemplateDirectoryPath;
	}

	/**
	 * 置換キーワード一覧取得処理 <BR>
	 * @param strMailType メール種別（2003.06 現在は使用しない）
	 * @return ArrayList 置換キーワードリスト
	 */
	public Vector getKeywordList( Hashtable htData )
	{
		Vector objKeywordList = new Vector();

		objKeywordList.add(new String("%USER_NAME%,%USER_NAME% [送信先ユーザ]"));
		objKeywordList.add(new String("%LOGIN_ID%,%LOGIN_ID% [送信先ユーザログインID]"));
		objKeywordList.add(new String("%USER_PASSWORD%,%USER_PASSWORD% [送信先ユーザパスワード]"));
		objKeywordList.add(new String("%USER_MAIL1%,%USER_MAIL1% [送信先ユーザメールアドレス１]"));
		objKeywordList.add(new String("%USER_MAIL2%,%USER_MAIL2% [送信先ユーザメールアドレス２]"));
		objKeywordList.add(new String("%ADMINISTRATOR_NAME%,%ADMINISTRATOR_NAME% [送信元ユーザ名]"));
		objKeywordList.add(
			new String("%ADMINISTRATOR_MAIL1%,%ADMINISTRATOR_MAIL1% [送信元ユーザメールアドレス１]"));
		objKeywordList.add(
			new String("%ADMINISTRATOR_MAIL2%,%ADMINISTRATOR_MAIL2% [送信元ユーザメールアドレス２]"));
		objKeywordList.add(new String("%TMATERIAL%,%TMATERIAL% [教材名]"));
		objKeywordList.add(new String("%TMATERIAL_URL%,%TMATERIAL_URL% [教材起動用URL]"));
		objKeywordList.add(new String("%LOGIN_URL%,%LOGIN_URL% [システムログインURL]"));
		objKeywordList.add(new String("%headertext%,%headertext% [ヘッダー情報]"));
		objKeywordList.add(new String("%footertext%,%footertext% [フッタ情報]"));
		objKeywordList.add(
			new String("%SITE_ADMINISTRATOR_MAIL%,%SITE_ADMINISTRATOR_MAIL% [サイト管理者用メールアドレス]"));
		objKeywordList.add(
			new String("%SITE_MAILER_MAIL%,%SITE_MAILER_MAIL% [サイトメーラーアドレス]"));
		objKeywordList.add(
			new String("%HELPDESK_MAIL%,%HELPDESK_MAIL% [ヘルプデスクメールアドレス]"));

		return objKeywordList;
	}
	

}

