package jp.terasoluna.batch.functionsample.b009;

import jp.terasoluna.fw.batch.blogic.AbstractTransactionBLogic;
import jp.terasoluna.fw.batch.blogic.vo.BLogicParam;
import jp.terasoluna.fw.batch.dao.support.BatchUpdateSupport;
import jp.terasoluna.fw.batch.dao.support.BatchUpdateSupportImpl;
import jp.terasoluna.fw.batch.exception.BatchException;
import jp.terasoluna.fw.collector.Collector;
import jp.terasoluna.fw.collector.db.DBValidateCollector;
import jp.terasoluna.fw.collector.util.CollectorUtility;
import jp.terasoluna.fw.dao.QueryRowHandleDAO;
import jp.terasoluna.fw.dao.UpdateDAO;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.validation.Validator;

/**
 * 入力データ取得機能を使用した際の拡張例外ハンドリングのサンプル<br>
 * <p>
 * 事前準備：C:\tmp配下にinputB009001.csvファイルを配置すること(DB初期化用)<br>
 * </p>
 * <p>
 * サンプル内容：EMPLOYEE3テーブルを読み取り、EMPLOYEE2テーブルに出力する。<br>
 * 拡張例外ハンドリングを使用し、ステータスにはENDを返却する。<br>
 * (エラーはValidationErrorExceptionが投げられるように実装している)<br>
 * 入力チェックエラーが発生した時点で終了するが、終了ステータスは100をセットする。<br>
 * (タイミングによって、EMPLOYEE2テーブルに挿入される件数は変動する)
 *</p>
 */
@Component
public class B009002BLogic extends AbstractTransactionBLogic {

    private Log log = LogFactory.getLog(B009002BLogic.class);

    private static final int BATCH_NORMAL_END = 0;

    @Autowired
    @Qualifier("queryRowHandleDAO")
    private QueryRowHandleDAO queryRowHandleDAO = null;

    @Autowired
    @Qualifier("updateDAO")
    private UpdateDAO updateDAO = null;

    @Autowired
    @Qualifier("beanValidator")
    private Validator beanValidator = null;

    public int doMain(BLogicParam arg0) {

        int returnCode = BATCH_NORMAL_END;

        int insertCount = 0;

        if (log.isInfoEnabled()) {
            log.info("EMPLOYEE3テーブル読み込み:開始");
        }

        BatchUpdateSupport bus = new BatchUpdateSupportImpl();

        CustomCollectorExceptionHandler cceHandler = new CustomCollectorExceptionHandler();

        Collector<CsvRecord> collector = new DBValidateCollector<CsvRecord>(
                queryRowHandleDAO, "B009002.selectEmployees", CsvRecord.class,
                20, cceHandler, beanValidator);

        try {

            while (collector.hasNext()) {
                CsvRecord csvRecord = collector.next();
                if (csvRecord != null) {
                    log.info("NAME:" + csvRecord.getFamilyName());
                    // バッチ更新に追加
                    bus.addBatch("B009002.insertEmployee2", csvRecord);
                }
            }

            // バッチ更新実行
            insertCount = bus.executeBatch(updateDAO);

        } catch (Exception e) {
            throw new BatchException(e);
        } finally {
            // コレクタのクローズ
            CollectorUtility.closeQuietly(collector);
        }

        if (log.isInfoEnabled()) {
            log.info("EMPLOYEE2テーブル:" + insertCount + "件挿入しました。");
        }

        // １件でもエラーが発生した場合は、"100"を返却する。
        if (cceHandler.getErrorFieldCount() > 0) {
            return 100;
        }

        // 正常終了
        return returnCode;
    }
}
