/*********************************************************************
*  All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名			：eo顧客基幹システム
*	モジュール名		：JBSBatZMChoAzaDataCst
*	ソースファイル名	：JBSBatZMChoAzaDataCst.java
*	作成者				：富士通　
*	作成日				：2011年08月29日
*＜機能概要＞
*　修正廃止町字データ抽出部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v2.00.00  	2011/08/29  FJ) 山本	新規作成
*   v4.00.00	2012/11/14	FJ) 伊藤	【TAI-2012-0000140】品質強化対策
*	v4.01.00	2013/01/08  FJ）日野	【TAI-2012-0000142】バッチ異常終了時のメッセージについて【優先度A】
*********************************************************************/
package eo.business.service;

import java.util.ArrayList;

import eo.business.common.JBSbatBusinessService;
import eo.business.common.JBSbatZMFileReaderUtil;
import eo.business.common.JZMBatCommon;
import eo.business.common.JZMBatConst;
import eo.common.constant.JPCBatchMessageConstant;
import eo.framework.application.JBSbatBusinessException;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.util.JBSbatBusinessFileUtil;

/**
* 修正廃止町字データ抽出クラスです。<p>
*<BR>
* @author 富士通
*/
public class JBSbatZMChoAzaDataCst extends JBSbatBusinessService
{
	/**▼▼▼▼▼▼ツールから生成した宣言です 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成した宣言です 終了▲▲▲▲▲▲*/
	

	/* ++++++++++ v1.0.0 追加開始 ++++++++++ */
	
	/** 出力ファイル名称 */
	private static final String OUT_FILE_NAME = "ZMIFM004001.csv";

	/** 入力ファイル名称*/
	private static final String FILENAME = "maf7c.txt";
	
	/** 修正コード値  */
	private static final String SHUSEI_CD = "3";
	
	/** 廃止コード値 */
	private static final String HAISHI_CD = "5";
	
	/** 町字コード名称 */
	private static final String CHO_AZA_CD = "町字コード";

	/** 新町字コード名称 */
	private static final String NEW_CHO_AZA_CD = "新町字コード";

	/** 修正コード名称 */
	private static final String SHUSEI_CD_NM = "修正コード";

	/** 呼称変更年月名称 */
	private static final String KOSHO_CHG_YM = "呼称変更年月";

	/** 郵便番号変更年月名称 */
	private static final String PCD_CHG_YM = "郵便番号変更年月";
	
	/** 町字コード・新町字コードの正規表現 */
	private static final String AD_CD_REGEX = "[a-zA-Z0-9]{11}";
	
	/** 修正コードの正規表現 */
	private static final String SHUSEI_CD_REGEX = "[ a-zA-Z0-9]{1}";

	/** 年月の正規表現 */
	private static final String YM_REGEX = "[0-9]{6}";
	
	/** ファイルリーダー */
	private JBSbatZMFileReaderUtil fr = null;
	
	/** メッセージ置換文字　町字コード */
	private static final String MSG_CHO_AZA_CD = "町字コード";
	
	/* ++++++++++ v1.0.0 追加終了 ++++++++++ */
	
	/**
	 * 初期処理
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの初期処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した初期化のソースです 開始▼▼▼▼▼▼*/
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);
		/**▲▲▲▲▲▲ツールから生成した初期化のソースです 終了▲▲▲▲▲▲*/
	/**▲▲▲▲▲▲業務サービスの初期処理を記述してください。▲▲▲▲▲▲*/
		


		/* ++++++++++ v1.0.0 追加開始 ++++++++++ */
		try
		{
			String filePath = JZMBatCommon.getGaibuReceiveDir(JZMBatConst.ZMIFE003_DIR);
			fr = new JBSbatZMFileReaderUtil(filePath + FILENAME);
		}
		catch(Exception ex)
		{
			if(null != fr)
			{
				fr.close();
			}
			throw ex;
		}
		
		/* ++++++++++ v1.0.0 追加終了 ++++++++++ */
		
		
	}

	/**
	 * 主処理
	 * @return JBSbatOutputItem　出力情報
	 * @throws Exception
	 */
	public JBSbatOutputItem execute() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの主処理を記述してください。▼▼▼▼▼▼*/
		

		/* ++++++++++ v1.0.0 追加開始 ++++++++++ */
		
		// 0	町字コード
		// 1	新町字コード
		// 2	旧郵便番号
		// 3	旧郵便番号分割F
		// 4	件名不要コード
		// 5	都道府県名カナ
		// 6	市区町村名カナ
		// 7	大字通称名カナ
		// 8	字丁目名カナ
		// 9	都道府県名カ数
		// 10	市区町村名カ数
		// 11	大字通称名カ数
		// 12	字丁目カ数
		// 13	総カナ文字数
		// 14	都道府県名
		// 15	市区町村名
		// 16	大字通称名
		// 17	字丁目名
		// 18	都道府県名漢数
		// 19	市区町村名漢数
		// 20	大字通称名漢数
		// 21	字丁目名漢数
		// 22	総漢字文字数
		// 23	都道府県名字種
		// 24	市区町村名字種１
		// 25	市区町村名字種２
		// 26	大字通称名字種１
		// 27	大字通称名字種２
		// 28	字丁目名字種１
		// 29	字丁目名字種２
		// 30	施工年月−YYMM
		// 31	廃止年月−YYMM
		// 32	新町字CD年月-YYMM
		// 33	呼称変更年月-YYMM
		// 34	郵便番号変更年月−YYMM
		// 35	地番変更年月-YYMM
		// 36	通り名識別
		// 37	大字字フラグ
		// 38	字小字フラグ
		// 39	予備１
		// 40	修正コード
		// 41	郵便番号
		// 42	バーコード情報
		// 43	バーコード文字数
		// 44	郵便番号関連情報１
		// 45	郵便番号関連情報２
		// 46	親子関係識別フラグ
		// 47	親子関係対応コード
		// 48	通称フラグ
		// 49	予備２
		// 50	施工年月
		// 51	廃止年月
		// 52	新町字CD年月
		// 53	呼称変更年月
		// 54	郵便番号変更年月
		// 55	地番変更年月
		// 56	カスタマーバーコード変更年月
		// 57	親子関係変更年月
		// 58	通称フラグ変更年月
		JBSbatBusinessFileUtil outputFile = null;
		try
		{
			
			String path = JZMBatCommon.getMidDir();
			String outputFileName = OUT_FILE_NAME;
			String outputFilePath = path + outputFileName;
			
			// ファイル出力制御クラス生成
			outputFile = JZMBatCommon.createBusinessFileUtil(outputFilePath,
					JZMBatConst.SJIS,
					JZMBatConst.CRLF,
					JZMBatConst.CONMA);
			
			String data = fr.readLine();
			
			while(null != data)
			{
				String[] strArr = data.split(JZMBatConst.CONMA);
				
				// ファイル形式チェック
				if(59 != strArr.length)
				{
					throw new JBSbatBusinessException(JPCBatchMessageConstant.EZMB0090CW, new String[]{fr.getFilePath()});
				}
				
				String choAzaCd = JZMBatCommon.trim(strArr[0]);
				String newChoAzaCd = JZMBatCommon.trim(strArr[1]);
				String shuseiCd = JZMBatCommon.trim(strArr[40]);
				String koshoChgYM = JZMBatCommon.trim(strArr[53]);
				String pcdChgYM = JZMBatCommon.trim(strArr[54]);
				
				if(!singleCheck(new String[]{choAzaCd, newChoAzaCd, shuseiCd, koshoChgYM, pcdChgYM}))
				{
					throw new JBSbatBusinessException(JPCBatchMessageConstant.EZMB0060CW);
				}
				
				if(isShusei(shuseiCd, koshoChgYM, pcdChgYM) || isHaishi(shuseiCd, choAzaCd, newChoAzaCd))
				{
					ArrayList<String> outputlist = new ArrayList<String>(5);
					outputlist.add(choAzaCd);
					outputlist.add(newChoAzaCd);
					outputlist.add(shuseiCd);
					outputlist.add(koshoChgYM);
					outputlist.add(pcdChgYM);
					JZMBatCommon.printBusinessFileUtil(outputFile, outputlist);
				}
				data = fr.readLine();
			}
		}
		catch (Exception ex)
		{
			throw ex;
		}
		finally
		{
			try{
				if(outputFile != null)
				{
					outputFile.close();
				}
			}
			catch (Exception e1)
			{
			
			}
			try
			{
				if(fr != null)
				{
					fr.close();
				}
			}
			catch (Exception e2)
			{
				
			}
		}

		/* ++++++++++ v1.0.0 追加終了 ++++++++++ */
				
		return null;
		
	/**▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲*/
	}
	
		
	/* ++++++++++ v1.0.0 追加開始 ++++++++++ */
	
	/**
	 * 単項目チェックを行います。
	 * @param val チェック対象項目の配列
	 * @return チェック結果
	 */
	private boolean singleCheck(String[] val)
	{
		for(int i = 0; i < val.length; i++)
		{
			
			// 必須チェック
			if(null == val[i] || JZMBatConst.BLANK.equals(val[i]))
			{
				commonItem.getLogPrint().printBusinessErrorLog(JPCBatchMessageConstant.EZMB0030TW,
						new String[]{createErrMsg(getKmkNm(i), val[0])});
				return false;
			}
			
			// 桁数チェック
			if(!checkKeta(i, val[i].length()))
			{
				commonItem.getLogPrint().printBusinessErrorLog(JPCBatchMessageConstant.EZMB0050TW,
						new String[]{createErrMsg(getKmkNm(i), val[0])});
				return false;
			}
			
			// 属性チェック
			if(!checkZoku(i, val[i]))
			{
				commonItem.getLogPrint().printBusinessErrorLog(JPCBatchMessageConstant.EZMB0040TW,
						new String[]{createErrMsg(getKmkNm(i), val[0])});
				return false;
			}
		}
		return true;
	}
	
	/**
	 * 属性チェックを行います。
	 * @param i チェック対象項目番号
	 * @param val チェック対象項目の値
	 * @return チェック結果
	 */
	private boolean checkZoku(int i, String val)
	{
		if(0 == i)
		{
			return val.matches(AD_CD_REGEX);
		}
		else if(1 == i)
		{
			return val.matches(AD_CD_REGEX);
		}
		else if(2 == i)
		{
			return val.matches(SHUSEI_CD_REGEX);
		}
		else if(3 == i || 4 == i)
		{
			return val.matches(YM_REGEX);
		}
		return true;
	}
	
	
	/**
	 * 桁巣チェックを行います。
	 * @param i チェック対象項目番号
	 * @param length 桁数
	 * @return チェック結果
	 */
	private boolean checkKeta(int i, int length)
	{
		if(0 == i)
		{
			return 11 == length;
		}
		else if(1 == i)
		{
			return 11 == length;
		}
		else if(2 == i)
		{
			return 1 == length;
		}
		else if(3 == i || 4 == i)
		{
			return 6 == length;
		}
		return true;
	}
	
	/**
	 * エラー項目名称を返します
	 * @param i チェック対象項目番号
	 * @return エラー項目名称
	 */
	private String getKmkNm(int i)
	{
		String val = JZMBatConst.BLANK;
		if(0 == i)
		{
			val = CHO_AZA_CD;
		}
		else if(1 == i)
		{
			val = NEW_CHO_AZA_CD;
		}
		else if(2 == i)
		{
			val = SHUSEI_CD_NM;
		}
		else if(3 == i)
		{
			val = KOSHO_CHG_YM;
		}
		else if(4 == i)
		{
			val = PCD_CHG_YM;
		}
		
		return val;
	}
	
	
	/***
	 * 修正データかどうかを判定します。
	 * @param shuseiCd
	 * @param koshoChgYM
	 * @param pcdChgYM
	 * @return 判定結果
	 */
	private boolean isShusei(String shuseiCd, String koshoChgYM, String pcdChgYM)
	{
		
		// 次の条件をすべて満たすものを、修正データとして抽出する。
		// ・「修正コード」が、“3”（修正）である。
		// ・「呼称変更年月」が“000000”以外であるか、または、「郵便番号変更年月」が“000000”以外である。
		
		if(SHUSEI_CD.equals(shuseiCd))
		{
			if(!JZMBatConst.SIX_ZERO.equals(koshoChgYM) || !JZMBatConst.SIX_ZERO.equals(pcdChgYM))
			{
				return true;
			}
		}
		return false;
	}
	
	/***
	 * 廃止データかどうかを判定します。
	 * @param shuseiCd
	 * @param choAzaCd
	 * @param newChoAza
	 * @return 判定結果
	 */
	private boolean isHaishi(String shuseiCd, String choAzaCd, String newChoAza)
	{
		if(null == choAzaCd || null == newChoAza)
		{
			return false;
		}
		
		// 次の条件をすべて満たすものを、廃止データとして抽出する。
		// ・「修正コード」が、“5”（廃止）である。
		// ・「町字コード」と「新町字コード」が異なる値である。
		// 抽出条件に適合したレコードを、ファイル編集仕様に従い編集し、出力したものが、修正廃止町字データファイルとなる。 
		
		if(HAISHI_CD.equals(shuseiCd))
		{
			if(!choAzaCd.equals(newChoAza))
			{
				return true;
			}
		}
		return false;
	}

	/**
	 * エラーメッセージ作成処理です。
	 * @param strItem 項目名
	 * @param strKey キー値
	 * @return string メッセージ置換文字列
	 */
	private String createErrMsg(String strItem, String strKey)
	{
		StringBuffer sb = new StringBuffer();
		
		sb.append(strItem);
		sb.append(JZMBatConst.KAKKO_LEFT);
		sb.append(JZMBatConst.KEY);
		sb.append(JZMBatConst.ZENKAKU_COLON);
		sb.append(MSG_CHO_AZA_CD);
		sb.append(JZMBatConst.EQUAL);
		sb.append(strKey);
		sb.append(JZMBatConst.KAKKO_RIGHT);
		
		return sb.toString();
	}
	
	/* ++++++++++ v1.0.0 追加終了 ++++++++++ */
	
	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した終了処理のソースです 開始▼▼▼▼▼▼*/
		

		/* ++++++++++ v1.0.0 追加開始 ++++++++++ */
		
		
		if(fr != null)
		{
			// ReadWriteのClose
			fr.close();
		}
		
		/* ++++++++++ v1.0.0 追加終了 ++++++++++ */
		
		/**▲▲▲▲▲▲ツールから生成した終了処理のソースです 終了▲▲▲▲▲▲*/
	/**▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲*/
	}
	

	/**▼▼▼▼▼▼ツールから生成したメソッドです 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成したメソッドです 終了▲▲▲▲▲▲*/
}
