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

//
//	Offline教材 サーバクラス
//			変更履歴
//				2004.01.08	新規作成	滝島　英幸
//
package jp.co.ntt.lms.lo.Offline;

import jp.co.ntt.lms.Common.RDF.*;
import jp.co.ntt.lms.lo.*;
import jp.co.ntt.lms.xmo.util.*;

import jp.co.ntt.lms.xmo.Lo.MaterialData;	// @pending この教材データオブジェクトは将来パッケージを変える
import jp.co.ntt.lms.xmo.MenuData;
import jp.co.ntt.lms.xmo.MessageData;

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
import java.util.*;
import java.sql.*;
import java.io.*;

/**
 * LO Offline教材 サーバクラスです。<BR>
 * 要求を受けたLOのメニューリストを作成して返します
 * RMIサーバとして動作するためRemoteインタフェースであるLoTopインタフェースを実装し、
 * 永続的な起動状態を確保するためjava.rmi.server.UnicastRemoteObjectクラスを継承します。
 * @author H.Takishima
 * @version 2.0.4.0.0 2004/0/08
 */
public class OfflineLo extends LoServer
	implements LoTop, LoPropertyDef
{

	//////////////////////////////////////////////////////////////////
	// メソッド名定義
	//////////////////////////////////////////////////////////////////

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

			mobjMenuMakerIF = new OfflineMenuMaker();
			mobjLearnManagerIF = new OfflineLearnManager();
			mobjSetupIF = new OfflineSetup();

	}

	/**
	 * 教材一覧を返します
	 *
	 * @param Hashtable パラメータリスト
	 * @return Vector メッセージデータと教材一覧
	 */
	public Vector getMaterialList( Hashtable htbParam )
	{
DebugLog.write( this.getClass(), "#########################################", DebugLog.ROW );
DebugLog.write( this.getClass(), "     Offline教材: getMaterialList Start", DebugLog.ROW );
DebugLog.write( this.getClass(), "#########################################", DebugLog.ROW );
		Vector vecLoMaterialList = new Vector();
		Vector vecRet            = new Vector();						
		MessageData objMd        = null;								
		try
		{
			// 環境ファイル読み込みクラスをインスタンス化します
			OfflineLoEnv objEnv = new OfflineLoEnv();
			// 教材Tempディレクトリパス取得
			String strMethodType = (String)htbParam.get("METHOD");
			String strMatID = (String)htbParam.get("MATERIALID");
			String strTempMaterialPath = "";
			//登録処理の場合、教材Tempディレクトリパス取得
			if(strMethodType.equals("INSERT")){
				strTempMaterialPath = objEnv.getTempMaterialPath();
			}
			//登録処理以外の場合、教材ディレクトリパス取得
			else{
				strTempMaterialPath = objEnv.getMaterialPath();
			}
			
DebugLog.write( this.getClass(), "TempMaterialPath : [" + strTempMaterialPath + "]", DebugLog.ROW );
			FileControl objFile = new FileControl();
			String[] strDirList = objFile.getFileList(strTempMaterialPath,
													  FileControl.DIR_LIST);
			
			// ディレクトリと同数分のxmlファイルが必ずある
			String[] strFileList = new String[strDirList.length];
			for(int i = 0; i < strDirList.length; i++)
			{
				try
				{
					if(strMethodType.equals("INSERT") || (!strMethodType.equals("INSERT") && strMatID.equals(strDirList[i]))){
					
						// ファイルパス(例 D:/material_temp/教材ID/教材ID.xml)を作成
						String strFilePath = strTempMaterialPath + "/" + 
											 strDirList[i] + "/" + 
											 strDirList[i] + ".xml";
						
						// ファイルが存在しない場合、処理をスキップします。
						File objFilePath = new File(strFilePath);
						if(objFilePath.exists() == false){
							continue;
						}
						
DebugLog.write( this.getClass(), "FilePath : [" + strFilePath + "]", DebugLog.ROW );
						// IDとタイトル読込み処理
						RDFDocument objRdf   = new RDFDocument();
						RDFNode     objNode  = objRdf.load(strFilePath);
						String strMaterialID = objNode.getMaterialID();					// 教材ID読込み
						String strTitle      = objNode.getTitle();						// 教材タイトル読込み
						MaterialData objMaterial = new MaterialData();
						objMaterial.setMaterialID(strMaterialID);						// 教材ID
						objMaterial.setTitle(strTitle);									// 教材タイトル
						vecLoMaterialList.add(objMaterial);
						
					}
				}
				catch(RDFParseException re)											
				{
					// エラーが発生しても次のフォルダを読む(ファイルが見つからないエラー対応)
					DebugLog.write( this.getClass(), re.getMessage(), DebugLog.HIGHT );
					// スタックトレース出力
					DebugLog.write( this.getClass(), re, DebugLog.HIGHT );
				}
			}
			// Vectorを教材データリスト型に変換
			MaterialData[] objRet = new MaterialData[vecLoMaterialList.size()];
			vecLoMaterialList.copyInto(objRet);									
			vecRet.add(objRet);													
		}
		catch(Exception e)
		{
			// 教材構造ロード失敗時
			DebugLog.write( this.getClass(), e.getMessage(), DebugLog.HIGHT );
			objMd = createSystemErrMessage( e.getMessage() );					
		}
		vecRet.add(0, objMd);													
		return vecRet;															
	}

	/**
	 * メソッドリストを返します
	 * @param htbParam パラメータ
	 * @return Vector メッセージデータとメソッドリスト
	 */
	public Vector getMethodList(Hashtable htbParam) {
		// @pending ここに処理を記述します
		Vector vecRet     = new Vector();
		Object objRet     = null;
		MessageData objMd = null;
		vecRet.add(objMd);
		vecRet.add(objRet);
		return vecRet;
	}

	/**
	 * デフォルトメニューURLを返します
	 * @param htbParam パラメータ
	 * @return Vector メッセージデータとデフォルトメニュー情報
	 */
	public Vector getDefaultMenu(Hashtable htbParam) {
		// @pending ここに処理を記述します
		Vector vecRet     = new Vector();
		Object objRet     = null;
		MessageData objMd = null;
		vecRet.add(objMd);
		vecRet.add(objRet);
		return vecRet;
	}

	/**
	 * 各Loに登録されているメソッドを起動します
	 * @param strMehodName 起動するメソッド名
	 * @param objParams 起動するメソッドのパラメータ
	 * @return Vector メッセージデータと実行結果
	 */
	public Vector execute( String strMethodName, Hashtable htbParams ) {

		Vector vecRet     = new Vector();
		MessageData objMd = null;
		Object objRet     = null;
		vecRet.add(objMd);
		vecRet.add(objRet);
		return vecRet;
	};

	/**
	 * 個別ログの取得を行います
	 * @param htbParam パラメータ
	 * @return Vector メッセージデータと個別ログ取得結果
	 */
	public Vector getIndividualLog( Hashtable htbParam ) {
		Vector vecRet     = new Vector();
		MessageData objMd = null;
		Object objRet     = null;
		try {
			OfflineLoDataAccess objDataAccess = new OfflineLoDataAccess();
			objRet = objDataAccess.select( htbParam );
		}
		catch(LOException le)
		{
			// メッセージデータオブジェクトが取得できない場合は
			// システムエラーメッセージオブジェクトを生成
			objMd = createSystemErrMessage(le.getMessage());
		}
		vecRet.add(objMd);
		vecRet.add(objRet);
		return vecRet;

	}

	/**
	 * 個別ログ(CSV)の取得を行います
	 * @param htbParam パラメータ
	 * @return Vector メッセージデータと個別ログ取得結果
	 */
	public Vector getIndividualLogCSV( Hashtable htbParam ) {

		Vector vecRet     = new Vector();
		MessageData objMd = null;
		Object objRet     = null;
		try {
			OfflineLoDataAccess objDataAccess = new OfflineLoDataAccess();
			objRet = objDataAccess.selectCSV( htbParam );
		}
		catch(Exception le)
		{
			// メッセージデータオブジェクトが取得できない場合は
			// システムエラーメッセージオブジェクトを生成
			objMd = createSystemErrMessage(le.getMessage());
		}
		vecRet.add(objMd);
		vecRet.add(objRet);
		return vecRet;
	}


	/**
	 * データ取得処理
	 *
	 * @param String
	 * @param Hashtable パラメータリスト
	 * @return Vector メッセージデータと実行結果データ
	 */
	public Vector getData(Hashtable htbParam)
	{
		Vector vecRet     = new Vector();
		MessageData objMd = null;
		Object objRet     = null;
		try {
			OfflineLoDataAccess objDataAccess = new OfflineLoDataAccess();
			objRet = objDataAccess.getData( htbParam );
		}
		catch(LOException le)
		{
			// メッセージデータオブジェクトが取得できない場合は
			// システムエラーメッセージオブジェクトを生成
			objMd = createSystemErrMessage(le.getMessage());
		}
		vecRet.add(objMd);
		vecRet.add(objRet);
		return vecRet;
	}
	
	/**
	 * 教材構造を取得するメソッドです
	 * @param objParams パラメータ
	 * @return Vector メッセージデータと実行結果
	 */
	public Vector getMaterialStruct(Hashtable htbParams)
	{
		Vector vecRet     = new Vector();
		MessageData objMd = null;
		Object objRet     = null;
		objRet = getMatStructure( htbParams );
		vecRet.add(objMd);
		vecRet.add(objRet);
		return vecRet;
	}
	
	/**
	 * 教材構造を取得するメソッドです
	 */
	private MaterialNode getMatStructure( Hashtable htbParams ) {

		MaterialNode objResultNode = null;

		String strMaterialID = (String)htbParams.get( "MATID" );
		String strAuID = (String)htbParams.get("AUID" );
		String strMaterialPath = (String)htbParams.get( "MatPath" );
		OfflineNode objNode = OfflineMaterialConverter.convertFromID( strMaterialID );

		if( strMaterialPath != null ) {
			objResultNode = objNode.searchChild( strMaterialPath );
		}
		else if( strAuID != null ) {
			objResultNode = objNode.searchAUID( strAuID );
		}


		return objResultNode;
	}

	/**
	 * OfflineLo個別ログ削除
	 *
	 * @param Hashtable パラメータリスト
	 * @return Vector メッセージデータ
	 */
	public Vector deleteIndividualLog(Hashtable htbParam)
	{
		Vector vecRet     = new Vector();
		MessageData objMd = null;
		try {
			OfflineLoLogDataAccess objDataAccess = new OfflineLoLogDataAccess();
			objDataAccess.delete( htbParam );
		}
		catch(LOException le)
		{
			// メッセージデータオブジェクトが取得できない場合は
			// システムエラーメッセージオブジェクトを生成
			objMd = createSystemErrMessage(le.getMessage());
		}
		catch(Exception e)
		{
			// メッセージデータオブジェクトが取得できない場合は
			// システムエラーメッセージオブジェクトを生成
			objMd = createSystemErrMessage(e.getMessage());
		}

		vecRet.add(objMd);
		return vecRet;
	}

	/**
	 * OfflineLo個別ログ更新
	 * @param htbParam	パラメータリスト
	 * @return Vector メッセージデータ
	 */
	public Vector changeTypeUpdateIndividualLog(Hashtable htbParam)
	{
		Vector vecRet     = new Vector();
		MessageData objMd = null;
		try {
			OfflineLoLogDataAccess objDataAccess = new OfflineLoLogDataAccess();
			objDataAccess.changeTypeUpdate( htbParam );
		}
		catch(LOException le)
		{
			// メッセージデータオブジェクトが取得できない場合は
			// システムエラーメッセージオブジェクトを生成
			objMd = createSystemErrMessage(le.getMessage());
		}
		catch(Exception e)
		{
			// メッセージデータオブジェクトが取得できない場合は
			// システムエラーメッセージオブジェクトを生成
			objMd = createSystemErrMessage(e.getMessage());
		}

		vecRet.add(objMd);
		return vecRet;
	}

	/**
	 * 教材構造ファイル内容取得メソッド
	 *
	 * @param Hashtable パラメータリスト
	 * @return Vector メッセージデータ
	 */
	public Vector getMaterialStructFile(Hashtable htbParams)
	{
		
		Vector vecRet     = new Vector();
		MessageData objMd = null;
		Object objRet     = null;
		String strFilePath = null;
		String strResult = "";
		
		String strMaterialID = (String)htbParams.get( "MATID" );
		
		try {
			// 環境ファイル読み込みクラスをインスタンス化します
			OfflineLoEnv objEnv = new OfflineLoEnv();
			// ファイルリスト取得
			String strMaterialListPath = objEnv.getMaterialPath();
			FileControl objFile = new FileControl();
			String[] strFileList = objFile.getFileList(strMaterialListPath, FileControl.DIR_LIST);
			for(int i = 0; i < strFileList.length; i++) {
				if ( strFileList[i].equals( strMaterialID ) ){
					// 教材IDに該当するディレクトリが見つかった場合はファイルパスを生成
					strFilePath = strMaterialListPath + "/" + 
										 strFileList[i] + "/" + 
										 strFileList[i] + ".xml";
					break;
				}
			}
			
			if ( strFilePath == null ){
				throw new Exception();
			}
			// ファイルを読み込む
			BufferedReader reader = null;
			try {
				
				FileInputStream objStream = new FileInputStream( strFilePath );
				InputStreamReader mFr = new InputStreamReader(objStream,"Windows-31J");
				
				reader = new BufferedReader(mFr);
				String strLine;
				StringBuffer sbAll = new StringBuffer(); 
				while ((strLine = reader.readLine()) != null) {
					sbAll.append(strLine);
				}
				strResult = sbAll.toString();
			} catch (FileNotFoundException e) {
				throw e;
			} catch (IOException e) {
				throw e;
			} finally {
				try {
					if (reader != null) {
						reader.close();
					}
				} catch (Exception e) {}
			}
		}
		catch( Exception e )
		{
			e.printStackTrace();
			// システムエラーメッセージオブジェクトを生成
			objMd = createSystemErrMessage("教材構造ファイルの読み込みに失敗しました。");
		}
		vecRet.add(objMd);
		vecRet.add(strResult);
		return vecRet;
	}

}

