package wowodc.background.tasks;
import java.text.DecimalFormat;
import java.text.Format;
import java.util.concurrent.Callable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import wowodc.background.utilities.Utilities;
import wowodc.eof.ResultItem;
import wowodc.eof.TaskInfo;
import com.webobjects.eocontrol.EOEditingContext;
import com.webobjects.eocontrol.EOGlobalID;
import com.webobjects.foundation.NSTimestamp;
import er.extensions.concurrency.IERXPercentComplete;
import er.extensions.concurrency.IERXStoppable;
import er.extensions.eof.ERXEC;
import er.extensions.eof.ERXEOControlUtilities;
import er.extensions.foundation.IERXStatus;
/**
* A task that <em>returns</em> an EOGlobalID result.
*
* What does this demonstration task do?
*
* A {@link TaskInfo} entity is created for every run of this task.
* Its attributes include
* <ul>
* <li>startNumber
* <li>endNumber
* <li>startTime
* <li>endTime
* </ul>
*
* For a random amount of time between 5 and 15 seconds, and
* starting at a random number, this task begins looking for prime numbers.
*
* Every number checked is stored as a {@link ResultItem} that is related to the {@link TaskInfo}
*
* @author kieran
*/
public class T04SimpleEOFTask implements Callable<EOGlobalID>, IERXStatus , IERXPercentComplete, IERXStoppable {
private static final Logger log = LoggerFactory.getLogger(T04SimpleEOFTask.class);
// Duration of the example task in milliseconds
private final long DURATION = 15000;
// Task elapsed time in milliseconds
private long _elapsedTime = 0l;
// Value between 0.0 and 1.0 indicating the task's percentage complete
private double _percentComplete = 0.0d;
// A message indicating current status
private String _status = "Starting...";
private long _numberToCheck = 0;
private long _count = 0;
private volatile boolean _isStopped = false;
private EOGlobalID _resultGid;
public EOGlobalID call() throws Exception {
_numberToCheck = Utilities.newStartNumber();
_elapsedTime = 0;
Format wholeNumberFormatter = new DecimalFormat("#,##0");
long startTime = System.currentTimeMillis();
// Create an EC and lock/try/finally/unlock.
EOEditingContext ec = ERXEC.newEditingContext();
ec.lock();
try {
// Create the new TaskInfo
TaskInfo taskInfo = ERXEOControlUtilities.createAndInsertObject(ec, TaskInfo.class);
// Task start time
taskInfo.setStartTime(new NSTimestamp(startTime));
taskInfo.setStartNumber(_numberToCheck);
taskInfo.setDuration(DURATION);
// Loop for a period of time
while (_elapsedTime < DURATION && !_isStopped) {
ResultItem resultItem = ERXEOControlUtilities.createAndInsertObject(ec, ResultItem.class);
resultItem.setTaskInfo(taskInfo);
resultItem.setNumberToCheck(_numberToCheck);
if (Utilities.isPrime(_numberToCheck)) {
log.info("==>> {} is a PRIME number.", _numberToCheck);
resultItem.setIsPrime(Boolean.TRUE);
} else {
log.debug("{} is not a prime number but is a COMPOSITE number.", _numberToCheck);
resultItem.setIsPrime(Boolean.FALSE);
}
ec.saveChanges();
_elapsedTime = System.currentTimeMillis() - startTime;
// Update progress variables
_count++;
_percentComplete = (double)(_elapsedTime) / (double)DURATION;
_status = wholeNumberFormatter.format(_count) + " numbers checked for prime qualification";
_numberToCheck++;
}
// Complete the stats
taskInfo.setEndNumber(_numberToCheck - 1);
taskInfo.setEndTime(new NSTimestamp());
taskInfo.setWorkflowState(TaskInfo.WORKFLOW_PRIME_CHECKED);
ec.saveChanges();
_resultGid = ec.globalIDForObject(taskInfo);
} finally {
ec.unlock();
}
return _resultGid;
}
/* (non-Javadoc)
* @see er.extensions.concurrency.IERXPercentComplete#percentComplete()
*/
public Double percentComplete() {
return _percentComplete;
}
/* (non-Javadoc)
* @see er.extensions.foundation.IERXStatus#status()
*/
public String status() {
return _status;
}
/* (non-Javadoc)
* @see er.extensions.concurrency.IERXStoppable#stop()
*/
public void stop() {
log.info("The task was stopped by the user.");
_isStopped = true;
}
}