2010-03-02 6 views
23

Ich schreibe eine Zeitplanungsanwendung in Java mit Quartz. Ich verwende den CronTrigger, aber meine Cron-Ausdrücke werden vor der Planung in eine Datenbank eingegeben und basieren auf Benutzereingaben.Die Überprüfung eines Cron-Ausdrucks ist in Java gültig

Kann ich überprüfen, ob die Cron-Ausdrücke gültig sind, wenn ich sie erfasse? Ich würde lieber dies tun und dem Benutzer eine entsprechende Fehlermeldung geben, als zu warten, bis der Scheduler ausgeführt wird, und ich bekomme eine ParseException, wenn ich versuche, den Trigger zu erstellen. Das könnte Tage dauern, nachdem der Benutzer die Daten eingegeben hat.

Antwort

35

Können Sie nicht einfach einen Trigger erstellen, ohne ihn tatsächlich auszuführen? Sie können im Falle einer ParseException einfach entsprechendes Feedback geben. Wenn der Ausdruck in Ordnung ist, speichern Sie den Ausdruck in DB.

Edit: oder einfach tun:

org.quartz.CronExpression.isValidExpression(expression); 
+8

Beachten Sie, dass die Gültigkeit dieses Verfahren geprüft, nicht der Fall ist * Garantie *, die ein Ausdruck arbeiten. Z.B. 'isValidExpression (" 0 0 12 1/2 * MON-FRI * ")' gibt "true" zurück, aber zur Laufzeit wird 'UnsupportedOperationException" ausgelöst: Die Unterstützung für die Angabe eines Wochentags UND eines Tag-des-Monats-Parameters ist nicht implementiert . ' – Jonik

+0

In der Tat, so ist es besser, auch einen Ausdruck zu initiieren, und lassen Sie den Konstruktor die buildExpression aufrufen, so dass Sie ziemlich sicher sind, ist dies ein gültiger Ausdruck für Quartz –

+0

@AhmedHashem 'isValidExpression' Methode initiiert bereits intern eine' CronExpression' und fängt jede 'ParseException'. Also sollte es nicht anders sein. – destan

12

ich geändert habe die folgenden code hinzugefügt von @ ph4r05 auch einen regulären Ausdruck zu erzeugen; hier ist die regex:

^\s*($|#|\w+\s*=|(\?|\*|(?:[0-5]?\d)(?:(?:-|\/|\,)(?:[0-5]?\d))?(?:,(?:[0-5]?\d)(?:(?:-|\/|\,)(?:[0-5]?\d))?)*)\s+(\?|\*|(?:[0-5]?\d)(?:(?:-|\/|\,)(?:[0-5]?\d))?(?:,(?:[0-5]?\d)(?:(?:-|\/|\,)(?:[0-5]?\d))?)*)\s+(\?|\*|(?:[01]?\d|2[0-3])(?:(?:-|\/|\,)(?:[01]?\d|2[0-3]))?(?:,(?:[01]?\d|2[0-3])(?:(?:-|\/|\,)(?:[01]?\d|2[0-3]))?)*)\s+(\?|\*|(?:0?[1-9]|[12]\d|3[01])(?:(?:-|\/|\,)(?:0?[1-9]|[12]\d|3[01]))?(?:,(?:0?[1-9]|[12]\d|3[01])(?:(?:-|\/|\,)(?:0?[1-9]|[12]\d|3[01]))?)*)\s+(\?|\*|(?:[1-9]|1[012])(?:(?:-|\/|\,)(?:[1-9]|1[012]))?(?:L|W)?(?:,(?:[1-9]|1[012])(?:(?:-|\/|\,)(?:[1-9]|1[012]))?(?:L|W)?)*|\?|\*|(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(?:(?:-)(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?(?:,(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(?:(?:-)(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?)*)\s+(\?|\*|(?:[0-6])(?:(?:-|\/|\,|#)(?:[0-6]))?(?:L)?(?:,(?:[0-6])(?:(?:-|\/|\,|#)(?:[0-6]))?(?:L)?)*|\?|\*|(?:MON|TUE|WED|THU|FRI|SAT|SUN)(?:(?:-)(?:MON|TUE|WED|THU|FRI|SAT|SUN))?(?:,(?:MON|TUE|WED|THU|FRI|SAT|SUN)(?:(?:-)(?:MON|TUE|WED|THU|FRI|SAT|SUN))?)*)(|\s)+(\?|\*|(?:|\d{4})(?:(?:-|\/|\,)(?:|\d{4}))?(?:,(?:|\d{4})(?:(?:-|\/|\,)(?:|\d{4}))?)*))$ 

Hier ist der Java-Code:

private static String cronRegex = null; 

public static String getCronRegex() 
{ 
    if (cronRegex == null) 
    { 
    // numbers intervals and regex 
    Map<String, String> numbers = new HashMap<String, String>(); 
    numbers.put("sec", "[0-5]?\\d"); 
    numbers.put("min", "[0-5]?\\d"); 
    numbers.put("hour", "[01]?\\d|2[0-3]"); 
    numbers.put("day", "0?[1-9]|[12]\\d|3[01]"); 
    numbers.put("month", "[1-9]|1[012]"); 
    numbers.put("dow", "[0-6]"); 
    numbers.put("year", "|\\d{4}"); 

    Map<String, String> field_re = new HashMap<String, String>(); 

    // expand regex to contain different time specifiers 
    for (String field : numbers.keySet()) 
    { 
     String number = numbers.get(field); 
     String range = "(?:" + number + ")(?:(?:-|\\/|\\," + ("dow".equals(field)? "|#" : "") + 

     ")(?:" + number + "))?" + ("dow".equals(field)? "(?:L)?" : ("month".equals(field)? "(?:L|W)?" : "")); 
     field_re.put(field, "\\?|\\*|" + range + "(?:," + range + ")*"); 
    } 

    // add string specifiers 
    String monthRE = field_re.get("month"); 
    String monthREVal = "JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC"; 
    String monthRERange = "(?:" + monthREVal + ")(?:(?:-)(?:" + monthREVal + "))?" ; 
    monthRE = monthRE + "|\\?|\\*|" + monthRERange + "(?:," + monthRERange + ")*" ; 
    field_re.put("month", monthRE); 

    String dowRE = field_re.get("dow"); 
    String dowREVal = "MON|TUE|WED|THU|FRI|SAT|SUN"; 
    String dowRERange = "(?:" + dowREVal + ")(?:(?:-)(?:" + dowREVal + "))?" ; 

    dowRE = dowRE + "|\\?|\\*|" + dowRERange + "(?:," + dowRERange + ")*" ; 
    field_re.put("dow", dowRE); 

    StringBuilder fieldsReSB = new StringBuilder(); 
    fieldsReSB.append("^\\s*(").append("$") // 
     .append("|#") // 
     .append("|\\w+\\s*=") // 
     .append("|") // 
     .append("(")// 
     .append(field_re.get("sec")).append(")\\s+(")// 
     .append(field_re.get("min")).append(")\\s+(")// 
     .append(field_re.get("hour")).append(")\\s+(")// 
     .append(field_re.get("day")).append(")\\s+(")// 
     .append(field_re.get("month")).append(")\\s+(")// 
     .append(field_re.get("dow")).append(")(|\\s)+(")// 
     .append(field_re.get("year"))// 
     .append(")")// 
     .append(")")// 
     .append("$"); 

    cronRegex = fieldsReSB.toString(); 
    } 
    return cronRegex; 
} 

ich nicht bin, bedeutet einen Regex-Experten, aber zumindest scheint dies auf allen Beispielen durch den Quarz gegeben zu arbeiten documentation

+0

Sehr nett! Dieser ist gültig, funktioniert aber leider nicht: "0 8 9? 1/1 MON # 3 *". Ich schätze, ich muss meinen Regex-Fu auffrischen, um das Ding zu reparieren ... – vincentjames501

-1

Ich fand den folgenden regulären Ausdruck im "QuartzNet" -Projekt auf Github. Ich denke, es könnte sein, was Quartz benutzt, um Cron-Ausdrücke zu validieren.

-Link: https://github.com/quartznet/quartznet/blob/master/src/Quartz/Xml/job_scheduling_data_2_0.xsd

(((([0-9]|[0-5][0-9])(-([0-9]|[0-5][0-9]))?,)*([0-9]|[0-5][0-9])(-([0-9]|[0-5][0-9]))?)|(([\*]|[0-9]|[0-5][0-9])/([0-9]|[0-5][0-9]))|([\?])|([\*]))[\s](((([0-9]|[0-5][0-9])(-([0-9]|[0-5][0-9]))?,)*([0-9]|[0-5][0-9])(-([0-9]|[0-5][0-9]))?)|(([\*]|[0-9]|[0-5][0-9])/([0-9]|[0-5][0-9]))|([\?])|([\*]))[\s](((([0-9]|[0-1][0-9]|[2][0-3])(-([0-9]|[0-1][0-9]|[2][0-3]))?,)*([0-9]|[0-1][0-9]|[2][0-3])(-([0-9]|[0-1][0-9]|[2][0-3]))?)|(([\*]|[0-9]|[0-1][0-9]|[2][0-3])/([0-9]|[0-1][0-9]|[2][0-3]))|([\?])|([\*]))[\s](((([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])(-([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1]))?,)*([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])(-([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1]))?(C)?)|(([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])/([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])(C)?)|(L(-[0-9])?)|(L(-[1-2][0-9])?)|(L(-[3][0-1])?)|(LW)|([1-9]W)|([1-3][0-9]W)|([\?])|([\*]))[\s](((([1-9]|0[1-9]|1[0-2])(-([1-9]|0[1-9]|1[0-2]))?,)*([1-9]|0[1-9]|1[0-2])(-([1-9]|0[1-9]|1[0-2]))?)|(([1-9]|0[1-9]|1[0-2])/([1-9]|0[1-9]|1[0-2]))|(((JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(-(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?,)*(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(-(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?)|((JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)/(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))|([\?])|([\*]))[\s]((([1-7](-([1-7]))?,)*([1-7])(-([1-7]))?)|([1-7]/([1-7]))|(((MON|TUE|WED|THU|FRI|SAT|SUN)(-(MON|TUE|WED|THU|FRI|SAT|SUN))?,)*(MON|TUE|WED|THU|FRI|SAT|SUN)(-(MON|TUE|WED|THU|FRI|SAT|SUN))?(C)?)|((MON|TUE|WED|THU|FRI|SAT|SUN)/(MON|TUE|WED|THU|FRI|SAT|SUN)(C)?)|(([1-7]|(MON|TUE|WED|THU|FRI|SAT|SUN))?(L|LW)?)|(([1-7]|MON|TUE|WED|THU|FRI|SAT|SUN)#([1-7])?)|([\?])|([\*]))([\s]?(([\*])?|(19[7-9][0-9])|(20[0-9][0-9]))?| (((19[7-9][0-9])|(20[0-9][0-9]))/((19[7-9][0-9])|(20[0-9][0-9])))?| ((((19[7-9][0-9])|(20[0-9][0-9]))(-((19[7-9][0-9])|(20[0-9][0-9])))?,)*((19[7-9][0-9])|(20[0-9][0-9]))(-((19[7-9][0-9])|(20[0-9][0-9])))?)?) 
1

könnten Sie verwenden cron-utils Nicht prüfen nur die cron gültig ist, aber Sie aus verschiedenen cron-Formaten auf das Ziel eine (ex umwandeln könnten .: wenn der Benutzer eine Unix-Eingänge Cron-Ausdruck, könnten Sie leicht zu Quartz konvertieren und diesen in DB beibehalten). Im Folgenden stellen wir einige Auszüge:

// Turn cron expressions into another format by using CronMapper: 
CronMapper cronMapper = CronMapper.fromUnixToQuartz(); 

Cron quartzCron = cronMapper.map(unixCron); 
// and to get a String representation of it, we can use 
quartzCron.asString(); 

//validate the cron expression! 
quartzCron.validate() 
Verwandte Themen