/********************************************************************
 * Copyright © 2006 VHA. All rights reserved
 ********************************************************************/

package gov.va.med.fw.scheduling;

import java.sql.Connection;
import java.sql.SQLException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.JobPersistenceException;
import org.springframework.scheduling.quartz.LocalDataSourceJobStore;

/**
 * This custom JobStore is necessary to reduce the contention on QRTZ_LOCKS
 * table in trigger/job insertions and misfire handler thread.
 * 
 * <p>
 * doRecoverMisfires() method CAN BE REMOVED AFTER QUARTZ 1.6.x INTEGRATION as
 * this improvement is implemented in it via Quartz property
 * org.quartz.jobStore.doubleCheckLockMisfireHandler.
 *
 * <p>
 * rollbackConnection() method CAN BE REMOVED AFTER QUARTZ 1.6.x INTEGRATION as
 * this defect (http://jira.opensymphony.com/browse/QUARTZ-415 ) is implemented in it.
 * 
 * Created Nov 2, 2006 4:05:36 PM
 * 
 * @author DNS   BOHMEG
 */
public class PersistentJobStore extends LocalDataSourceJobStore {
	protected final Log logger = LogFactory.getLog(getClass());

	public PersistentJobStore() {
		super.setLockOnInsert(false);
	}
	
	protected void rollbackConnection(Connection conn)
			throws JobPersistenceException {
		if (conn != null)
			try {
				conn.rollback();
			} catch (SQLException e) {
                logger.error(
                        "Couldn't rollback jdbc connection. "+e.getMessage(), e);
			}
	}

	protected boolean doRecoverMisfires() throws JobPersistenceException {
		Connection conn = null;
		try {
			conn = getNonManagedTXConnection();
			// first check to see if any misfires exist before doing inherited
			// actions...should reduce contention.
			int currentMisfireCount = getDelegate().selectTriggersInState(conn,
					STATE_MISFIRED).length;
			if (currentMisfireCount > 0) {
				if (logger.isDebugEnabled())
					logger.debug("Misfire situation detected for "
							+ currentMisfireCount + " triggers");
				return super.doRecoverMisfires();
			}

			if (logger.isDebugEnabled())
				logger.debug("No Misfires detected for object: "
						+ System.identityHashCode(this));
		} catch (Exception e) {
			super.rollbackConnection(conn);
		} finally {
			super.closeConnection(conn);
		}
		return false;
	}
}
