package jp.terasoluna.batch.functionsample.b001;

import java.util.Random;

import jp.terasoluna.fw.batch.blogic.BLogic;
import jp.terasoluna.fw.batch.blogic.vo.BLogicParam;
import jp.terasoluna.fw.batch.util.BatchUtil;
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.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;

/**
 * DB関連ジョブのサンプル<br>
 * <br>
 * 
 * 事前準備：EMPLOYEEテーブルを作成しておくこと<br>
 * <br>
 * サンプル内容：セーブポイントはリリースされた後、そのセーブポイントにロールバックしようとしエラーが発生することを確認するサンプル。
 * （releaseSavepointはOracleのJDBCドライバではサポートしていないため、postgreSQLのみ対象となる）。
 * 
 * 
 */
public class B001006BLogic implements BLogic {

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

	private static final int BATCH_NORMAL_END = 0;
	private static final int BATCH_ABNORMAL_END = 255;

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

	@Autowired
	@Qualifier("transactionManager")
	private PlatformTransactionManager transactionManager = null;

	public int execute(BLogicParam arg0) {

		Random rnd = new Random();
		Object savePoint1 = null;
		Object savePoint2 = null;

		TransactionStatus stat = null;
		int max_count = 100;
		int commitTimes = 10;

		if (arg0 != null && arg0.getJobArgNm1() != null) {
			max_count = Integer.parseInt(arg0.getJobArgNm1());
		}

		if (arg0 != null && arg0.getJobArgNm2() != null) {
			commitTimes = Integer.parseInt(arg0.getJobArgNm2());
		}

		try {
			stat = BatchUtil.startTransaction(transactionManager);

			int count = updateDAO.execute("B001006.deleteEmployee", null);

			if (count == 0) {
				BatchUtil.rollbackTransaction(transactionManager, stat);
				return BATCH_ABNORMAL_END;
			} else {

				for (int i = 1; i <= max_count; i++) {

					B001006Param newUser = new B001006Param();

					newUser.setId(i);
					newUser.setFamilyName("木村");
					newUser.setFirstName("太郎");
					newUser.setAge(rnd.nextInt(99) + 1);

					updateDAO.execute("B001006.insertEmployee", newUser);

					// 50件毎にせ―プポイントを設定する
					if (i % 50 == 0) {
						savePoint1 = BatchUtil.setSavepoint(stat);
						log.info(i + "セーブポイント設定 savePoint1");
					}

					if (i % 10 == 0) {
						savePoint2 = BatchUtil.setSavepoint(stat);
						log.info(i + "セーブポイント設定 savePoint2");

						if (i > 50 && savePoint1 != null) {
							log.info("savePoint1 セーブポイントリリース");
							BatchUtil.releaseSavepoint(stat, savePoint1);
						}

					}

					// 75件目で50件目のセーブポイントに戻りコミットして終了する。
					if (i == 75) {
						BatchUtil.rollbackSavepoint(stat, savePoint1);

						BatchUtil.commitTransaction(transactionManager, stat);

						return BATCH_ABNORMAL_END;
					}

				}

				BatchUtil.commitTransaction(transactionManager, stat);

				return BATCH_NORMAL_END;
			}

		} finally {

			BatchUtil.endTransaction(transactionManager, stat);
		}
	}

}
