public RepeatStatus execute(final StepContribution contribution, ChunkContext chunkContext) throws Exception {
StepContext context = StepSynchronizationManager.getContext();
final StepExecution stepExecution = (context != null) ? context.getStepExecution() : null;
final AtomicBoolean done = new AtomicBoolean(false);
final JobListener jobListener = new JobListener() {
@Override
public Object beforeAction() {
// double check the underlying thread to see whether it is aware of a step execution
if (StepSynchronizationManager.getContext() == null) {
StepSynchronizationManager.register(stepExecution);
return Boolean.TRUE;
}
return Boolean.FALSE;
}
@Override
public void afterAction(Object state) {
if (Boolean.TRUE.equals(state)) {
StepSynchronizationManager.close();
}
done.set(true);
synchronized (done) {
done.notify();
}
}
@Override
public void jobKilled(Job job) {
saveCounters(job, contribution);
saveJobStats(job, stepExecution);
}
@Override
public void jobFinished(Job job) {
saveCounters(job, contribution);
saveJobStats(job, stepExecution);
}
};
startJobs(jobListener);
boolean stopped = false;
// check status (if we have to wait)
if (isWaitForCompletion()) {
while (!done.get() && !stopped) {
if (stepExecution.isTerminateOnly()) {
log.info("Cancelling job tasklet");
stopped = true;
stopJobs(jobListener);
// wait for stopping to properly occur