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

package gov.va.med.fw.batchprocess;

import java.util.List;

/**
 * Specialization of AbstractDataFileIncrementalProcess that allows for record processing
 * one record at a time.
 * 
 * Created Feb 16, 2006 2:09:21 PM
 * 
 * @author DNS   BOHMEG
 */
public abstract class AbstractDataFileSingleRowIncrementProcess extends
		AbstractDataFileIncrementalProcess {
	private boolean continueParsingIfErrors = true;
	private boolean keepProcessedData = false;

	/*
	 * (non-Javadoc)
	 * 
	 * @see gov.va.med.fw.batchprocess.AbstractDataProcess#processData(gov.va.med.fw.batchprocess.DataProcessExecutionContext,
	 *      java.util.List)
	 */
	public  void processDataRecords(DataFileProcessExecutionContext context,
			List acquiredData) {
		if(acquiredData.isEmpty())
			return;
		
		String rawData = context.getCurrentRowRawData();
		try {
			Object obj = acquiredData.get(0);
			if (processDataRecord(context, obj)) {
				context.getProcessStatistics()
						.incrementNumberOfSuccessfulRecords();
				if(keepProcessedData)
					context.getProcessedData().add(obj);
			} else {
				context.getProcessStatistics().incrementNumberOfErrorRecords();
				context.getExceptionData().add(createExceptionObject(rawData));
			}
		} catch (RuntimeException e) {
			if(logger.isErrorEnabled())
				logger.error("Error processing data record: " + rawData, e);
			context.getProcessStatistics().incrementNumberOfErrorRecords();
			context.getExceptionData().add(createExceptionObject(rawData));
			if (!continueParsingIfErrors)
				throw e;
		}
	}
	
	protected Object createExceptionObject(String rawData) {
		// default is to use rawData
		return rawData;
	}

	protected abstract boolean processDataRecord(
            DataFileProcessExecutionContext context, Object bean);

	public void afterPropertiesSet() {
		super.afterPropertiesSet();
		this.setIncrementSize(1);
	}

	/**
	 * @return Returns the keepProcessedData.
	 */
	public boolean isKeepProcessedData() {
		return keepProcessedData;
	}

	/**
	 * @param keepProcessedData The keepProcessedData to set.
	 */
	public void setKeepProcessedData(boolean keepProcessedData) {
		this.keepProcessedData = keepProcessedData;
	}
	
	protected boolean shouldUpdateJobResult(DataFileProcessExecutionContext context) {
		// using an increment of 1 for each update is too extreme...tone it down
		return context.getProcessStatistics().isTotalNumberMod(DEFAULT_JOB_RESULT_UPDATE_INTERVAL);
	}			
}
