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

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Vector;

import jp.co.ntt.lms.xmo.DataAccess;
import jp.co.ntt.lms.xmo.MenuData;
import jp.co.ntt.lms.xmo.MessageData;
import jp.co.ntt.lms.xmo.XMO;
import jp.co.ntt.lms.xmo.XMOException;
import jp.co.ntt.lms.xmo.XMOPropertyDef;
import jp.co.ntt.lms.xmo.Message.MessageClient;
import jp.co.ntt.lms.xmo.util.FileControl;
import jp.co.ntt.lms.xmo.util.DebugLog;

/**
 * 一括登録 XMO サーバクラスです。<BR>
 * XMO基本メソッドを実装し、クライアントからの一括登録
 * 要求をうけそれぞれの処理を行います。<BR>
 * RMIサーバとして動作するためRemoteインタフェースであるXMOインタフェースを実装し、
 * 永続的な起動状態を確保するためjava.rmi.server.UnicastRemoteObjectクラスを継承します。
 * @author T.Nijou
 * @version 0.0.0.1 2004/01/08
 */
public class LumpInsert extends UnicastRemoteObject
	implements XMO, LumpInsertParam, LumpInsertMessage
{

	//////////////////////////////////////////////////////////////////
	// メソッド名定義
	//////////////////////////////////////////////////////////////////
	/** 一括登録メソッド名です */
	private static final String METHOD1 = "insert";	// 一括登録

	/** アップロードメソッド名です */
	private static final String METHOD2 = "upload";	// アップロード


	/** 一括登録ファイル取得メソッド名です */
	private static final String METHOD3 = "getFileList";	// リスト取得


	/** メール送信の１回あたりの送信件数を取得するメソッド名称 */
	private static final String METHOD4 = "getSendMailCount";
	/**
	 * ＲＭＩ戻り値Ｍａｐキー：エラーメッセージ。
	 */
	private static final String KEY_ERROR_MESSAGE = "errormessage";

	/**
	 * ＲＭＩ戻り値Ｍａｐキー：送信件数。
	 */
	private static final String KEY_SEND_MAIL_COUNT = "sendMailCount";

	/**
	 * コンストラクタです。<BR>
	 */
	public LumpInsert() throws RemoteException {
		// リモートオブジェクトをエクスポートする
		// java.rmi.server.UnicastRemoteObject の
		// 引数なしのコンストラクタを呼び出す
		super();
	}

	/**
	 * メニュー一覧を返します
	 * @return Vector メニュー一覧
	 */
	public Vector getMenuList(Hashtable htbParam) {
		Vector vecMenuList = new Vector();
		try {
			LumpInsertEnv objEnv = LumpInsertEnv.getInstance();
			vecMenuList = objEnv.getMenuList();
		}
		catch( Exception e ) {
			return new Vector();
		}
		return vecMenuList;
	}

	/**
	 * メソッド一覧を返します
	 * @return Vector
	 */
	public Vector getMethodList() {
		Vector vecMethod = new Vector();
		vecMethod.add( METHOD1 );
		vecMethod.add( METHOD2 );
		vecMethod.add( METHOD3 );
		vecMethod.add( METHOD4 );
		return vecMethod;
	}

	/**
	 * デフォルトメニューを返します
	 * @return MenuData
	 */
	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 = insert( htData );
		}

		if(strMethodName.equals(METHOD2))
		{
			objReturn = uploadLumpFile(htData);
		}

		if(strMethodName.equals(METHOD3))
		{
			objReturn = getLumpFileList();
		}

		else if( strMethodName.equals( METHOD4 ) )
		{
			objReturn = getSendMailCount( htData );
		}
		return objReturn;
	}

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

	/**
	 * 一括登録処理を行います。<BR>
	 * @param htData 登録情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納して返します)
	 */
	private Vector insert( Hashtable htData ) {
		Vector vecReturn = new Vector();

		String strFileName = (String)htData.get( LUMP_FILENAME );
		String strMailFlag = (String)htData.get( MAIL_FLG );
		String strLumpRootGroup = (String)htData.get( LUMP_GROUP_ROOT );
		String strLumpXML = (String)htData.get(LUMP_XML);

		MessageData objMessage = null;

		//一括登録ユーザリストの作成
		Vector vctUserList = new Vector();

		// トランザクションを管理するデータアクセスクラス
		DataAccess objDataAccess = new DataAccess();

		try
		{
			// パラメータチェック
			// ファイル名またはXMLどちらかは必須
			if( strFileName == null && strLumpXML == null ) {
				// @LOG >err >1
				DebugLog.write( this.getClass(), "一括登録:insert() ファイル名またはXMLは必須パラメータです。", DebugLog.HIGHT );
				throw new XMOException( PARAM_WAR );
			}

			// 登録グループIDが未指定の場合はルートを指定する。
			if( strLumpRootGroup == null ) {
				strLumpRootGroup = XMOPropertyDef.ROOT_GROUPID;
			}

			// ディレクトリ取得
			LumpInsertEnv objEnv = LumpInsertEnv.getInstance();
			String strDir        = objEnv.getLumpDir();						// LumpFileDisplayFile.jspと同様にする

			// パラメータでファイル名が指定されていた場合はファイルを読み込む
			if( strFileName != null ) {
				// ファイル読込処理
				File objFile             = new File(strDir + "/" + strFileName);
				FileInputStream objFis   = new FileInputStream(objFile);
				InputStreamReader objIsr = new InputStreamReader(objFis,"Windows-31J");
				BufferedReader objBr      = new BufferedReader(objIsr);

				StringBuffer strBuf      = new StringBuffer();

				while(true)
				{
					String strLine = objBr.readLine();
					if(strLine == null)
					{
						break;
					}
					strBuf.append(strLine);
				}

				objBr.close();
				objIsr.close();
				objFis.close();

				// 一括登録XML
				strLumpXML = strBuf.toString();
			}
DebugLog.write( this.getClass(), "一括登録XML出力::\n " + strLumpXML, DebugLog.ROW );

			// メール送信フラグの判定
			boolean blMailFlag = (strMailFlag != null && strMailFlag.equals("true") ? true : false );

			LumpParser objParser = new LumpParser( strLumpRootGroup );
			LumpTree objTree = objParser.parse(strLumpXML, blMailFlag);

			objTree.setUserList( vctUserList );
			// トランザクションの開始
			objDataAccess.trans();

			objTree.insert(strLumpRootGroup, objDataAccess);

			// コミット
			objDataAccess.commit();

			// グループあるいはユーザーが１件でもエラーならば
			LumpGroupAndPeople objTop = objTree.getTop();
			if(objTop.isFail())
			{
				throw new XMOException(INSERT_WAR);
			}

			// 正常終了メッセージ作成
			objMessage = getMessageData( INSERT_COMPLETE );

		}
		catch(XMOException xe)
		{
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ){}

			DebugLog.write(this.getClass(), xe, DebugLog.HIGHT);
			objMessage = xe.getMessageData();
			if(objMessage == null)
			{
				// メッセージオブジェクト生成
				objMessage     = getMessageData(xe.getMsgNum());
			}
		}
		catch( FileNotFoundException nfe ) {
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ){}
			DebugLog.write(this.getClass(), nfe, DebugLog.HIGHT);
			objMessage = getMessageData( FILE_NOT_FOUND_WAR );
		}
		catch( IOException ie ) {
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ){}
			DebugLog.write(this.getClass(), ie, DebugLog.HIGHT);
			objMessage = getMessageData( FILE_ACCESS_ERR );
		}
		catch( SQLException se ) {
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ){}
			// @LOG >err >1
			DebugLog.write(this.getClass(), se, DebugLog.HIGHT);
			// データベースエラーをスローする
			objMessage = getMessageData( DB_ERR );
		}
		catch(Exception e)
		{
			// ロールバック
			try { objDataAccess.rollback(); } catch( Exception ex ){}
			DebugLog.write(this.getClass(), e, DebugLog.HIGHT);
			objMessage = getMessageData( SYSTEM_ERR );
		}

		// メッセージデータオブジェクトの作成
		vecReturn.add( objMessage );
		vecReturn.add( vctUserList );
		return vecReturn;
	}

	/**
	 * アップロード処理を行います。<BR>
	 * @param htData アップロード情報
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納して返します)
	 */
	private Vector uploadLumpFile(Hashtable htData )
	{
		Vector vecReturn = new Vector();
		MessageData objMessage = null;
		String strFileName = "";
		String strLumpFile = (String)htData.get(LUMP_FILE);
		String strLumpLogin = (String)htData.get(LUMP_LOGIN);
		String strLumpRootGroup = (String)htData.get( LUMP_GROUP_ROOT );

		//	XMLが空の場合はエラーを返す
		if(strLumpFile.equals( "" )) {
			// メッセージオブジェクト生成
			objMessage = getMessageData( SAVE_WAR );
			vecReturn.add( objMessage );
			vecReturn.add(strFileName);
			return vecReturn;
		}
		try
		{
			LumpParser objParser = new LumpParser( strLumpRootGroup );
			strFileName = objParser.save(strLumpFile, strLumpLogin);

			// メッセージデータオブジェクトの作成
			objMessage = getMessageData( UPLOAD_COMPLETE );
		}
		catch(XMOException xe)
		{
			DebugLog.write(this.getClass(), xe, DebugLog.HIGHT);
			objMessage = xe.getMessageData();
			if(objMessage == null)
			{
				// メッセージオブジェクト生成
				objMessage     = getMessageData(xe.getMsgNum());
			}
		}
		catch(Exception e)
		{
			DebugLog.write(this.getClass(), e, DebugLog.HIGHT);
			// システムエラー
			objMessage = getMessageData( SYSTEM_ERR );
		}

		vecReturn.add( objMessage );
		vecReturn.add(strFileName);
		return vecReturn;
	}

	/**
	 * 一括登録リスト取得処理を行います。<BR>
	 * @return Vector 結果（配列の先頭にMessageDataオブジェクトを格納して返します)
	 */
	private Vector getLumpFileList()
	{
		Vector vecReturn = new Vector();
		MessageData objMessage = null;
		String[] strList = null;
		try
		{
			// 指定フォルダから一括登録ファイル一覧を取得
			LumpInsertEnv objEnv = LumpInsertEnv.getInstance();
			String strDir        = objEnv.getLumpDir();
			File objFile         = new File(strDir);
			FileControl objFc    = new FileControl();
			strList              = objFc.getFileList(strDir, 1);
		}
		catch(Exception e)
		{
			DebugLog.write(this.getClass(), e, DebugLog.HIGHT);
			objMessage = getMessageData(FILE_ACCESS_ERR);
		}

		// メッセージデータオブジェクトの作成
		objMessage = getMessageData( GETLIST_COMPLETE );
		vecReturn.add( objMessage );
		vecReturn.add(strList);

		return vecReturn;
	}

	/**
	 * メッセージオブジェクトを作成します
	 * @param strMessageID メッセージID
	 * @return MessageData メッセージオブジェクト 例外発生時はnullを返します
	 */
	private MessageData getMessageData( String strMessageID) {
		MessageData objMessage = null;
		try {
			MessageClient objMessageClient = new MessageClient( MSG_FIEL_PATH, MSG_FILE_NAME );
			objMessage = objMessageClient.getMessageData( strMessageID );
		}
		catch( Exception e ) {

		}
		return objMessage;
	}

	/**
	 * メール送信の１回あたりの送信件数を取得する。
	 * @param htbParam パラメータ・ハッシュテーブル。
	 * @return 送信件数またはエラーメッセージを含むMap。
	 * 以下のキー−値の組み合わせのいずれかを戻す。<br>
	 * <table border="1">
	 *	<tr>
	 *		<td>キー</td><td>型</td><td>内容</td>
	 *	</tr>
	 *	<tr>
	 *		<td>KEY_ERROR_MESSAGE</td><td>String</td><td>エラーメッセージ</td>
	 *	</tr>
	 *	<tr>
	 *		<td>KEY_SEND_MAIL_COUNT</td><td>Integer</td><td>送信件数</td>
	 *	</tr>
	 * </table>
	 * @see #KEY_ERROR_MESSAGE
	 * @see #KEY_SEND_MAIL_COUNT
	 * @see Integer
	 */
	private Map getSendMailCount( Hashtable htbParam ) {
		// このメソッドの戻り値
		Map returnValue = null;

		// アサインメント環境変数クラス 
		LumpInsertEnv objEnv = null;
		// 送信件数
		Integer sendMailCount = null;
		String  strSendMailCount = null;
		
		try {
			returnValue = new HashMap();
			// アサインメント環境変数クラスを取得
			objEnv = LumpInsertEnv.getInstance();
			//一括送信数を取得
			strSendMailCount = objEnv.getSendMailCount();
			// 数値化
			sendMailCount = new Integer(strSendMailCount);
			// 戻り値に格納
			returnValue.put(KEY_SEND_MAIL_COUNT, sendMailCount);
		} catch (Exception e) {
			// 例外発生時は、メッセージを格納
			DebugLog.write(this.getClass(), e,DebugLog.HIGHT);
			returnValue.put(KEY_ERROR_MESSAGE, e.getMessage());
		}
		return returnValue;	
	}
}

