#% CSVファイル出力 Javaソースファイル作成用の雛型ファイル
#% 2009/05/01 By S.Ito

#! package
package #package#;

#! csv out 1
#loggerComment#import org.apache.log4j.Logger;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;

/**
 * #nameJp# CSVファイル出力
 *
 * @author
 *
 */
public class #mstName#CsvFileOut implements RecordAction {

	// 出力ファイルのキャラクタセット
	protected String characterSetName = "MS932";

	// 出力ファイルの改行コード
	protected byte[] nextLineBytes = new byte[] { 0x0d, 0x0a };

	// 出力ファイル名
	protected String outputFileNname;

	// ヘッダ出力フラグ
	protected boolean outputHeader;

	// 出力件数
	protected int outputCount;

	// 出力ストリーム
	protected OutputStream outputStream;

	// 日付フォーマーット
	protected static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");

	// 時間フォーマーット
	protected static final SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");

	// 日時フォーマーット
	protected static final SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

	// ロガー
	#loggerComment#private static Logger logger = Logger.getLogger(#mstName#CsvFileOut.class);

	/**
	 * コンストラクタ
	 *
	 * @param outputFileNname
	 *            CSV出力ファイル名
	 * @param outputHeader
	 *            ヘッダ出力フラグ true=ヘッダを出力する
	 */
	public #mstName#CsvFileOut(String outputFileNname, boolean outputHeader) {
		this.outputFileNname = outputFileNname;
		this.outputHeader = outputHeader;
	}
	
	/**
	 * CSVフィル出力
	 * 
	 * @param searchObject
	 *            検索オブジェクト
	 * @throws Exception
	 *             エラー発生時
	 */
	public void csvFileOut(RecordSearch searchObject) throws Exception {

		try {
			#loggerComment#logger.info("START #nameJp#・CSVファイル出力処理");

			// 処理開始
			searchObject.search(this);

			#loggerComment#logger.info("END   #nameJp#・CSVファイル出力処理 出力件数 = " + getOutputCount());

		} catch (Exception e) {
			#loggerComment#logger.fatal("#nameJp#・CSVファイル出力処理でエラーが発生しました", e);
			throw e;
		}
	}

	/**
	 * 出力ファイルのキャラクタセット
	 *
	 * @param characterSetName
	 *            キャラクタセット
	 */
	public void setCharacterSetName(String characterSetName) {
		this.characterSetName = characterSetName;
	}

	/**
	 * 出力ファイルの改行コード設定
	 *
	 * @param nextLineBytes
	 *            改行コード
	 */
	public void setNextLineBytes(byte[] nextLineBytes) {
		this.nextLineBytes = nextLineBytes;
	}

	/**
	 * ファイル出力件数の
	 * @return
	 */
	public int getOutputCount(){
		return outputCount;
	}

	@Override
	public void initAction() throws Exception {
		outputCount = 0;
		outputStream = null;

		// 出力ファイルをオープン
		outputStream = new BufferedOutputStream(new FileOutputStream(outputFileNname));

		// ヘッダ出力判定
		if (outputHeader) {
			writeHeader();
		}

	}

	@Override
	public void closeAction() throws Exception {

		try {
			outputStream.flush();
		} finally {
			if (outputStream != null) {
				outputStream.close();
				outputStream = null;
			}
		}
	}

	/**
	 * ヘッダーレコード出力
	 *
	 * @param bos
	 * @throws UnsupportedEncodingException
	 * @throws IOException
	 */
	protected void writeHeader() throws UnsupportedEncodingException, IOException {

		StringBuilder sb = new StringBuilder();

		// ヘッダー文字組立て
#! header write
		sb.append(createSafeCsvField("#nameJp#"));
#! header write cnm
		sb.append(',');
#! csv out 2

		// ヘッダー出力
		outputStream.write(sb.toString().getBytes(characterSetName));
		outputStream.write(nextLineBytes);
	}

	@Override
	public void action(Object record) throws Exception {

		StringBuilder sb = new StringBuilder();

		#mntMast# rec = (#mntMast#) record;

		// 1レコード組み立て
#! data write
		sb.append(createSafeCsvField(rec.#getMethod#()));
#! data write cnm
		sb.append(',');
#! csv out 3

		// 1レコード出力
		outputStream.write(sb.toString().getBytes(characterSetName));
		outputStream.write(nextLineBytes);
		outputCount++;
	}

	/**
	 * CSVファイルの1項目の作成<BR>
	 * 『"』や『，』を補正する
	 *
	 * @param value
	 *            項目値
	 * @return 補正された項目値
	 */
	private String createSafeCsvField(Object value) {

		if (value == null) {
			return "";
		}

		String str = "";

		if (value instanceof Date) {
			str = dateFormat.format((Date) value);
		} else if (value instanceof Time) {
			str = timeFormat.format((Time) value);
		} else if (value instanceof Timestamp) {
			str = dateTimeFormat.format((Timestamp) value);
		} else if (value instanceof byte[]) {
			StringBuilder sb = new StringBuilder();
			for (byte b : (byte[]) value) {
				String hex = Integer.toHexString(b);
				if (hex.length() == 1) {
					sb.append('0');
				} else if (hex.length() > 2) {
					hex = hex.substring(hex.length() - 2);
				}
				sb.append(hex);
			}
			str = sb.toString();
		} else {
			str = value.toString();
		}

		// 改行はスペースに変換
		str = str.replaceAll("\\r\\n", " ");
		str = str.replaceAll("\\r", " ");
		str = str.replaceAll("\\n", " ");

		boolean fenceFlag = false;

		// 『"』は『""』に変換しダブルコーテーションで囲む
		if (str.indexOf('\"') >= 0) {
			str = str.replaceAll("\"", "\"\"");
			fenceFlag = true;
		}

		// 『,』が存在したらダブルコーテーションで囲む
		if (str.indexOf(',') >= 0) {
			fenceFlag = true;
		}

		if (fenceFlag) {
			str = "\"" + str + "\"";
		}
		return str;
	}

#! csv out main
	/**
	 * メインルーチン
	 *
	 * @param args
	 *            引数 1番目に出力を行うCSVファイル名
	 */
	public static void main(String[] args) {

		// パラメータチェック
		if (args.length < 1) {
			System.out.println("パラメーターエラー");
			System.exit(1);
		}

		// 出力するデータを検索して抽出するオブジェクトを作成
		// オブジェクトはRecordSearchインターフェースを実装していること（このサンプルでは#mstName#Daoを使用）
		#mstName#Dao dao = new #mstName#Dao();

		// 自クラスのオブジェクト作成
		#mstName#CsvFileOut myObj = new #mstName#CsvFileOut(args[0], true);

		try {

			// 処理開始
			myObj.csvFileOut(dao);

			// 出力件数表示
			System.out.println("出力件数:" + myObj.getOutputCount());
			System.exit(0);

		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

#! csv out 4
}
#!