package jp.terasoluna.batch.functionsample.b001;

import java.util.ArrayList;
import java.util.List;
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>
 * サンプル内容：10件ごとにセーブポイントを設定し、指定したセーブポイント(40件目）にロールバックし、それまでの処理をコミットするサンプル。
 * 
 * 
 */
public class B001005BLogic implements BLogic {

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

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

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

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

	public int execute(BLogicParam arg0) {

		Random rnd = new Random();
		List<Object> savePoint = new ArrayList<Object>();

		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("B001005.deleteEmployee", null);

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

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

					B001005Param newUser = new B001005Param();

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

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

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

						BatchUtil.commitTransaction(transactionManager, stat);

						return BATCH_ABNORMAL_END;
					}

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

				BatchUtil.commitTransaction(transactionManager, stat);

				return BATCH_NORMAL_END;
			}

		} finally {

			BatchUtil.endTransaction(transactionManager, stat);
		}
	}

}
