/*
このファイルの中身は、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.util.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import jp.co.ntt.lms.xmo.util.DebugLog;
import jp.co.ntt.lms.xmo.util.FileControl;

import jp.co.ntt.lms.xmo.Assignments.AssignmentsEnv;
import jp.co.ntt.lms.xmo.Lo.LoEnv;
import jp.co.ntt.lms.xmo.LumpInsert.LumpInsertEnv;
import jp.co.ntt.lms.xmo.People.PeopleEnv;

/**
 * メール送信 XMO テンプレート管理クラスです。<BR>
 */
public class TemplateControl {

	// エラーメッセージ定義
	// テンプレートファイルなし
	private static final String ERR_MSG_NOFILE 
		= "格納先フォルダ、またはメールテンプレートファイルが存在しない";

	// テンプレートフォルダなし
	private static final String ERR_MSG_NODIR 
		= "メールテンプレートの格納先指定なし";

	// アサインテンプレートファイル一覧（キャッシュ用）
	private static ArrayList mobjAssignTemplateList = new ArrayList();

	// レジストテンプレートファイル一覧（キャッシュ用）
	private static ArrayList mobjRegistTemplateList = new ArrayList();

	// 一括登録テンプレートファイル一覧（キャッシュ用）
	private static ArrayList mobjLumpTemplateList = new ArrayList();

	// 激励テンプレートファイル一覧（キャッシュ用）
	private static ArrayList mobjStimulateTemplateList = new ArrayList();

	// Singltonとして動作するために自分のインスタンスを保持します 
	private static TemplateControl objTempCtrl = new TemplateControl();

	/**
	 * インスタンスを返却します
	 * @param objTempCtrl 
	 */
	public static TemplateControl getInstance() {
		return objTempCtrl;
	}

	/**
	 * メールテンプレートのファイルリストを取得する。<BR>
	 * メールテンプレートファイルが存在しない場合、空の
	 * リストを保持します。
	 * @return 変換後文字列
	 */
	public	void setTemplateFileList() throws Exception {

		// テンプレート種別毎に対応するフォルダ配下のテンプレートファイル
		// 一覧を取得する。
		// ファイル名、及びタイトルを起動時にListでキャッシュする。
		// Listはテンプレート種別毎に保持する。
		
		// ユーザ登録／更新用のメールテンプレートファイルリストを取得します。
		PeopleEnv objEnv = PeopleEnv.getInstance();
		String strUserPath = objEnv.getSendMailPath();
		mobjRegistTemplateList = this.getTemplateFile(strUserPath);

		// 一括登録用のメールテンプレートファイルリストを取得します。
		LumpInsertEnv objLumpEnv = LumpInsertEnv.getInstance();
		String strLumpPath = objLumpEnv.getSendMailPath();
		mobjLumpTemplateList = this.getTemplateFile(strLumpPath);

		// アサイン用のメールテンプレートファイルリストを取得します。
		AssignmentsEnv objAssignEnv = AssignmentsEnv.getInstance();
		String strAssignPath = objAssignEnv.getSendMailPath();
		mobjAssignTemplateList = this.getTemplateFile(strAssignPath);

		// 激励用のメールテンプレートファイルリストを取得します。
		LoEnv objStimEnv = LoEnv.getInstance();
		String strStimPath = objStimEnv.getSendMailPath();
		mobjStimulateTemplateList = this.getTemplateFile(strStimPath);

		return;
	}
	
	/**
	 * 指定したメール種別のテンプレートファイル一覧を取得します。<BR>
	 * @param srcMailType メール種別
	 * @return boolean ファイルがある場合True、ない
	 */
	public Vector getTemplateList(String strMailType)
	{

		// ファイル名、及びタイトルは起動時にListでキャッシュしていますが、
		// 起動中の入れ替えがあるので、ファイルの存在チェック、タイムスタンプ
		// 比較を行い、List中の項目と同期をとります。
		Vector vcTemplateList = new Vector();
		try {

			String strTemplatePath = "";
			
			// メール種別によりテンプレートファイルの取得元を変更します。
			if ( strMailType.compareTo( MailConst.TYPE_LUMP ) == 0 )
			{	// メール種別が「一括登録」の場合
				// 一括登録用のメールテンプレートファイル格納パスを指定します。
				LumpInsertEnv objEnv = LumpInsertEnv.getInstance();
				strTemplatePath = objEnv.getSendMailDir();
				synchronized (mobjLumpTemplateList)
				{
					refresh(mobjLumpTemplateList, strTemplatePath);
					for( int i=0; i<mobjLumpTemplateList.size(); i++ )
					{
						vcTemplateList.add(mobjLumpTemplateList.get(i));
					}
				}
			}
			else if ( strMailType.compareTo( MailConst.TYPE_ASSIGNMENTS ) == 0)
			{	// メール種別が「アサイン」の場合
				// アサイン用のメールテンプレートファイル格納パスを指定します。
				AssignmentsEnv objEnv = AssignmentsEnv.getInstance();
				strTemplatePath = objEnv.getSendMailDir();
				synchronized (mobjAssignTemplateList)
				{
					refresh(mobjAssignTemplateList, strTemplatePath);
					// Vectorに入れて返却します。
					for( int i=0; i<mobjAssignTemplateList.size(); i++ )
					{
						vcTemplateList.add(mobjAssignTemplateList.get(i));
					}
				}
			}
			else if ( strMailType.compareTo( MailConst.TYPE_STIMULATE ) == 0)
			{	// メール種別が「激励」の場合
				// 激励用のメールテンプレートファイル格納パスを指定します。
				LoEnv objEnv = LoEnv.getInstance();
				strTemplatePath = objEnv.getSendMailDir();
				synchronized (mobjStimulateTemplateList)
				{
					refresh(mobjStimulateTemplateList, strTemplatePath);
					// Vectorに入れて返却します。
					for( int i=0; i<mobjStimulateTemplateList.size(); i++ )
					{
						vcTemplateList.add(mobjStimulateTemplateList.get(i));
					}
				}
				
			}
			else if ( strMailType.compareTo( MailConst.TYPE_REGIST ) == 0)
			{	// メール種別が「レジスト」の場合
				// レジスト用のメールテンプレートファイル格納パスを指定します。
				PeopleEnv objEnv = PeopleEnv.getInstance();
				strTemplatePath = objEnv.getSendMailDir();
				synchronized (mobjRegistTemplateList)
				{
					refresh(mobjRegistTemplateList, strTemplatePath);
					for( int i=0; i<mobjRegistTemplateList.size(); i++ )
					{
						vcTemplateList.add(mobjRegistTemplateList.get(i));
					}
				}
			}
			return( vcTemplateList );
		}
		catch( Exception ex )
		{
			// 内部エラーコード返却
			DebugLog.write( this.getClass(), ex, DebugLog.HIGHT );
			return vcTemplateList;
		}
	}
	
	/**
	 * 指定したメールテンプレートファイルの情報を取得します。<BR>
	 * @param strTemplatePath テンプレートファイル名
	 * @return	テンプレート情報
	 */
	public MailTemplateVO getTemplateInfo(String strTemplatePath)
		throws Exception
	{
		MailTemplateVO voMailInfo = null;

		try {
			voMailInfo = new MailTemplateVO();

			try {
				
				// メールテンプレート読み込みインスタンスを生成します。
				MailParser objParser = new MailParser( strTemplatePath );
		
				// テンプレート情報を取得します。
				String strSubject = objParser.getSubject();	// 題名を取得
				String strBody = objParser.getBody();			// 本文を取得
				String strFrom = objParser.getFrom();			// 送信元を取得
		
				voMailInfo.setSubject( strSubject );
				voMailInfo.setBody( strBody );
				voMailInfo.setFromAddress( strFrom );
		
				voMailInfo.setErrCode( MailConst.RESULT_SUCCESS );
				return voMailInfo;
					
			}
			catch( FileNotFoundException ex )
			{
				// テンプレートファイル存在なしエラーメッセージ返却
				voMailInfo.setErrCode( MailConst.RESULT_TEMPEXIST_ERR );
				return voMailInfo;
			}
			catch( IOException ex )
			{
				// テンプレートファイル読み込みエラーの場合
				voMailInfo.setErrCode( MailConst.RESULT_TEMPREAD_ERR );
				return voMailInfo;
			}
			catch( Exception ex ){
				// 内部エラーコード返却
				DebugLog.write( this.getClass(), ex, DebugLog.HIGHT );
				voMailInfo.setErrCode( MailConst.RESULT_INTERNAL_ERR );
				return voMailInfo;
			}
		}
		catch ( Exception ex ){
			// 内部エラーコード返却
			DebugLog.write( this.getClass(), ex, DebugLog.HIGHT );
			voMailInfo = new MailTemplateVO();
			voMailInfo.setErrCode( MailConst.RESULT_INTERNAL_ERR );
			return voMailInfo;
		}

	}

	/**
	 * テンプレート一覧に変更がある場合、キャッシュリストを更新します。<BR>
	 * @param objTemplateList キャッシュリスト
	 * @param strTemplatePath テンプレートファイル格納先パス名
	 * @return	なし
	 */
	private void refresh( ArrayList objTemplateList, String strTemplatePath )
		throws Exception
	{

		// テンプレートファイルの存在チェック、及びタイムスタンプの比較を行います。
		checkTemplatePathStatus( strTemplatePath, objTemplateList );

		// テンプレート一覧に変更がある場合、キャッシュリストを更新します。
		refreshCacheList( objTemplateList );

	}

	/**
	 * テンプレートファイルの存在チェックを行い、先にキャッシュに
	 * 読み込んでいたテンプレートファイルリストとの同期をとります。<BR>
	 * @param strTemplateFolder テンプレートファイル格納先
	 * @param objTemplateList  同期をとるメール種別テンプレートの
	 * 							キャッシュリスト
	 * @return	なし
	 */
	private void checkTemplatePathStatus( String strTemplateFolder, ArrayList objTemplateList )
			throws Exception
	{
		// 現在のファイル一覧を取得します。
		ArrayList objCurrTempList = getTemplateFile( strTemplateFolder );

		int iCacheSize = objTemplateList.size();
		for( int i = iCacheSize-1; i >= 0; i-- )
		{
			// キャッシュからファイル情報を取得し、存在チェックを行います。
			TemplateListVO voCachePath = 
				(TemplateListVO)objTemplateList.get(i);
			String strPath = voCachePath.getTemplatePath();
	
			// キャッシュのファイルが、取得したファイル一覧に存在するか
			// 確認します。
			int j = 0;
			for( ; j < objCurrTempList.size(); j++ )
			{
				TemplateListVO voNowPath = 
					(TemplateListVO)objCurrTempList.get(j);
	
				// ** テンプレートファイルの存在チェック **
				if ( strPath.compareTo(voNowPath.getTemplatePath()) == 0 )
				{	// テンプレートファイルが存在する場合
	
					// ** タイムスタンプの比較 **
					long lTimeStump = voCachePath.getLastModified();
					if ( lTimeStump != voNowPath.getLastModified() )
					{	// タイムスタンプが更新されている場合
	
						// キャッシュの情報を更新します。
						// （変更したキャッシュ情報には、更新フラグを立てます。）
						voCachePath.setLastModified( 
								voNowPath.getLastModified());
					}
					break;
				}
			}
			if ( j != objCurrTempList.size() )
			{
				// 一致したファイルについては、取得一覧から削除します。
				objCurrTempList.remove(j);
			}
			else
			{	// 取得一覧と一致しないテンプレートがキャッシュリストにある場合
	
				// ファイルが存在しない場合、キャッシュリストから削除します。
				File objFilePath = new File(strPath);
				if(objFilePath.exists() == false)
				{
					objTemplateList.remove(i);
				}
			}
		}
	
		// 取得一覧に残ったテンプレートファイルリストについては、新規ファイル
		// としてキャッシュリストに追加します。
		for( int j = 0; j < objCurrTempList.size(); j++ )
		{
			TemplateListVO voNowPath = (TemplateListVO)objCurrTempList.get(j);
			objTemplateList.add(voNowPath);
		}
		return;
	}

	/**
	 * 指定したフォルダを検索し、存在するテンプレートファイル名を
	 * 全て取得します。<BR>
	 * @param strFolderName テンプレートファイル格納先
	 * @return	ArrayList テンプレートファイル一覧
	 */
	private ArrayList getTemplateFile( String strFolderName ) 
			throws Exception
	{
		try {
			ArrayList objTempLateList = new ArrayList();

			if ( (strFolderName == null) || 
				(strFolderName.equals("") == true) )
			{	// 格納先が指定されていない場合

				// 空のテンプレートリストを返却します。
				DebugLog.write( this.getClass(), 
					ERR_MSG_NODIR, DebugLog.HIGHT );
				return objTempLateList;
			}

			
			String[] strTempList = 
				FileControl.getFileList(strFolderName,FileControl.FILE_LIST);
			if(strTempList.length == 0)
			{	// 格納先が存在しなかった場合

				// 空のテンプレートリストを返却します。
				DebugLog.write( this.getClass(), ERR_MSG_NOFILE,
					DebugLog.HIGHT );
				return objTempLateList;
			}

			for(int i=0; i<strTempList.length; i++)
			{
				File objFilePath = new File(strTempList[i]);
				long lTime = objFilePath.lastModified();

				// 取得したファイル名から拡張子を取り出す。
				String exp = strTempList[i].substring(strTempList[i].length()-4);
				if (exp.equalsIgnoreCase(".xml") == true)
				{	// 取り出した拡張子がXMLファイルの場合
					String strTemplatePath = strFolderName + strTempList[i];

					// テンプレート一覧VOを生成します。
					TemplateListVO template = new TemplateListVO();
					template.setTemplatePath(strTemplatePath);
					// テンプレートファイル名を設定
					template.setTemplateFileName(strTempList[i]);
					template.setLastModified(lTime);

					// 返却リストに取得したテンプレートファイルリストを
					// 格納します。
					if (strTempList[i].equalsIgnoreCase(MailConst.DEFAULT_XML_NAME) == true)
					{	// デフォルトのテンプレートXMLをリストの先頭に格納します。
						objTempLateList.add(0, template);
					}
					else
					{	// その他のテンプレートXMLは順次リストに格納します。
						objTempLateList.add(template);
					}
				}
			}
			// Default.xmlが存在しない場合、空のテンプレートをリストの先頭に設定します。
			String fileName = ((TemplateListVO)objTempLateList.get(0)).getTemplateFileName();
			if (!fileName.equals(MailConst.DEFAULT_XML_NAME)) {
				objTempLateList.add(0, new TemplateListVO());
			}

			return objTempLateList;
		}
		catch( Exception ex )
		{
			return new ArrayList();
		}
	}
	
	/**
	 * 指定リストの内容を更新します。
	 * リストの要素に削除フラグが立っている場合は、要素を削除します。
	 * 更新フラグが立っている場合は、再度テンプレートの内容をパースします。
	 * @param  vcTempList テンプレートリスト
	 */
	private void refreshCacheList( ArrayList objTemplateList ) 
			throws Exception
	{

		try
		{
			// 指定リストの内容を更新します。
			int iCacheSize = objTemplateList.size();
			for( int i = iCacheSize-1; i >= 0; i-- )
			{
				TemplateListVO voCachePath =
					(TemplateListVO)objTemplateList.get(i);
				if ( voCachePath.isUpdate() == true )
				{	// 更新されているものは、再度データをパースします。

					try
					{
						// メールテンプレート読み込みインスタンスを生成します。
						MailParser objParser = 
							new MailParser(voCachePath.getTemplatePath());

						// テンプレートからタイトルを取得します。
						String strTitle = objParser.getTitle();	// タイトルタグ題名を取得
						voCachePath.setTitle( strTitle );
					}
					catch( FileNotFoundException ex )
					{	// キャッシュリストの更新時にファイルなしエラーが発生した場合
						// キャッシュリストからそのファイル名を削除します。
						objTemplateList.remove(i);
					}
					catch( IOException ex )
					{	// キャッシュリストの更新時にIOエラーが発生した場合
						// キャッシュリストからそのファイル名を削除します。
						objTemplateList.remove(i);
					}
				}
			}
		}
		catch ( Exception ex )
		{
			throw ex;
		}
	}

	/**
	 * メール種別毎に対応するフォルダパスを取得する。<BR>
	 * @param  strMailType	メール種別
	 * @return strTemplateDirectoryPath テンプレートフォルダパス
	 */
	public String getTemplateDirectoryPath(String strMailType) {

		String strTemplateDirectoryPath = null;

		try {
			// ユーザ登録／更新用のメールテンプレートファイルリストを取得します。
			if ( strMailType.equals( MailConst.TYPE_REGIST ) ) {
				PeopleEnv objEnv = PeopleEnv.getInstance();
				strTemplateDirectoryPath = objEnv.getSendMailDir();
	
			// 一括登録用のメールテンプレートファイルリストを取得します。
			} else if ( strMailType.equals( MailConst.TYPE_LUMP ) ) {
				LumpInsertEnv objLumpEnv = LumpInsertEnv.getInstance();
				strTemplateDirectoryPath = objLumpEnv.getSendMailDir();
	
			// アサイン用のメールテンプレートファイルリストを取得します。		
			} else if ( strMailType.equals( MailConst.TYPE_ASSIGNMENTS ) ) {
				AssignmentsEnv objAssignEnv = AssignmentsEnv.getInstance();
				strTemplateDirectoryPath = objAssignEnv.getSendMailDir();
	
			// 激励用のメールテンプレートファイルリストを取得します。
			} else if ( strMailType.equals( MailConst.TYPE_STIMULATE ) ) {
				LoEnv objStimEnv = LoEnv.getInstance();
				strTemplateDirectoryPath = objStimEnv.getSendMailDir();
			}
		} catch (Exception ex) {
			return null;
		}
		return strTemplateDirectoryPath;
	}

}