/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：プロジェクト共通
*   モジュール名    ：JTUBatFileUtil
*   ソースファイル名：JTUBatFileUtil.java
*   作成者          ：富士通
*   日付            ：2011年05月19日
*＜機能概要＞
*   ファイル出力・編集部品
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v3.00.00    2011/05/19   FJ) 北村    新規作成
*
**********************************************************************/
package eo.business.common;

import java.io.File;
import java.util.ArrayList;

import eo.common.constant.JTUStrConst;
import eo.framework.application.JBSbatBusinessException;
import eo.framework.file.JBSbatDefFileUtil;
import eo.framework.file.JBSbatInputFileUtil;
import eo.framework.file.JBSbatOutputFileUtil;
import eo.framework.util.JBSbatAplConst;
import eo.common.util.JCCFileUtil;
import eo.common.util.JCCFrameworkException;
import eo.framework.application.JCCbatFrameworkException;
import eo.framework.db.JBSbatSQLAccess;
import eo.framework.item.JBSbatCommonDBInterface;
import eo.framework.item.JBSbatCommonItem;


/**
 * 電話手続システム用ファイル出力・編集を提供する。<p>
 * ジョブで実装します。
 * <BR>
 * @author 富士通
 */
public class JTUBatFileUtil extends JCCBatCommon
{
	/**
	 * 圧縮レベルのプロパティファイルキー
	 */
	private static final String PROP_KEY_COMP_LEVEL = "COMP_LEVEL";
	
	/** SQL定義キー(KK_INSERT_002)*/
	private static final String DL_FILE_KANRI_INSERT_002 = "KK_INSERT_002";
	
	/**
	 * ファイルのリネーム処理を行います。<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.引数で対象ファイル名、出力ファイル名、出力ディレクトリを設定します。<br>
	 *
	 * 2.引数を元に対象ファイル名を出力ファイル名にリネームします。<br>
	 * 
	 * </pre>
	 * <p>
	 * @param filePath1    対象ファイルパス。
	 * @param filePath2    出力ファイルパス。
	 * @throws Exception      業務サービス内で発生した例外全般。
	 */
	public static void updateFileName(String filePath1, String filePath2) throws Exception
	{
	
		File outFile1 = new File(filePath1);

		File outFile2 = new File(filePath2);
		
		//リネーム処理(FileName1⇒FileName2)
		outFile1.renameTo(outFile2);
	}
	
	/**
	 * ファイルのリネーム処理を行います。<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.引数で対象ファイル名、出力ファイル名、出力ディレクトリを設定します。<br>
	 *
	 * 2.引数を元に対象ファイル名を出力ファイル名にリネームします。<br>
	 * 
	 * </pre>
	 * <p>
	 * @param fileName1    対象ファイル名。
	 * @param fileName2    出力ファイル名。
	 * @param fileDir      出力ディレクトリ。
	 * @throws Exception      業務サービス内で発生した例外全般。
	 */
	public static void updateFileName(String fileName1, String fileName2, String fileDir) throws Exception
	{
		//対象ファイル名
		String filePath1 = fileDir + "/" + fileName1;
		
		//出力ファイル名
		String filePath2 = fileDir + "/" + fileName2;
	
		File outFile1 = new File(checkFilePath(filePath1));

		File outFile2 = new File(checkFilePath(filePath2));
		
		//リネーム処理(FileName1⇒FileName2)
		outFile1.renameTo(outFile2);
	}
	
	/**
	 * ファイル出力先照査を行います。<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.引数でファイル出力先を設定します。<br>
	 *
	 * 2.引数を元に半角英数字記号にて構成されているか照査を行います。<br>
	 * 
	 * </pre>
	 * <p>
	 * @param fileOut    出力ファイルパス
	 * @return fileOut   出力ファイルパス
	 * @throws Exception    業務サービス内で発生した例外全般。
	 */
	private static String checkFilePath(String fileOut) throws Exception
	{
		if(fileOut.matches("^[a-zA-Z0-9 -/:_]+$")) 
		{
			return fileOut;
		}
		
		throw new JBSbatBusinessException("ETUB0220KE", new String[] {fileOut});
	}
	
	/**
	 * 件数、フラグファイル作成処理<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.件数調査ファイル(フルパス)をして、レコード件数を取得する<br>
	 *
	 * 2.件数、フラグファイル作成処理を呼び出す<br>
	 * 
	 * 3.件数ファイル、フラグファイルのフルパスをArrayListに設定し、返却<br>
	 * </pre>
	 * <p>
	 * @param cntTargetFile    件数調査ファイル(フルパス)
	 * @param cntFlgFile    件数フラグファイル名(拡張子なし)
	 * @param defFileId    定義ファイルID
	 * @return fileList   出力ファイルリスト
	 * @throws Exception    業務サービス内で発生した例外全般。
	 */
	public static ArrayList<String> createCntFlgFile(String cntTargetFile, String cntFlgFile, String defFileId) throws Exception
	{
		int fileRecordCnt = 0;
		
		// 件数調査ファイルオブジェクトを生成する
		JBSbatInputFileUtil cntTarget = new JBSbatInputFileUtil(cntTargetFile);
		
		// 件数調査定義ファイル名を取得する
		String cntTargetDefName = JBSbatAplConst.getAplConstValue(JTUStrConst.BAT_ID_IND) + defFileId + ".def";
		// 件数調査定義ファイルオブジェクトを生成する
		JBSbatDefFileUtil  cntTargetFileDef  = new JBSbatDefFileUtil(cntTargetDefName, cntTarget);
		
		// Readerオブジェクトを生成する。
		cntTarget.createReader();
		
		
		// データ件数取得
		while (cntTarget.ready()) 
		{
			cntTarget.readLine();
			fileRecordCnt++;
		}
		cntTarget.close();
		ArrayList<String> fileList = createCntFlgFile(fileRecordCnt, cntFlgFile, cntTarget.getEncode(), cntTarget.getLine());
		
		return fileList;
	}
	
	/**
	 * 件数、フラグファイル作成処理<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.件数フラグファイル名(拡張子なし)に.cntと.flgを付加<br>
	 *
	 * 2.件数ファイル、フラグファイルを作成<br>
	 * 
	 * 3.件数ファイル、フラグファイルのフルパスをArrayListに設定し、返却<br>
	 * </pre>
	 * <p>
	 * @param fileRecordCnt    ファイルレコード件数
	 * @param cntFlgFile    件数フラグファイル名(拡張子なし)
	 * @param encode    文字コード（ＯＳ準拠の場合は""（空）を指定）
	 * @param linefeed    改行コード（ＯＳ準拠の場合は""（空）を指定）
	 * @return fileList   出力ファイルリスト
	 * @throws Exception    業務サービス内で発生した例外全般。
	 */
	public static ArrayList<String> createCntFlgFile(int fileRecordCnt, String cntFlgFile, String encode, String linefeed) throws Exception
	{
		String cntFile = cntFlgFile + ".cnt";
		String flgFile = cntFlgFile + ".flg";
		
		// 件数ファイル作成
		JBSbatOutputFileUtil objCnt = new JBSbatOutputFileUtil(cntFile);
		objCnt.setLine(linefeed);
		objCnt.setEncode(encode);
		//Writerオブジェクトを生成する。
		objCnt.createWriter();
		
		objCnt.write(String.valueOf(fileRecordCnt));
		objCnt.close();
		
		//フラグファイル作成
		JBSbatOutputFileUtil objFlg = new JBSbatOutputFileUtil(flgFile);
		objFlg.setLine(linefeed);
		objFlg.setEncode(encode);
		
		//Writerオブジェクトを生成する。
		objFlg.createWriter();
		objFlg.close();
		
		ArrayList<String> fileList = new ArrayList<String>();
		fileList.add(cntFile);
		fileList.add(flgFile);
		return fileList;
	}
	
	/**
	 * ファイル登録処理<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 * 1.初期処理<br>
	 *
	 * 2.ファイル圧縮処理<br>
	 * 
	 * 3.電子ファイル管理処理<br>
	 * 
	 * 4.ダウンロードファイル管理登録処理<br>
	 * 
	 * 5.ファイル削除処理<br>
	 * 
	 * </pre>
	 * <p>
	 * @param commonItem    バッチ共通パラメータ電文
	 * @param trnKanriNo    処理管理番号
	 * @param dataCnt    データ件数
	 * @param fileCd    ファイルコード
	 * @param fileDir    ファイルディレクトリ
	 * @param fileName    ファイル名
	 * @param fileDelYmd    ファイル削除年月日
	 * @param dbDlFileKanri    テーブルアクセスクラス
	 * @param isCompress    圧縮実行フラグ
	 * @throws JCCbatFrameworkException, Exception      業務サービス内で発生した例外全般。
	 */
	public void createFile(JBSbatCommonItem commonItem, String trnKanriNo, Long dataCnt, 
									String fileCd, String fileDir, String fileName, String fileDelYmd, 
									JBSbatSQLAccess dbDlFileKanri, boolean isCompress) throws JCCbatFrameworkException, Exception
	{
		if (!JCCBatCommon.isNotNull(fileDir) || !JCCBatCommon.isNotNull(fileName))
		{
			return;
		}
		// ファイルパス設定
		String filePath = fileDir + "/" + fileName;
		
		// 登録ファイルパス設定
		String insertFilePath = fileDir + "/" + fileName;
		
		if(isCompress)
		{
			// 圧縮実行フラグがTrueの場合、圧縮ファイルを作成する。
			// 圧縮レベルの取得
			String compLevel = getCompLevel();
			
			// ファイルの圧縮、圧縮ファイルのパスの取得
			insertFilePath = JCCBatCommon.compressFile(filePath, fileDir, compLevel);
		}
		
		File insertFile = new File(insertFilePath);
		
		// ファイル存在確認
		if (insertFile.exists())
		{
			// 電子ファイル管理登録処理
			String[] resultKey = null;		// 電子ファイル管理テーブルに登録された場合に返却されるPKEY
			
			resultKey = JCCBatCommon.createDenshiFile(commonItem, fileCd, insertFile.getPath(), fileDelYmd);
			
			// ダウンロードファイル管理登録処理
			JBSbatCommonDBInterface paramList = new JBSbatCommonDBInterface();
			
			// 処理管理番号
			paramList.setValue(trnKanriNo);
			// ファイル名
			paramList.setValue(insertFile.getName());
			// データ件数
			paramList.setValue(dataCnt);
			// 電子ファイル管理番号
			paramList.setValue(resultKey[0]);
			// 世代登録年月日時分秒
			paramList.setValue(resultKey[1]);
			
			// ダウンロードファイル管理登録
			createDlFileKanri(paramList, dbDlFileKanri);
			
			// ファイル削除処理
			if(isCompress)
			{
				// 圧縮実行フラグがTrueの場合、圧縮ファイル削除
				removeDir(insertFile.getPath());
			}
		}
		
		// ファイル存在確認
		File file = new File(filePath);
		if (file.exists())
		{
			// ファイル削除
			file.delete();
		}
	}
	
	/**
	 * 引数のファイルが残っている場合、そのファイルが入っているディレクトリごと削除する。
	 * @param filePath 削除対象のファイルパス
	 * @throws JCCFrameworkException
	 */
	private static void removeDir(String filePath) throws JCCFrameworkException
	{
		// 作業ディレクトリが残っていた場合、削除
		if(filePath != null)
		{
			File f_dir = new File(new File(filePath).getParent());
			if(f_dir.exists())
			{
				JCCFileUtil.removeDir(new File(filePath).getParent());
			}

		}
	}
	
	/**
	 * アプリケーションプロパティファイルから圧縮レベルを取得する。
	 * <br>
	 * @return 圧縮レベル
	 * @throws JCCbatFrameworkException バッチフレームワーク例外
	 */
	private static String getCompLevel() throws JCCbatFrameworkException 
	{
		// 圧縮レベル
		String compLevel = JCCBatCommon.getApplicationConst(PROP_KEY_COMP_LEVEL);
		if (!JCCBatCommon.isNotNull(compLevel))
		{
			throw new JCCbatFrameworkException("APLConst.propertiesに圧縮レベルの定義がありません。");
		}
		
		// 圧縮レベル（範囲チェック用）
		int intCompLevel = 0;
		try
		{
			intCompLevel = Integer.parseInt(compLevel);
		}
		catch (NumberFormatException e)
		{
			throw new JCCbatFrameworkException("圧縮レベルの定義が不正です。");
		}
		
		// 圧縮レベルの範囲確認
		if (intCompLevel < 1 || 9 < intCompLevel)
		{
			throw new JCCbatFrameworkException("圧縮レベルが範囲外の設定です。");
		}
		return compLevel;
	}
	
	/**
	 * ファイル登録処理<br>
	 * <p>
	 * <b>処理フロー</b><br>
	 * <pre>
	 *
	 * 1.DBアクセスを実行します。<br>
	 * 
	 * </pre>
	 * <p>
	 * @param paramList    SQLパラメータリスト
	 * @param dbDlFileKanri    テーブルアクセスクラス
	 * @throws Exception      業務サービス内で発生した例外全般。
	 */
	private static void createDlFileKanri(JBSbatCommonDBInterface paramList, JBSbatSQLAccess dbDlFileKanri) throws Exception
	{
	
		// DBアクセスを実行します
		dbDlFileKanri.executeBySqlDefine(paramList, DL_FILE_KANRI_INSERT_002);
	}
	
}
