-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #43487 from mkouba/issue-25855
Scheduler: introduce a shared CronParser util class
- Loading branch information
Showing
4 changed files
with
158 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
...nsions/scheduler/common/src/main/java/io/quarkus/scheduler/common/runtime/CronParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package io.quarkus.scheduler.common.runtime; | ||
|
||
import static com.cronutils.model.field.expression.FieldExpression.questionMark; | ||
|
||
import java.util.ArrayList; | ||
import java.util.EnumMap; | ||
import java.util.Map; | ||
|
||
import com.cronutils.Function; | ||
import com.cronutils.mapper.CronMapper; | ||
import com.cronutils.model.Cron; | ||
import com.cronutils.model.CronType; | ||
import com.cronutils.model.SingleCron; | ||
import com.cronutils.model.definition.CronDefinitionBuilder; | ||
import com.cronutils.model.field.CronField; | ||
import com.cronutils.model.field.CronFieldName; | ||
import com.cronutils.model.field.expression.Always; | ||
import com.cronutils.model.field.expression.QuestionMark; | ||
|
||
public class CronParser { | ||
|
||
private final CronType cronType; | ||
|
||
private final com.cronutils.parser.CronParser cronParser; | ||
|
||
public CronParser(CronType cronType) { | ||
this.cronType = cronType; | ||
this.cronParser = new com.cronutils.parser.CronParser(CronDefinitionBuilder.instanceDefinitionFor(cronType)); | ||
} | ||
|
||
public CronType cronType() { | ||
return cronType; | ||
} | ||
|
||
public Cron parse(String value) { | ||
return cronParser.parse(value); | ||
} | ||
|
||
public Cron mapToQuartz(Cron cron) { | ||
switch (cronType) { | ||
case QUARTZ: | ||
return cron; | ||
case UNIX: | ||
return CronMapper.fromUnixToQuartz().map(cron); | ||
case CRON4J: | ||
return CronMapper.fromCron4jToQuartz().map(cron); | ||
case SPRING: | ||
return CronMapper.fromSpringToQuartz().map(cron); | ||
case SPRING53: | ||
// https://github.com/jmrozanec/cron-utils/issues/579 | ||
return new CronMapper( | ||
CronDefinitionBuilder.instanceDefinitionFor(CronType.SPRING53), | ||
CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ), | ||
setQuestionMark()).map(cron); | ||
default: | ||
throw new IllegalStateException("Unsupported cron type: " + cronType); | ||
} | ||
} | ||
|
||
// Copy from com.cronutils.mapper.CronMapper#setQuestionMark() | ||
private static Function<Cron, Cron> setQuestionMark() { | ||
return cron -> { | ||
final CronField dow = cron.retrieve(CronFieldName.DAY_OF_WEEK); | ||
final CronField dom = cron.retrieve(CronFieldName.DAY_OF_MONTH); | ||
if (dow == null && dom == null) { | ||
return cron; | ||
} | ||
if (dow.getExpression() instanceof QuestionMark || dom.getExpression() instanceof QuestionMark) { | ||
return cron; | ||
} | ||
final Map<CronFieldName, CronField> fields = new EnumMap<>(CronFieldName.class); | ||
fields.putAll(cron.retrieveFieldsAsMap()); | ||
if (dow.getExpression() instanceof Always) { | ||
fields.put(CronFieldName.DAY_OF_WEEK, | ||
new CronField(CronFieldName.DAY_OF_WEEK, questionMark(), | ||
fields.get(CronFieldName.DAY_OF_WEEK).getConstraints())); | ||
} else { | ||
if (dom.getExpression() instanceof Always) { | ||
fields.put(CronFieldName.DAY_OF_MONTH, | ||
new CronField(CronFieldName.DAY_OF_MONTH, questionMark(), | ||
fields.get(CronFieldName.DAY_OF_MONTH).getConstraints())); | ||
} else { | ||
cron.validate(); | ||
} | ||
} | ||
return new SingleCron(cron.getCronDefinition(), new ArrayList<>(fields.values())); | ||
}; | ||
} | ||
|
||
} |
52 changes: 52 additions & 0 deletions
52
...ns/scheduler/common/src/test/java/io/quarkus/scheduler/common/runtime/CronParserTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package io.quarkus.scheduler.common.runtime; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertSame; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import com.cronutils.model.Cron; | ||
import com.cronutils.model.CronType; | ||
|
||
public class CronParserTest { | ||
|
||
@Test | ||
public void testMapUnixToQuartz() { | ||
CronParser parser = new CronParser(CronType.UNIX); | ||
Cron cron = parser.parse("10 14 * * 1"); | ||
Cron quartz = parser.mapToQuartz(cron); | ||
assertEquals("0 10 14 ? * 2 *", quartz.asString()); | ||
} | ||
|
||
@Test | ||
public void testMapQuartzToQuartz() { | ||
CronParser parser = new CronParser(CronType.QUARTZ); | ||
Cron cron = parser.parse("0 10 14 ? * 2 *"); | ||
assertSame(cron, parser.mapToQuartz(cron)); | ||
} | ||
|
||
@Test | ||
public void testMapCron4jToQuartz() { | ||
CronParser parser = new CronParser(CronType.CRON4J); | ||
Cron cron = parser.parse("10 14 L * *"); | ||
Cron quartz = parser.mapToQuartz(cron); | ||
assertEquals("0 10 14 L * ? *", quartz.asString()); | ||
} | ||
|
||
@Test | ||
public void testMapSpringToQuartz() { | ||
CronParser parser = new CronParser(CronType.SPRING); | ||
Cron cron = parser.parse("1 10 14 * * 0"); | ||
Cron quartz = parser.mapToQuartz(cron); | ||
assertEquals("1 10 14 ? * 1 *", quartz.asString()); | ||
} | ||
|
||
@Test | ||
public void testMapSpring53ToQuartz() { | ||
CronParser parser = new CronParser(CronType.SPRING53); | ||
Cron cron = parser.parse("1 10 14 L * *"); | ||
Cron quartz = parser.mapToQuartz(cron); | ||
assertEquals("1 10 14 L * ? *", quartz.asString()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters