2017-09-21 15 views
0

J'ai eu ce problème:Comment convertir une chaîne CRON en ScheduleExpression en Java?

J'ai un champ de texte,

Il devrait y avoir une expression de CRON écrit, et plus tard sauvé.

Maintenant, je besoin d'une méthode pour convertir la chaîne CRON (voici quelques exemples au hasard: http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/crontrigger.html) java ScheduleExpression (http://docs.oracle.com/javaee/6/api/javax/ejb/ScheduleExpression.html)

Mais, je ne sais pas comment le faire ...

J'ai un système d'exécution basé sur le minuteur, qui fonctionne seulement sur des jours, des semaines et des mois, mais maintenant je dois implémenter les modèles CRON, afin que les exécutions puissent être exécutées sur une période de temps spécifique ...

un petit code, juste pour me soutenir:

@Resource 
private TimerService timerService; 


@Timeout 
public void execute(Timer timer) { 
    Script s = (Script) timer.getInfo(); 
    execute(s, true); 
    System.out.println("Timer Service : " + s.getScriptId()); 
    System.out.println("Current Time : " + new Date()); 
    System.out.println("Next Timeout : " + timer.getNextTimeout()); 
    System.out.println("Time Remaining : " + timer.getTimeRemaining()); 
    System.out.println("____________________________________________"); 
    Date today = new Date(); 
    if (s.getTimerSetup().getEndDate() <= today.getTime()) { 
     stopTimer(s); 
    } 
} 


@Override 
public void startTimer(Script s) { 
    if (s.getTimerSetup().getTimerRepeat().equals("0")) { 
     return; 
    } 
    s.setStatus(true); 
    em.merge(s); 
    em.flush(); 
    if (s.getTimerSetup().getEndDate() > System.currentTimeMillis()) { 
     long timeOut = 1L; 
     String timerRepeat = s.getTimerSetup().getTimerRepeat(); 

     if (timerRepeat.equals("1")) {// day 
      timeOut = 1000L * 60L * 60L * 24L; 
     } else if (timerRepeat.equals("2")) {// week 
      timeOut = 1000L * 60L * 60L * 24L * 7L; 
     } else if (timerRepeat.equals("3")) {// month 
      timeOut = 1000L * 60L * 60L * 24L * 30L; 
     } else { 
      return; //Here is the part where the cron string is detected 
     } 

     long initialTimeOut = s.getTimerSetup().getStartDate() - System.currentTimeMillis(); 

     if (initialTimeOut < 0) { 
      long initCheck = initialTimeOut * -1; 
      while (initCheck > timeOut) { 
       initCheck -= timeOut; 
      } 
      initialTimeOut = timeOut - initCheck; 
     } 

     Boolean found = false; 
     if (timerService.getAllTimers().size() == 0) { 
      System.out.println("Started the timer for the script: " + s.getFileName()); 
      timerService.createTimer(initialTimeOut, timeOut, s); 
     } else { 
      for (Timer timer : timerService.getAllTimers()) { 
       if (((Script) timer.getInfo()).getScriptId() == s.getScriptId()) { 
        System.out.println("This script's timer was already started!"); 
        found = true; 
       } 
      } 

      if (!found) { 
       System.out.println("Started the timer for the script: " + s.getFileName()); 
       timerService.createTimer(initialTimeOut, timeOut, s); 
       found = true; 
      } 
     } 
    } else { 
     System.out.println("The script's end date has expired"); 
    } 
} 

J'ai marqué l'endroit où la chaîne cron est détectée (dans l'instruction if) Et j'ai besoin maintenant de transformer la chaîne en ScheduleExpression.

Et ensuite de l'exécuter avec les minuteurs normaux. (mais cela vient plus tard :))

S'il vous plaît aider. Merci d'avance.

+0

pourquoi ne pas utiliser [quartz] (http://www.quartz-scheduler.org/) – Frank

+0

Parce que je ne sais pas ce :) – newbie

+0

vous devriez en apprendre davantage sur le Web app et quartz plus tard! – Frank

Répondre

0

Je trouve la réponse, mais il a oublié d'y répondre, voici le code qui a fonctionné pour moi:

private ScheduleExpression parseCronExpressionToScheduleExpression(String cronExpression) { 

    if ("never".equals(cronExpression)) { 
     return null; 
    } 

    // parsing it more or less like cron does, at least supporting same fields (+ seconds) 

    final String[] parts = cronExpression.split(" "); 
    final ScheduleExpression scheduleExpression; 

    if (parts.length != 6 && parts.length != 5) { 
     scheduleExpression = scheduleAliases.get(cronExpression); 
     if (scheduleExpression == null) { 
      throw new IllegalArgumentException(cronExpression + " doesn't have 5 or 6 segments as excepted"); 
     } 
     return scheduleExpression; 
    } else if (parts.length == 6) { // enriched cron with seconds 
     return new ScheduleExpression() 
       .second(parts[0]) 
       .minute(parts[1]) 
       .hour(parts[2]) 
       .dayOfMonth(parts[3]) 
       .month(parts[4]) 
       .dayOfWeek(parts[5]); 
    } 

    // cron 
    return new ScheduleExpression() 
      .minute(parts[0]) 
      .hour(parts[1]) 
      .dayOfMonth(parts[2]) 
      .month(parts[3]) 
      .dayOfWeek(parts[4]); 
} 

Ainsi, si vous envoyez l'expression cron à la fonction, il fera une expression shedule sur de celui-ci, mais il ne fonctionne pas à 100% sur toutes les expressions cron, mais sur la plupart

Voici ce qui a fonctionné pour les postes individuels dans l'expression de cron

* works 
- works 
, works 
/ works 
last works (only in the part Day Of Month) 

Qu'est-ce que ne fonctionne pas sont les lettres, telles que L, et les autres, au moins pas lors de ma dernière vérification.

Espérons que cela aidera le prochain gars :)