/** {@inheritDoc} */
 @Override
 public Status getStatus(FileGroup fileGroup) {
   Map<String, Set<String>> parameterMap = new HashMap<String, Set<String>>();
   Set<String> fileGroupIdStringSet = new LinkedHashSet<String>();
   fileGroupIdStringSet.add(fileGroup.getId().toString());
   parameterMap.put(WaspJobParameters.FILE_GROUP_ID, fileGroupIdStringSet);
   JobExecution je =
       batchJobExplorer.getMostRecentlyStartedJobExecutionInList(
           batchJobExplorer.getJobExecutions(FLOW_NAME, parameterMap, false));
   if (je == null) return Status.UNKNOWN;
   ExitStatus jobExitStatus = je.getExitStatus();
   if (jobExitStatus.isRunning()) return Status.STARTED;
   if (jobExitStatus.isCompleted()) return Status.COMPLETED;
   return Status.FAILED;
 }
  /**
   * Run the specified job, handling all listener and repository calls, and delegating the actual
   * processing to {@link #doExecute(JobExecution)}.
   *
   * @see Job#execute(JobExecution)
   * @throws StartLimitExceededException if start limit of one of the steps was exceeded
   */
  @Override
  public final void execute(JobExecution execution) {

    logger.debug("Job execution starting: " + execution);

    try {

      jobParametersValidator.validate(execution.getJobInstance().getJobParameters());

      if (execution.getStatus() != BatchStatus.STOPPING) {

        execution.setStartTime(new Date());
        updateStatus(execution, BatchStatus.STARTED);

        listener.beforeJob(execution);

        try {
          doExecute(execution);
          logger.debug("Job execution complete: " + execution);
        } catch (RepeatException e) {
          throw e.getCause();
        }
      } else {

        // The job was already stopped before we even got this far. Deal
        // with it in the same way as any other interruption.
        execution.setStatus(BatchStatus.STOPPED);
        execution.setExitStatus(ExitStatus.COMPLETED);
        logger.debug("Job execution was stopped: " + execution);
      }

    } catch (JobInterruptedException e) {
      logger.info("Encountered interruption executing job: " + e.getMessage());
      if (logger.isDebugEnabled()) {
        logger.debug("Full exception", e);
      }
      execution.setExitStatus(getDefaultExitStatusForFailure(e));
      execution.setStatus(BatchStatus.max(BatchStatus.STOPPED, e.getStatus()));
      execution.addFailureException(e);
    } catch (Throwable t) {
      logger.error("Encountered fatal error executing job", t);
      execution.setExitStatus(getDefaultExitStatusForFailure(t));
      execution.setStatus(BatchStatus.FAILED);
      execution.addFailureException(t);
    } finally {

      if (execution.getStatus().isLessThanOrEqualTo(BatchStatus.STOPPED)
          && execution.getStepExecutions().isEmpty()) {
        ExitStatus exitStatus = execution.getExitStatus();
        execution.setExitStatus(
            exitStatus.and(
                ExitStatus.NOOP.addExitDescription(
                    "All steps already completed or no steps configured for this job.")));
      }

      execution.setEndTime(new Date());

      try {
        listener.afterJob(execution);
      } catch (Exception e) {
        logger.error("Exception encountered in afterStep callback", e);
      }

      jobRepository.update(execution);
    }
  }