Skip to content
This repository has been archived by the owner on May 7, 2020. It is now read-only.

Commit

Permalink
Scheduler : fix #2105 (#2270)
Browse files Browse the repository at this point in the history
Also-by: Markus Rathgeb <maggu2810@gmail.com>
Signed-off-by: Karel Goderis <karel.goderis@me.com>
  • Loading branch information
kgoderis authored and maggu2810 committed Oct 25, 2016
1 parent f052a1a commit d38740c
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import java.util.Calendar;
import java.util.Date;

import org.eclipse.smarthome.core.scheduler.CronExpression;
import org.junit.Test;

public class CronExpressionTest {
Expand Down Expand Up @@ -63,4 +62,22 @@ public void getFinalTimeCheck() throws ParseException {

assertEquals(checkDate, nextDate);
}

@Test
public void runForever() throws ParseException, InterruptedException {

final CronExpression expression;
expression = new CronExpression("* * * * * ?");

Date nextDate = expression.getTimeAfter(Calendar.getInstance().getTime());
int counter = 1;

while (nextDate != null && counter <= 150) {
System.out.println("value " + counter + " is " + nextDate);
nextDate = expression.getTimeAfter(nextDate);
counter++;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public abstract class AbstractExpression<E extends AbstractExpressionPart> imple

private final Logger logger = LoggerFactory.getLogger(this.getClass().getName());

private int minimumCandidates = 10;
private int minimumCandidates = 1;
private int maximumCandidates = 100;

private String expression;
Expand Down Expand Up @@ -207,22 +207,49 @@ protected void prune() {

@Override
public Date getTimeAfter(Date afterTime) {
if (getCandidates().isEmpty()) {

Date currentStartDate = getStartDate();

if (hasFloatingStartDate()) {
try {
clearCandidates();
setStartDate(afterTime);
} catch (IllegalArgumentException | ParseException e) {
logger.error("An exception occurred while setting the start date : '{}'", e.getMessage());
}
} else if (getCandidates().isEmpty()) {
try {
setStartDate(afterTime);
parseExpression(expression);
} catch (ParseException e) {
logger.error("An exception occurred while parsing the expression : '{}'", e.getMessage());
logger.error("An exception occurred while setting the start date : '{}'", e.getMessage());
}
}

if (!getCandidates().isEmpty()) {

Collections.sort(getCandidates());

for (Date candidate : getCandidates()) {
if (candidate.after(afterTime)) {
return candidate;
if (getCandidates().size() == 1) {
return getCandidates().get(0);
} else {
while (getCandidates().size() > 1) {

Collections.sort(getCandidates());

Date newStartDate = null;

try {

for (Date candidate : getCandidates()) {
newStartDate = candidate;
if (candidate.after(afterTime)) {
setStartDate(currentStartDate);
return candidate;
}
}

clearCandidates();
setStartDate(newStartDate);
} catch (IllegalArgumentException | ParseException e) {
logger.error("An exception occurred while parsing the expression : '{}'", e.getMessage());
}
}
}
}
Expand All @@ -232,6 +259,9 @@ public Date getTimeAfter(Date afterTime) {

@Override
public Date getFinalFireTime() {

Date currentStartDate = getStartDate();

if (getCandidates().isEmpty()) {
try {
parseExpression(getExpression());
Expand All @@ -240,11 +270,36 @@ public Date getFinalFireTime() {
}
}

if (getCandidates().isEmpty()) {
return null;
Date lastCandidate = null;

if (!getCandidates().isEmpty()) {
if (getCandidates().size() == 1) {
lastCandidate = getCandidates().get(0);
} else {

while (getCandidates().size() == maximumCandidates) {
Collections.sort(getCandidates());
lastCandidate = getCandidates().get(getCandidates().size() - 1);
try {
clearCandidates();
setStartDate(lastCandidate);
} catch (IllegalArgumentException | ParseException e) {
logger.error("An exception occurred while parsing the expression : '{}'", e.getMessage());
}

}

lastCandidate = getCandidates().get(getCandidates().size() - 1);

try {
setStartDate(currentStartDate);
} catch (IllegalArgumentException | ParseException e) {
logger.error("An exception occurred while setting the start date : '{}'", e.getMessage());
}
}
}

return getCandidates().get(getCandidates().size() - 1);
return lastCandidate;
}

/**
Expand Down Expand Up @@ -275,6 +330,10 @@ protected void setCandidates(ArrayList<Date> candidates) {
this.candidates = candidates;
}

protected void clearCandidates() {
this.candidates = null;
}

public ArrayList<E> getExpressionParts() {
return expressionParts;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public CronExpression(final String expression, final Date startTime) throws Pars
* @throws ParseException if the string expression cannot be parsed into a valid <code>CronExpression</code>.
*/
public CronExpression(final String expression, final Date startTime, final TimeZone zone) throws ParseException {
super(expression, " \t", startTime, zone, 10);
super(expression, " \t", startTime, zone, 0);
}

@Override
Expand Down Expand Up @@ -1193,4 +1193,9 @@ public ArrayList<Date> apply(Date startDate, ArrayList<Date> candidates) {
return candidates;
}
}

@Override
public boolean hasFloatingStartDate() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,9 @@ public int order() {
}
}

@Override
public boolean hasFloatingStartDate() {
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public interface Expression {
/**
* Returns the final time that the <code>Expression</code> will match.
*
* @return the last date the expression will fire
* @return the last date the expression will fire, or null when the final time can not be calculated
*/
Date getFinalFireTime();

Expand Down Expand Up @@ -81,17 +81,25 @@ public interface Expression {
/**
* Returns the start date of the expression.
*
* @return the start date.
* @return the start date, as from which the expression will be evaluated
*/

Date getStartDate();

/**
* Sets the start date of the rule.
* Sets the start date of the rule
*
* @param startTime the start date to set
* @throws ParseException when the expression can not be parsed correctly after the start date was set
*/
void setStartDate(Date startTime) throws ParseException;

/**
* Indicates whether the expression does not need an explicit start date in order to be evaluated. 'infinite' style
* expression types, e.g. without an explicit start date part of their definition, like cron, should return true
*
* @return true, if the start date does not matter for evaluating the expression
*/
boolean hasFloatingStartDate();

}
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@
* arrive at "every other year". Then, "BYMONTH=1" would be applied
* to arrive at "every January, every other year". Then, "BYDAY=SU"
* would be applied to arrive at "every Sunday in January, every
* other year". Then, "BYHOUR=8,9" would be applied to arrive at
* other year". Then, "BYHOUR=8,9" would be applied to arrive at
* "every Sunday in January at 8 AM and 9 AM, every other year".
* Then, "BYMINUTE=30" would be applied to arrive at "every Sunday in
* January at 8:30 AM and 9:30 AM, every other year". Then, lacking
Expand Down Expand Up @@ -551,23 +551,8 @@ public final Date getFinalFireTime() {
if (!(isUntil || isCount)) {
return null;
} else {

if (getCandidates().isEmpty()) {
try {
parseExpression(getExpression());
} catch (ParseException e) {
logger.error("An exception occurred while parsing the expression : '{}'", e.getMessage());
}
}

if (!getCandidates().isEmpty()) {

Collections.sort(getCandidates());

return getCandidates().get(getCandidates().size() - 1);
}
return super.getFinalFireTime();
}
return null;
}

@Override
Expand Down Expand Up @@ -1847,4 +1832,9 @@ public int order() {
}
}

@Override
public boolean hasFloatingStartDate() {
return false;
}

}

0 comments on commit d38740c

Please sign in to comment.