/*******************************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
********************************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JSYejbECC0041A010TPDA
*	ソースファイル名：JSYejbECC0041A010TPDA.java
*	作成者			：EKek0070
*	日付			：2011年04月19日
*＜機能概要＞
*	SQLFacility
*	テンプレートDBアクセス部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	ｖ1.00.00
*
********************************************************************************/

package eo.ejb.cbs.sqlf;

import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.base.CAANSQLFacility;
import com.fujitsu.futurity.model.base.CAANRuntimeException;
import com.fujitsu.futurity.model.base.CAANJDBCUtil;
import com.fujitsu.futurity.model.ejb.common.JSYejbConnection;
import com.fujitsu.futurity.model.ejb.common.JSYejbLog;
import com.fujitsu.futurity.model.ejb.common.StatusCodes;
import com.fujitsu.futurity.model.ejb.common.fw.TemplateDBAccessHandler;
import com.fujitsu.futurity.model.ejb.common.fw.AgentDispatchContext;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.rmi.server.UID;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import eo.common.util.JCCFileUtil;
import eo.common.util.JCCFrameworkException;
import eo.common.util.JCCUnCompressFileUtil;
import eo.ejb.cbs.cbsmsg.ECC0041A010CBSMsg;
import eo.ejb.cbs.cbsmsg.ECC0041A010CBSMsg1List;
import eo.ejb.cbm.entity.CC0041ETMsg;
import eo.ejb.common.JCCModelCommon;

/**
*
*  テンプレートDBアクセス部品　ECC0041A010_SQLF<br>
*  入力された項目からSQL文を動的に組み立て、<br>
*  検索結果をCBSMsgにセットします。<br>
*/
public class JSYejbECC0041A010TPDA extends CAANSQLFacility implements TemplateDBAccessHandler{
	
	/**
	 * コンストラクタ
	 */
	public JSYejbECC0041A010TPDA()	{
	}
	
	/**
	*   ECC0041A010_SQLF<br>
	*   @param inMsg    入力値の格納されたCBSMsg <br>
	*   @return void
	*/
	public void invoke(CAANMsg inMsg,AgentDispatchContext inContext){
		
		// コネクション
		Connection con1 = null;
		
		// プリペアステートメント
		PreparedStatement pstmt = null;
		
		// リザルトセット
		ResultSet rsltQuery = null;
		
		/******************** 
		 * SQL文の作成
		 ********************/

		try{
			
			//コネクション取得
			con1 = JSYejbConnection.getConnection(CC0041ETMsg.getTableName());
			
			
			// SQL文_基本部1
			StringBuffer sql_Buff = new StringBuffer();
			sql_Buff.append(" SELECT ")
					.append("   CC0041.EFILE_KANRI_NO    EFILE_KANRI_NO, ")
					.append("   CC0041.GENE_ADD_DTM      GENE_ADD_DTM, ")
					.append("   CC0041.SYS_CD            SYS_CD, ")
					.append("   CC0041.FILE_CD           FILE_CD, ")
					.append("   CC0041.EFILE             EFILE, ")
					.append("   CC0041.BUTSURI_FILE_NM   BUTSURI_FILE_NM, ")
					.append("   CC0041.FILE_SIZE         FILE_SIZE, ")
					.append("   CC0041.ASSHUKU_FILE_SIZE ASSHUKU_FILE_SIZE, ")
					.append("   CC0041.FILE_DEL_YMD      FILE_DEL_YMD, ")
					.append("   CC0041.ADD_DTM           ADD_DTM, ")
					.append("   CC0041.ADD_OPEACNT       ADD_OPEACNT, ")
					.append("   CC0041.UPD_DTM           UPD_DTM, ")
					.append("   CC0041.UPD_OPEACNT       UPD_OPEACNT, ")
					.append("   CC0041.DEL_DTM           DEL_DTM, ")
					.append("   CC0041.DEL_OPEACNT       DEL_OPEACNT, ")
					.append("   CC0041.MK_FLG            MK_FLG ")
					.append(" FROM CC_T_EFILE_KANRI CC0041 ");
			// SQL文_個別部1
			if ( "1".equals( inMsg.getObject(ECC0041A010CBSMsg.FUNC_CODE).toString() ) ) {
 				sql_Buff.append(" WHERE CC0041.EFILE_KANRI_NO = ? ")
						.append("   AND CC0041.GENE_ADD_DTM = ? ")
						.append("   AND CC0041.MK_FLG = 0 ");
			}
			if ( "2".equals( inMsg.getObject(ECC0041A010CBSMsg.FUNC_CODE).toString() ) ) {
 				sql_Buff.append(" WHERE CC0041.EFILE_KANRI_NO = ? ")
						.append("   AND CC0041.GENE_ADD_DTM = (SELECT MAX(CC0041_GENE.GENE_ADD_DTM) ")
// 2012/08/16 FST)arata 単体製造品質チェック対応 start
						.append("              FROM CC_T_EFILE_KANRI CC0041_GENE WHERE CC0041_GENE.EFILE_KANRI_NO = CC0041.EFILE_KANRI_NO AND CC0041_GENE.MK_FLG = '0') ")
						.append("   AND CC0041.MK_FLG = '0' ");
// 2012/08/16 FST)arata 単体製造品質チェック対応 end
			}
			
			//prepareStatementにSQL文をセット
			pstmt = con1.prepareStatement(sql_Buff.toString());
			
			//ログ出力(SQL文の出力)
			JSYejbLog.outlog(inContext, JSYejbLog.DBACCESS, this.getClass(), sql_Buff);
			
			// PreparedStatementの指定されたパラメータカラムに 指定された値を設定
			if ( "1".equals( inMsg.getString(ECC0041A010CBSMsg.FUNC_CODE) ) ) {
				// パラメータの設定(ＫＥＹ＿電子ファイル管理番号を指定)
				CAANJDBCUtil.setParam(pstmt, 1, inMsg.getObject(ECC0041A010CBSMsg.KEY_EFILE_KANRI_NO));
				// パラメータの設定(ＫＥＹ＿世代登録年月日時分秒を指定)
				CAANJDBCUtil.setParam(pstmt, 2, inMsg.getObject(ECC0041A010CBSMsg.KEY_GENE_ADD_DTM));
			}
			if ( "2".equals( inMsg.getString(ECC0041A010CBSMsg.FUNC_CODE) ) ) {
				// パラメータの設定(ＫＥＹ＿電子ファイル管理番号を指定)
				CAANJDBCUtil.setParam(pstmt, 1, inMsg.getObject(ECC0041A010CBSMsg.KEY_EFILE_KANRI_NO));
			}
			
			// ResultSetの取得
			rsltQuery = pstmt.executeQuery();
			
			// ECC0041A010CBSMsgの明細にセットする項目
			String[] msgKeyList1 = {
					  ECC0041A010CBSMsg1List.EFILE_KANRI_NO
					, ECC0041A010CBSMsg1List.GENE_ADD_DTM
					, ECC0041A010CBSMsg1List.SYS_CD
					, ECC0041A010CBSMsg1List.FILE_CD
					, ECC0041A010CBSMsg1List.EFILE
					, ECC0041A010CBSMsg1List.BUTURI_FILE_NM
					, ECC0041A010CBSMsg1List.FILE_SIZE
					, ECC0041A010CBSMsg1List.ASSHUKU_FILE_SIZE
					, ECC0041A010CBSMsg1List.FILE_DEL_YMD
					, ECC0041A010CBSMsg1List.ADD_DTM
					, ECC0041A010CBSMsg1List.ADD_OPEACNT
					, ECC0041A010CBSMsg1List.UPD_DTM
					, ECC0041A010CBSMsg1List.UPD_OPEACNT
					, ECC0041A010CBSMsg1List.DEL_DTM
					, ECC0041A010CBSMsg1List.DEL_OPEACNT
					, ECC0041A010CBSMsg1List.MK_FLG
			};
			
			// 明細に処理結果(ResultSet)をマッピング
			CAANMsg[] outMsg1 = mapMessageList(rsltQuery,msgKeyList1,"eo.ejb.cbs.cbsmsg.ECC0041A010CBSMsg1List",0);
			// inMsg(CBSMsg)に明細をセット
			inMsg.set("ECC0041A010CBSMsg1List", outMsg1);
			

		} catch(SQLException e) {
			inMsg.set(ECC0041A010CBSMsg.STATUS, StatusCodes.FIND_DB_ERR);
			throw new CAANRuntimeException(e);
		} finally {
			// 資源の解放
			try{
				if(rsltQuery != null){
					rsltQuery.close();
				}
				if(pstmt != null){
					pstmt.close();
				}
				if(con1 != null){
					closeConnection(con1);
				}
			}catch(SQLException e){
				inMsg.set(ECC0041A010CBSMsg.STATUS, StatusCodes.FIND_DB_ERR);
				throw new CAANRuntimeException(e);
			}
		}
		
		//10.3.2 電子ファイルの解凍処理	
		
		final String DIR_UNCOMP_TMP = "DIR_UNCOMP_TMP";
		String errMSG = null;
		CAANMsg[] cAANMsgList = inMsg.getCAANMsgList("ECC0041A010CBSMsg1List");
		
		//(1)アプリケーションプロパティファイルからの設定値取得				
		//	(a) 解凍ファイル格納作業ディレクトリ取得
		String dirUncompTMP = JCCModelCommon.getApplicationConst(DIR_UNCOMP_TMP);
		//		@ 解凍ファイル格納作業ディレクトリが取得できない場合、システムエラーとして終了する。
		//		   throwする内容：「解凍ファイル格納作業ディレクトリ（キー：DIR_UNCOMP_TMP）が
		//アプリケーションプロパティファイル（AplConst）にて設定されていません。」
		//		A 取得できた場合、解凍ファイル格納作業ディレクトリを内部変数へ設定する。
		if (null == dirUncompTMP || dirUncompTMP.isEmpty())
		{
			errMSG = "解凍ファイル格納作業ディレクトリ（キー：DIR_UNCOMP_TMP）が"+
			  "アプリケーションプロパティファイル（AplConst）にて設定されていません。" + dirUncompTMP;
			throw new CAANRuntimeException(new JCCFrameworkException(errMSG));
		}
		String uid = null;
		String workDir = null;
//		String fileName = null;
		String filePath = null;
		File file = null;
		byte[] efile = null;
		ByteArrayInputStream bis = null;
		ByteArrayOutputStream bos = null;
		FileOutputStream fos = null;
		FileInputStream fis = null;
		OutputStream os = null;
		
		String uncompFilePath = null;
		
		for(int i = 0; i < cAANMsgList.length; i++)
		{
			//(2) 電子ファイル解凍処理
			//(a) 解凍ファイル格納作業ディレクトリ内でシステム一意となるディレクトリを（UIDにて）作成し、作業用ディレクトリを作成する。
			//(b) (a)で作成した作業用ディレクトリにて、システム一意となるファイル名を（UIDにて）作成する。				
			//(c) (a)および(b)で作成したディレクトリおよびファイル名より、ファイルパスを作成する。（@ + "/" + A）
			//(d) (a)および(b)で作成したディレクトリおよびファイル名より、ファイルオブジェクトを作成する。
			
			//　 作業ディレクトリの作成に失敗した場合は、Exceptionをスローし、解凍ファイル格納作業ディレクトリの削除を行う。				
			//   throwする内容：「作業ディレクトリの作成に失敗しました。
			//   (ディレクトリ指定の誤り／書き込み権限／同名ディレクトリの有無を確認してください）：ファイルパス」				
			//(e) 作成したファイルに、電子ファイルオブジェクトの書き込みを行う。
			//電子ファイルオブジェクトの書き込みに失敗した場合は、Exceptionをスローし、				
			//   解凍ファイル格納作業ディレクトリの削除を行う。				
			//   throwする内容：「解凍前ファイルの生成に失敗しました。：Exceptionの内容」
			uid = new UID().toString();
			//workDir = dirUncompTMP + File.separator + uid;
			
			try
			{
// 20110420 FST START
				//ファイル名の取得
				CAANMsg[] list = inMsg.getCAANMsgList(ECC0041A010CBSMsg.ECC0041A010CBSMSG1LIST);
				String zipFile = list[0].getString(ECC0041A010CBSMsg1List.BUTURI_FILE_NM);
				workDir = JCCFileUtil.createFileNameUid(dirUncompTMP);
				
				//ファイルのフルパスを取得
				zipFile = workDir + File.separator + zipFile;
				
				//ディレクトリの作成
				JCCFileUtil.createDir(zipFile);
// 20110420 FST END
			}
			catch (Exception e)
			{
				errMSG = "「作業ディレクトリの作成に失敗しました。"
					+ "(ディレクトリ指定の誤り／書き込み権限／同名ディレクトリの有無を確認してください）："
					+ workDir + "」";
				try
				{
// 20110420 FST START
//					JCCFileUtil.removeDir(dirUncompTMP);
					// 作成したディレクトリを削除
					File workFile = new File(workDir);
					if (null != workFile && workFile.exists() && workFile.isDirectory())
					{
						JCCFileUtil.removeDir(workDir);
					}
// 20110420 FST END
				}
				catch (Exception ex)
				{
				}
// 20110420 FST START
//				throw new CAANRuntimeException(new JCCFrameworkException(errMSG));
				throw new CAANRuntimeException(new JCCFrameworkException(errMSG, e));
// 20110420 FST END
			}
			
			/*
			uid = new UID().toString();
			fileName = workDir + File.separator + uid;
			filePath = fileName;
			*/

			
			try
			{
				filePath = JCCFileUtil.createFileNameUid(workDir);
				file = new File(filePath);
				efile = (byte[])(cAANMsgList[i].getObject(ECC0041A010CBSMsg1List.EFILE));
				bis = new ByteArrayInputStream(efile);
				fos = new FileOutputStream(file);
				os = JCCFileUtil.writeOutputStream(bis, fos);
				os.flush();
				//□□ 20110421 From
				//os.close();
				//□□ 20110421 To
			}
			
			catch (Exception e)
			{
				// JCCFrameworkExceptionをスローし、作業ディレクトリの削除
				try
				{
					JCCFileUtil.removeDir(workDir);
				}
				catch (Exception ex)
				{
				}
				throw new CAANRuntimeException(new JCCFrameworkException("解凍前ファイルの生成に失敗しました。", e));
			}
// 2012/08/14 FST)arata Fortify対応 start
			finally
			{
				try
				{
					if(fos != null)
					{
						fos.close();
					}
					if(os != null)
					{
						os.close();
					}
				}
				catch(IOException e)
				{
					throw new CAANRuntimeException(e);
				}
			}
// 2012/08/14 FST)arata Fortify対応 end
			
			//(f) ファイル解凍部品(JCCModelCommon.uncompressFile)を利用し、解凍後のファイルパスの取得を行う。			
			//   （引数：(2)(c)で作成したファイルパス、(2)(a)で作成した作業用ディレクトリパス、"0"）			
			//   ファイル解凍部品についての詳細は、「SSA26_部品仕様書(ファイル解凍部品)」参照。			
			//   部品からExceptionがthrowされた場合、呼び出し元へそのままthrowし、解凍ファイル格納作業ディレクトリを削除する。
			try
			{
				uncompFilePath = JCCUnCompressFileUtil.uncompressFile(filePath, workDir, "0");
			}
			catch (Exception e)
			{
				// JCCFrameworkExceptionをスローし、作業ディレクトリの削除
				try
				{
					JCCFileUtil.removeDir(workDir);
				}
				catch (Exception ex)
				{
				}
				throw new CAANRuntimeException(e);
			}
			//(g) (f)で取得した解凍後のファイルパスよりファイルオブジェクトを生成し、byte[]型へ変換し、電子ファイルへ格納する。
			try
			{
				file = new File(uncompFilePath);
				fis = new FileInputStream(file);
				byte[] b = new byte[1];
				bos = new ByteArrayOutputStream();
				while(fis.read(b) > 0)
				{
					bos.write(b);
				}
				
//				bos.close();
//				fis.close();
				
				b = bos.toByteArray();
				cAANMsgList[i].set(ECC0041A010CBSMsg1List.EFILE, b);
			}
			catch (FileNotFoundException e)
			{
				throw new CAANRuntimeException(e);
			}
			catch (IOException e) 
			{
				throw new CAANRuntimeException(e);
			}
// 2012/08/13 FST)arata Fortify対応 start
			finally
			{
				try
				{
					if(bos != null)
					{
						bos.close();
					}
					if(fis != null)
					{
						fis.close();
					}
				}
				catch(IOException e)
				{
					throw new CAANRuntimeException(e);
				}
			}
// 2012/08/13 FST)arata Fortify対応 end
			//(3) 作業用ディレクトリの削除				
			//(a) (1)で取得した解凍ファイル格納作業ディレクトリの削除を行う。
			try
			{
				JCCFileUtil.removeDir(workDir);
			}
			catch (Exception e)
			{
				throw new CAANRuntimeException("作業用ディレクトリの削除に失敗しました",e);
			}
		}
	}
}
