/** @see org.quartz.JobListener#jobToBeExecuted(JobExecutionContext) */
  public void jobToBeExecuted(JobExecutionContext context) {

    try {
      ForEachListener forEachListener =
          new TrackNRestartListener(
              dataSource,
              tablePrefix,
              this.getName(),
              scheduler.getSchedulerName(),
              context.getJobDetail().getKey().getGroup(),
              context.getJobDetail().getKey().getName(),
              context.getFireInstanceId());
      context.getJobDetail().getJobDataMap().put(FOR_EACH_LISTENER, forEachListener);
    } catch (Exception e) {
      TrackNRestartMessageKind.ETNRPLUGIN0002.format(e);
      // getLog().error("Unexpected exception.",e);
    }

    Trigger trigger = context.getTrigger();

    JobDetail jobDetail = context.getJobDetail();
    JobDataMap jobDataMap = jobDetail.getJobDataMap();

    String params = "";
    for (Iterator<Entry<String, Object>> iterator = jobDataMap.entrySet().iterator();
        iterator.hasNext(); ) {
      Entry<String, Object> entry = (Entry<String, Object>) iterator.next();
      params += entry.getKey() + "=" + entry.getValue();
      if (iterator.hasNext()) {
        params += ", ";
      }
    }

    Object[] args = {
      jobDetail.getKey().getName(),
      jobDetail.getKey().getGroup(),
      new java.util.Date(),
      trigger.getKey().getName(),
      trigger.getKey().getGroup(),
      trigger.getPreviousFireTime(),
      trigger.getNextFireTime(),
      Integer.valueOf(context.getRefireCount()),
      context.getFireInstanceId(),
      params
    };

    try {

      // TODO : not for JobToBeFired ?
      //			insertJobDetail(this.getNonManagedTXConnection(), context);
      getLog().info(MessageFormat.format(getJobToBeFiredMessage(), args));
    } catch (Exception e) {
      getLog().error(MessageFormat.format(getJobToBeFiredMessage(), args, e));
    }
  }
  public void jobAdded(JobDetail jobDetail) {
    TrackNRestartMessageKind.ITNRPLUGIN0003.format(jobDetail.getKey());
    JobKey jobKey = jobDetail.getKey();
    JobDataMap currentJobDataMap = jobDetail.getJobDataMap();
    String restart = currentJobDataMap.getString(RESTARTED_FIRE_INSTANCE_ID);
    try {
      if (fetchJob(getNonManagedTXConnection(), jobKey)) { // group.job exists
        if (restart
            == null) { // simple tracking mode but such an initial execution of this job has already
          // been recorded
          TrackNRestartMessageKind.ITNRPLUGIN0004.format(jobKey);
          TrackNRestartMessageKind.WTNRPLUGIN0005.format(jobKey);
        } else {
          if (restart.trim().equals("_LAST_")) { // Retrieve last execution to restart it
            restart = fetchJobExecLast(getNonManagedTXConnection(), jobKey);
            if (restart != null) {

              jobDetail.getJobBuilder().usingJobData(RESTARTED_FIRE_INSTANCE_ID, restart);
              jobDetail.getJobBuilder().usingJobData(JOB_IDENTIFICATION_COMPLETE, false);

              TrackNRestartMessageKind.ITNRPLUGIN0006.format(jobKey, restart);
              scheduler.pauseJob(jobKey);
              scheduler.addJob(jobDetail, true); // WARNING recursivity !

            } else {
              breakJob(jobKey, TrackNRestartMessageKind.ETNRPLUGIN0007.format(jobKey, restart));
            }
          } else { // Retrieve numbered execution to restart it
            if (!currentJobDataMap.getBoolean(
                JOB_IDENTIFICATION_COMPLETE)) { // to break recursivity
              if (fetchJobExec(getNonManagedTXConnection(), jobKey, restart)) { // found

                JobDataMap previousJobDataMap =
                    (JobDataMap)
                        getJobExecParams(
                            getNonManagedTXConnection(),
                            jobKey,
                            restart); // retrieve JDM from job to restart

                completeWithMissingParams(currentJobDataMap, previousJobDataMap);

                jobDetail.getJobBuilder().usingJobData(JOB_IDENTIFICATION_COMPLETE, true);

                TrackNRestartMessageKind.ITNRPLUGIN0010.format(jobKey, restart);
                scheduler.addJob(jobDetail, true); // WARNING recursivity !

              } else { // not found
                breakJob(jobKey, TrackNRestartMessageKind.ETNRPLUGIN0007.format(jobKey, restart));
              }
              scheduler.resumeJob(jobKey);
            }
          }
        }
      } else { // group.job doesn't exist
        if (restart == null) { // simple tracking mode
          TrackNRestartMessageKind.ITNRPLUGIN0004.format(jobKey);
        } else { // inconsistent restarting mode
          breakJob(jobKey, TrackNRestartMessageKind.ETNRPLUGIN0013.format(jobKey, restart));
        }
      }
    } catch (TrackNRestartException e) {
      throw e;
    } catch (Exception e) {
      try {
        breakJob(jobKey, TrackNRestartMessageKind.ETNRPLUGIN0002.format(e));
        //				e.printStackTrace();
        //				scheduler.deleteJob(jobKey);
      } catch (SchedulerException e1) {
        getLog().error("Deleting " + jobKey + " caused exception.", e);
      }
    }
  }