refs #200: Create accouting-lib library
https://support.d4science.org/issues/200 Remove classes due to license incompatibility git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/vre-management/smart-executor-api@115472 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
2a00685ae2
commit
6dbb7a7da0
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* This class was originally part of:
|
||||
*
|
||||
* cron4j - A pure Java cron-like scheduler
|
||||
*
|
||||
* Copyright (C) 2007-2010 Carlo Pelliccia (www.sauronsoftware.it)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version
|
||||
* 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License 2.1 for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License version 2.1 along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.gcube.vremanagement.executor.api.scheduling;
|
||||
|
||||
/**
|
||||
* This ValueMatcher always returns true!
|
||||
*
|
||||
* @author Carlo Pelliccia
|
||||
*/
|
||||
class AlwaysTrueValueMatcher implements ValueMatcher {
|
||||
|
||||
/**
|
||||
* Always true!
|
||||
*/
|
||||
public boolean match(int value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* This class was originally part of:
|
||||
*
|
||||
* cron4j - A pure Java cron-like scheduler
|
||||
*
|
||||
* Copyright (C) 2007-2010 Carlo Pelliccia (www.sauronsoftware.it)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version
|
||||
* 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License 2.1 for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License version 2.1 along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.gcube.vremanagement.executor.api.scheduling;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A ValueMatcher whose rules are in a plain array of integer values. When asked
|
||||
* to validate a value, this ValueMatcher checks if it is in the array and, if
|
||||
* not, checks whether the last-day-of-month setting applies.
|
||||
* </p>
|
||||
*
|
||||
* @author Paul Fernley
|
||||
*/
|
||||
class DayOfMonthValueMatcher extends IntArrayValueMatcher {
|
||||
|
||||
private static final int[] lastDays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
/**
|
||||
* Builds the ValueMatcher.
|
||||
*
|
||||
* @param integers
|
||||
* An ArrayList of Integer elements, one for every value accepted
|
||||
* by the matcher. The match() method will return true only if
|
||||
* its parameter will be one of this list or the
|
||||
* last-day-of-month setting applies.
|
||||
*/
|
||||
public DayOfMonthValueMatcher(ArrayList integers) {
|
||||
super(integers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given value is included in the matcher list or the
|
||||
* last-day-of-month setting applies.
|
||||
*/
|
||||
public boolean match(int value, int month, boolean isLeapYear) {
|
||||
return (super.match(value) || (value > 27 && match(32) && isLastDayOfMonth(value, month, isLeapYear)));
|
||||
}
|
||||
|
||||
public boolean isLastDayOfMonth(int value, int month, boolean isLeapYear) {
|
||||
if (isLeapYear && month == 2) {
|
||||
return value == 29;
|
||||
} else {
|
||||
return value == lastDays[month - 1];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
* This class was originally part of:
|
||||
*
|
||||
* cron4j - A pure Java cron-like scheduler
|
||||
*
|
||||
* Copyright (C) 2007-2010 Carlo Pelliccia (www.sauronsoftware.it)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version
|
||||
* 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License 2.1 for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License version 2.1 along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.gcube.vremanagement.executor.api.scheduling;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A ValueMatcher whose rules are in a plain array of integer values. When asked
|
||||
* to validate a value, this ValueMatcher checks if it is in the array.
|
||||
* </p>
|
||||
*
|
||||
* @author Carlo Pelliccia
|
||||
*/
|
||||
class IntArrayValueMatcher implements ValueMatcher {
|
||||
|
||||
/**
|
||||
* The accepted values.
|
||||
*/
|
||||
private int[] values;
|
||||
|
||||
/**
|
||||
* Builds the ValueMatcher.
|
||||
*
|
||||
* @param integers
|
||||
* An ArrayList of Integer elements, one for every value accepted
|
||||
* by the matcher. The match() method will return true only if
|
||||
* its parameter will be one of this list.
|
||||
*/
|
||||
public IntArrayValueMatcher(ArrayList integers) {
|
||||
int size = integers.size();
|
||||
values = new int[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
try {
|
||||
values[i] = ((Integer) integers.get(i)).intValue();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given value is included in the matcher list.
|
||||
*/
|
||||
public boolean match(int value) {
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
if (values[i] == value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* This class was originally part of:
|
||||
*
|
||||
* cron4j - A pure Java cron-like scheduler
|
||||
*
|
||||
* Copyright (C) 2007-2010 Carlo Pelliccia (www.sauronsoftware.it)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version
|
||||
* 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License 2.1 for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License version 2.1 along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.gcube.vremanagement.executor.api.scheduling;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This kind of exception is thrown if an invalid scheduling pattern is
|
||||
* encountered by the scheduler.
|
||||
* </p>
|
||||
*
|
||||
* @author Carlo Pelliccia
|
||||
*/
|
||||
public class InvalidPatternException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Package-reserved construction.
|
||||
*/
|
||||
InvalidPatternException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Package-reserved construction.
|
||||
*/
|
||||
InvalidPatternException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,739 +0,0 @@
|
|||
/*
|
||||
* This class was originally part of:
|
||||
*
|
||||
* cron4j - A pure Java cron-like scheduler
|
||||
*
|
||||
* Copyright (C) 2007-2010 Carlo Pelliccia (www.sauronsoftware.it)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version
|
||||
* 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License 2.1 for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License version 2.1 along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.gcube.vremanagement.executor.api.scheduling;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Iterator;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A UNIX crontab-like pattern is a string split in five space separated parts.
|
||||
* Each part is intented as:
|
||||
* </p>
|
||||
* <ol>
|
||||
* <li><strong>Minutes sub-pattern</strong>. During which minutes of the hour
|
||||
* should the task been launched? The values range is from 0 to 59.</li>
|
||||
* <li><strong>Hours sub-pattern</strong>. During which hours of the day should
|
||||
* the task been launched? The values range is from 0 to 23.</li>
|
||||
* <li><strong>Days of month sub-pattern</strong>. During which days of the
|
||||
* month should the task been launched? The values range is from 1 to 31. The
|
||||
* special value L can be used to recognize the last day of month.</li>
|
||||
* <li><strong>Months sub-pattern</strong>. During which months of the year
|
||||
* should the task been launched? The values range is from 1 (January) to 12
|
||||
* (December), otherwise this sub-pattern allows the aliases "jan",
|
||||
* "feb", "mar", "apr", "may",
|
||||
* "jun", "jul", "aug", "sep",
|
||||
* "oct", "nov" and "dec".</li>
|
||||
* <li><strong>Days of week sub-pattern</strong>. During which days of the week
|
||||
* should the task been launched? The values range is from 0 (Sunday) to 6
|
||||
* (Saturday), otherwise this sub-pattern allows the aliases "sun",
|
||||
* "mon", "tue", "wed", "thu",
|
||||
* "fri" and "sat".</li>
|
||||
* </ol>
|
||||
* <p>
|
||||
* The star wildcard character is also admitted, indicating "every minute
|
||||
* of the hour", "every hour of the day", "every day of the
|
||||
* month", "every month of the year" and "every day of the
|
||||
* week", according to the sub-pattern in which it is used.
|
||||
* </p>
|
||||
* <p>
|
||||
* Once the scheduler is started, a task will be launched when the five parts in
|
||||
* its scheduling pattern will be true at the same time.
|
||||
* </p>
|
||||
* <p>
|
||||
* Some examples:
|
||||
* </p>
|
||||
* <p>
|
||||
* <strong>5 * * * *</strong><br />
|
||||
* This pattern causes a task to be launched once every hour, at the begin of
|
||||
* the fifth minute (00:05, 01:05, 02:05 etc.).
|
||||
* </p>
|
||||
* <p>
|
||||
* <strong>* * * * *</strong><br />
|
||||
* This pattern causes a task to be launched every minute.
|
||||
* </p>
|
||||
* <p>
|
||||
* <strong>* 12 * * Mon</strong><br />
|
||||
* This pattern causes a task to be launched every minute during the 12th hour
|
||||
* of Monday.
|
||||
* </p>
|
||||
* <p>
|
||||
* <strong>* 12 16 * Mon</strong><br />
|
||||
* This pattern causes a task to be launched every minute during the 12th hour
|
||||
* of Monday, 16th, but only if the day is the 16th of the month.
|
||||
* </p>
|
||||
* <p>
|
||||
* Every sub-pattern can contain two or more comma separated values.
|
||||
* </p>
|
||||
* <p>
|
||||
* <strong>59 11 * * 1,2,3,4,5</strong><br />
|
||||
* This pattern causes a task to be launched at 11:59AM on Monday, Tuesday,
|
||||
* Wednesday, Thursday and Friday.
|
||||
* </p>
|
||||
* <p>
|
||||
* Values intervals are admitted and defined using the minus character.
|
||||
* </p>
|
||||
* <p>
|
||||
* <strong>59 11 * * 1-5</strong><br />
|
||||
* This pattern is equivalent to the previous one.
|
||||
* </p>
|
||||
* <p>
|
||||
* The slash character can be used to identify step values within a range. It
|
||||
* can be used both in the form <em>*/c</em> and <em>a-b/c</em>. The
|
||||
* subpattern is matched every <em>c</em> values of the range
|
||||
* <em>0,maxvalue</em> or <em>a-b</em>.
|
||||
* </p>
|
||||
* <p>
|
||||
* <strong>*/5 * * * *</strong><br />
|
||||
* This pattern causes a task to be launched every 5 minutes (0:00, 0:05, 0:10,
|
||||
* 0:15 and so on).
|
||||
* </p>
|
||||
* <p>
|
||||
* <strong>3-18/5 * * * *</strong><br />
|
||||
* This pattern causes a task to be launched every 5 minutes starting from the
|
||||
* third minute of the hour, up to the 18th (0:03, 0:08, 0:13, 0:18, 1:03, 1:08
|
||||
* and so on).
|
||||
* </p>
|
||||
* <p>
|
||||
* <strong>*/15 9-17 * * *</strong><br />
|
||||
* This pattern causes a task to be launched every 15 minutes between the 9th
|
||||
* and 17th hour of the day (9:00, 9:15, 9:30, 9:45 and so on... note that the
|
||||
* last execution will be at 17:45).
|
||||
* </p>
|
||||
* <p>
|
||||
* All the fresh described syntax rules can be used together.
|
||||
* </p>
|
||||
* <p>
|
||||
* <strong>* 12 10-16/2 * *</strong><br />
|
||||
* This pattern causes a task to be launched every minute during the 12th hour
|
||||
* of the day, but only if the day is the 10th, the 12th, the 14th or the 16th
|
||||
* of the month.
|
||||
* </p>
|
||||
* <p>
|
||||
* <strong>* 12 1-15,17,20-25 * *</strong><br />
|
||||
* This pattern causes a task to be launched every minute during the 12th hour
|
||||
* of the day, but the day of the month must be between the 1st and the 15th,
|
||||
* the 20th and the 25, or at least it must be the 17th.
|
||||
* </p>
|
||||
* <p>
|
||||
* Finally cron4j lets you combine more scheduling patterns into one, with the
|
||||
* pipe character:
|
||||
* </p>
|
||||
* <p>
|
||||
* <strong>0 5 * * *|8 10 * * *|22 17 * * *</strong><br />
|
||||
* This pattern causes a task to be launched every day at 05:00, 10:08 and
|
||||
* 17:22.
|
||||
* </p>
|
||||
*
|
||||
* @author Carlo Pelliccia
|
||||
* @since 2.0
|
||||
*/
|
||||
public class SchedulingPattern {
|
||||
|
||||
/**
|
||||
* The parser for the minute values.
|
||||
*/
|
||||
private static final ValueParser MINUTE_VALUE_PARSER = new MinuteValueParser();
|
||||
|
||||
/**
|
||||
* The parser for the hour values.
|
||||
*/
|
||||
private static final ValueParser HOUR_VALUE_PARSER = new HourValueParser();
|
||||
|
||||
/**
|
||||
* The parser for the day of month values.
|
||||
*/
|
||||
private static final ValueParser DAY_OF_MONTH_VALUE_PARSER = new DayOfMonthValueParser();
|
||||
|
||||
/**
|
||||
* The parser for the month values.
|
||||
*/
|
||||
private static final ValueParser MONTH_VALUE_PARSER = new MonthValueParser();
|
||||
|
||||
/**
|
||||
* The parser for the day of week values.
|
||||
*/
|
||||
private static final ValueParser DAY_OF_WEEK_VALUE_PARSER = new DayOfWeekValueParser();
|
||||
|
||||
/**
|
||||
* Validates a string as a scheduling pattern.
|
||||
*
|
||||
* @param schedulingPattern
|
||||
* The pattern to validate.
|
||||
* @return true if the given string represents a valid scheduling pattern;
|
||||
* false otherwise.
|
||||
*/
|
||||
public static boolean validate(String schedulingPattern) {
|
||||
try {
|
||||
new SchedulingPattern(schedulingPattern);
|
||||
} catch (InvalidPatternException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The pattern as a string.
|
||||
*/
|
||||
private String asString;
|
||||
|
||||
/**
|
||||
* The ValueMatcher list for the "minute" field.
|
||||
*/
|
||||
protected ArrayList minuteMatchers = new ArrayList();
|
||||
|
||||
/**
|
||||
* The ValueMatcher list for the "hour" field.
|
||||
*/
|
||||
protected ArrayList hourMatchers = new ArrayList();
|
||||
|
||||
/**
|
||||
* The ValueMatcher list for the "day of month" field.
|
||||
*/
|
||||
protected ArrayList dayOfMonthMatchers = new ArrayList();
|
||||
|
||||
/**
|
||||
* The ValueMatcher list for the "month" field.
|
||||
*/
|
||||
protected ArrayList monthMatchers = new ArrayList();
|
||||
|
||||
/**
|
||||
* The ValueMatcher list for the "day of week" field.
|
||||
*/
|
||||
protected ArrayList dayOfWeekMatchers = new ArrayList();
|
||||
|
||||
/**
|
||||
* How many matcher groups in this pattern?
|
||||
*/
|
||||
protected int matcherSize = 0;
|
||||
|
||||
/**
|
||||
* Builds a SchedulingPattern parsing it from a string.
|
||||
*
|
||||
* @param pattern
|
||||
* The pattern as a crontab-like string.
|
||||
* @throws InvalidPatternException
|
||||
* If the supplied string is not a valid pattern.
|
||||
*/
|
||||
public SchedulingPattern(String pattern) throws InvalidPatternException {
|
||||
this.asString = pattern;
|
||||
StringTokenizer st1 = new StringTokenizer(pattern, "|");
|
||||
if (st1.countTokens() < 1) {
|
||||
throw new InvalidPatternException("invalid pattern: \"" + pattern + "\"");
|
||||
}
|
||||
while (st1.hasMoreTokens()) {
|
||||
String localPattern = st1.nextToken();
|
||||
StringTokenizer st2 = new StringTokenizer(localPattern, " \t");
|
||||
if (st2.countTokens() != 5) {
|
||||
throw new InvalidPatternException("invalid pattern: \"" + localPattern + "\"");
|
||||
}
|
||||
try {
|
||||
minuteMatchers.add(buildValueMatcher(st2.nextToken(), MINUTE_VALUE_PARSER));
|
||||
} catch (Exception e) {
|
||||
throw new InvalidPatternException("invalid pattern \""
|
||||
+ localPattern + "\". Error parsing minutes field: "
|
||||
+ e.getMessage() + ".");
|
||||
}
|
||||
try {
|
||||
hourMatchers.add(buildValueMatcher(st2.nextToken(), HOUR_VALUE_PARSER));
|
||||
} catch (Exception e) {
|
||||
throw new InvalidPatternException("invalid pattern \""
|
||||
+ localPattern + "\". Error parsing hours field: "
|
||||
+ e.getMessage() + ".");
|
||||
}
|
||||
try {
|
||||
dayOfMonthMatchers.add(buildValueMatcher(st2.nextToken(), DAY_OF_MONTH_VALUE_PARSER));
|
||||
} catch (Exception e) {
|
||||
throw new InvalidPatternException("invalid pattern \""
|
||||
+ localPattern
|
||||
+ "\". Error parsing days of month field: "
|
||||
+ e.getMessage() + ".");
|
||||
}
|
||||
try {
|
||||
monthMatchers.add(buildValueMatcher(st2.nextToken(), MONTH_VALUE_PARSER));
|
||||
} catch (Exception e) {
|
||||
throw new InvalidPatternException("invalid pattern \""
|
||||
+ localPattern + "\". Error parsing months field: "
|
||||
+ e.getMessage() + ".");
|
||||
}
|
||||
try {
|
||||
dayOfWeekMatchers.add(buildValueMatcher(st2.nextToken(), DAY_OF_WEEK_VALUE_PARSER));
|
||||
} catch (Exception e) {
|
||||
throw new InvalidPatternException("invalid pattern \""
|
||||
+ localPattern
|
||||
+ "\". Error parsing days of week field: "
|
||||
+ e.getMessage() + ".");
|
||||
}
|
||||
matcherSize++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A ValueMatcher utility builder.
|
||||
*
|
||||
* @param str
|
||||
* The pattern part for the ValueMatcher creation.
|
||||
* @param parser
|
||||
* The parser used to parse the values.
|
||||
* @return The requested ValueMatcher.
|
||||
* @throws Exception
|
||||
* If the supplied pattern part is not valid.
|
||||
*/
|
||||
private ValueMatcher buildValueMatcher(String str, ValueParser parser)
|
||||
throws Exception {
|
||||
if (str.length() == 1 && str.equals("*")) {
|
||||
return new AlwaysTrueValueMatcher();
|
||||
}
|
||||
ArrayList values = new ArrayList();
|
||||
StringTokenizer st = new StringTokenizer(str, ",");
|
||||
while (st.hasMoreTokens()) {
|
||||
String element = st.nextToken();
|
||||
ArrayList local;
|
||||
try {
|
||||
local = parseListElement(element, parser);
|
||||
} catch (Exception e) {
|
||||
throw new Exception("invalid field \"" + str
|
||||
+ "\", invalid element \"" + element + "\", "
|
||||
+ e.getMessage());
|
||||
}
|
||||
for (Iterator i = local.iterator(); i.hasNext();) {
|
||||
Object value = i.next();
|
||||
if (!values.contains(value)) {
|
||||
values.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (values.size() == 0) {
|
||||
throw new Exception("invalid field \"" + str + "\"");
|
||||
}
|
||||
if (parser == DAY_OF_MONTH_VALUE_PARSER) {
|
||||
return new DayOfMonthValueMatcher(values);
|
||||
} else {
|
||||
return new IntArrayValueMatcher(values);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an element of a list of values of the pattern.
|
||||
*
|
||||
* @param str
|
||||
* The element string.
|
||||
* @param parser
|
||||
* The parser used to parse the values.
|
||||
* @return A list of integers representing the allowed values.
|
||||
* @throws Exception
|
||||
* If the supplied pattern part is not valid.
|
||||
*/
|
||||
private ArrayList parseListElement(String str, ValueParser parser)
|
||||
throws Exception {
|
||||
StringTokenizer st = new StringTokenizer(str, "/");
|
||||
int size = st.countTokens();
|
||||
if (size < 1 || size > 2) {
|
||||
throw new Exception("syntax error");
|
||||
}
|
||||
ArrayList values;
|
||||
try {
|
||||
values = parseRange(st.nextToken(), parser);
|
||||
} catch (Exception e) {
|
||||
throw new Exception("invalid range, " + e.getMessage());
|
||||
}
|
||||
if (size == 2) {
|
||||
String dStr = st.nextToken();
|
||||
int div;
|
||||
try {
|
||||
div = Integer.parseInt(dStr);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new Exception("invalid divisor \"" + dStr + "\"");
|
||||
}
|
||||
if (div < 1) {
|
||||
throw new Exception("non positive divisor \"" + div + "\"");
|
||||
}
|
||||
ArrayList values2 = new ArrayList();
|
||||
for (int i = 0; i < values.size(); i += div) {
|
||||
values2.add(values.get(i));
|
||||
}
|
||||
return values2;
|
||||
} else {
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a range of values.
|
||||
*
|
||||
* @param str
|
||||
* The range string.
|
||||
* @param parser
|
||||
* The parser used to parse the values.
|
||||
* @return A list of integers representing the allowed values.
|
||||
* @throws Exception
|
||||
* If the supplied pattern part is not valid.
|
||||
*/
|
||||
private ArrayList parseRange(String str, ValueParser parser)
|
||||
throws Exception {
|
||||
if (str.equals("*")) {
|
||||
int min = parser.getMinValue();
|
||||
int max = parser.getMaxValue();
|
||||
ArrayList values = new ArrayList();
|
||||
for (int i = min; i <= max; i++) {
|
||||
values.add(new Integer(i));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
StringTokenizer st = new StringTokenizer(str, "-");
|
||||
int size = st.countTokens();
|
||||
if (size < 1 || size > 2) {
|
||||
throw new Exception("syntax error");
|
||||
}
|
||||
String v1Str = st.nextToken();
|
||||
int v1;
|
||||
try {
|
||||
v1 = parser.parse(v1Str);
|
||||
} catch (Exception e) {
|
||||
throw new Exception("invalid value \"" + v1Str + "\", "
|
||||
+ e.getMessage());
|
||||
}
|
||||
if (size == 1) {
|
||||
ArrayList values = new ArrayList();
|
||||
values.add(new Integer(v1));
|
||||
return values;
|
||||
} else {
|
||||
String v2Str = st.nextToken();
|
||||
int v2;
|
||||
try {
|
||||
v2 = parser.parse(v2Str);
|
||||
} catch (Exception e) {
|
||||
throw new Exception("invalid value \"" + v2Str + "\", "
|
||||
+ e.getMessage());
|
||||
}
|
||||
ArrayList values = new ArrayList();
|
||||
if (v1 < v2) {
|
||||
for (int i = v1; i <= v2; i++) {
|
||||
values.add(new Integer(i));
|
||||
}
|
||||
} else if (v1 > v2) {
|
||||
int min = parser.getMinValue();
|
||||
int max = parser.getMaxValue();
|
||||
for (int i = v1; i <= max; i++) {
|
||||
values.add(new Integer(i));
|
||||
}
|
||||
for (int i = min; i <= v2; i++) {
|
||||
values.add(new Integer(i));
|
||||
}
|
||||
} else {
|
||||
// v1 == v2
|
||||
values.add(new Integer(v1));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This methods returns true if the given timestamp (expressed as a UNIX-era
|
||||
* millis value) matches the pattern, according to the given time zone.
|
||||
*
|
||||
* @param timezone
|
||||
* A time zone.
|
||||
* @param millis
|
||||
* The timestamp, as a UNIX-era millis value.
|
||||
* @return true if the given timestamp matches the pattern.
|
||||
*/
|
||||
public boolean match(TimeZone timezone, long millis) {
|
||||
GregorianCalendar gc = new GregorianCalendar();
|
||||
gc.setTimeInMillis(millis);
|
||||
gc.setTimeZone(timezone);
|
||||
int minute = gc.get(Calendar.MINUTE);
|
||||
int hour = gc.get(Calendar.HOUR_OF_DAY);
|
||||
int dayOfMonth = gc.get(Calendar.DAY_OF_MONTH);
|
||||
int month = gc.get(Calendar.MONTH) + 1;
|
||||
int dayOfWeek = gc.get(Calendar.DAY_OF_WEEK) - 1;
|
||||
int year = gc.get(Calendar.YEAR);
|
||||
for (int i = 0; i < matcherSize; i++) {
|
||||
ValueMatcher minuteMatcher = (ValueMatcher) minuteMatchers.get(i);
|
||||
ValueMatcher hourMatcher = (ValueMatcher) hourMatchers.get(i);
|
||||
ValueMatcher dayOfMonthMatcher = (ValueMatcher) dayOfMonthMatchers.get(i);
|
||||
ValueMatcher monthMatcher = (ValueMatcher) monthMatchers.get(i);
|
||||
ValueMatcher dayOfWeekMatcher = (ValueMatcher) dayOfWeekMatchers.get(i);
|
||||
boolean eval = minuteMatcher.match(minute)
|
||||
&& hourMatcher.match(hour)
|
||||
&& ((dayOfMonthMatcher instanceof DayOfMonthValueMatcher) ? ((DayOfMonthValueMatcher) dayOfMonthMatcher)
|
||||
.match(dayOfMonth, month, gc.isLeapYear(year))
|
||||
: dayOfMonthMatcher.match(dayOfMonth))
|
||||
&& monthMatcher.match(month)
|
||||
&& dayOfWeekMatcher.match(dayOfWeek);
|
||||
if (eval) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This methods returns true if the given timestamp (expressed as a UNIX-era
|
||||
* millis value) matches the pattern, according to the system default time
|
||||
* zone.
|
||||
*
|
||||
* @param millis
|
||||
* The timestamp, as a UNIX-era millis value.
|
||||
* @return true if the given timestamp matches the pattern.
|
||||
*/
|
||||
public boolean match(long millis) {
|
||||
return match(TimeZone.getDefault(), millis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pattern as a string.
|
||||
*
|
||||
* @return The pattern as a string.
|
||||
*/
|
||||
public String toString() {
|
||||
return asString;
|
||||
}
|
||||
|
||||
/**
|
||||
* This utility method changes an alias to an int value.
|
||||
*
|
||||
* @param value
|
||||
* The value.
|
||||
* @param aliases
|
||||
* The aliases list.
|
||||
* @param offset
|
||||
* The offset appplied to the aliases list indices.
|
||||
* @return The parsed value.
|
||||
* @throws Exception
|
||||
* If the expressed values doesn't match any alias.
|
||||
*/
|
||||
private static int parseAlias(String value, String[] aliases, int offset)
|
||||
throws Exception {
|
||||
for (int i = 0; i < aliases.length; i++) {
|
||||
if (aliases[i].equalsIgnoreCase(value)) {
|
||||
return offset + i;
|
||||
}
|
||||
}
|
||||
throw new Exception("invalid alias \"" + value + "\"");
|
||||
}
|
||||
|
||||
/**
|
||||
* Definition for a value parser.
|
||||
*/
|
||||
private static interface ValueParser {
|
||||
|
||||
/**
|
||||
* Attempts to parse a value.
|
||||
*
|
||||
* @param value
|
||||
* The value.
|
||||
* @return The parsed value.
|
||||
* @throws Exception
|
||||
* If the value can't be parsed.
|
||||
*/
|
||||
public int parse(String value) throws Exception;
|
||||
|
||||
/**
|
||||
* Returns the minimum value accepred by the parser.
|
||||
*
|
||||
* @return The minimum value accepred by the parser.
|
||||
*/
|
||||
public int getMinValue();
|
||||
|
||||
/**
|
||||
* Returns the maximum value accepred by the parser.
|
||||
*
|
||||
* @return The maximum value accepred by the parser.
|
||||
*/
|
||||
public int getMaxValue();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple value parser.
|
||||
*/
|
||||
private static class SimpleValueParser implements ValueParser {
|
||||
|
||||
/**
|
||||
* The minimum allowed value.
|
||||
*/
|
||||
protected int minValue;
|
||||
|
||||
/**
|
||||
* The maximum allowed value.
|
||||
*/
|
||||
protected int maxValue;
|
||||
|
||||
/**
|
||||
* Builds the value parser.
|
||||
*
|
||||
* @param minValue
|
||||
* The minimum allowed value.
|
||||
* @param maxValue
|
||||
* The maximum allowed value.
|
||||
*/
|
||||
public SimpleValueParser(int minValue, int maxValue) {
|
||||
this.minValue = minValue;
|
||||
this.maxValue = maxValue;
|
||||
}
|
||||
|
||||
public int parse(String value) throws Exception {
|
||||
int i;
|
||||
try {
|
||||
i = Integer.parseInt(value);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new Exception("invalid integer value");
|
||||
}
|
||||
if (i < minValue || i > maxValue) {
|
||||
throw new Exception("value out of range");
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
public int getMinValue() {
|
||||
return minValue;
|
||||
}
|
||||
|
||||
public int getMaxValue() {
|
||||
return maxValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The minutes value parser.
|
||||
*/
|
||||
private static class MinuteValueParser extends SimpleValueParser {
|
||||
|
||||
/**
|
||||
* Builds the value parser.
|
||||
*/
|
||||
public MinuteValueParser() {
|
||||
super(0, 59);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The hours value parser.
|
||||
*/
|
||||
private static class HourValueParser extends SimpleValueParser {
|
||||
|
||||
/**
|
||||
* Builds the value parser.
|
||||
*/
|
||||
public HourValueParser() {
|
||||
super(0, 23);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The days of month value parser.
|
||||
*/
|
||||
private static class DayOfMonthValueParser extends SimpleValueParser {
|
||||
|
||||
/**
|
||||
* Builds the value parser.
|
||||
*/
|
||||
public DayOfMonthValueParser() {
|
||||
super(1, 31);
|
||||
}
|
||||
|
||||
/**
|
||||
* Added to support last-day-of-month.
|
||||
*
|
||||
* @param value
|
||||
* The value to be parsed
|
||||
* @return the integer day of the month or 32 for last day of the month
|
||||
* @throws Exception
|
||||
* if the input value is invalid
|
||||
*/
|
||||
public int parse(String value) throws Exception {
|
||||
if (value.equalsIgnoreCase("L")) {
|
||||
return 32;
|
||||
} else {
|
||||
return super.parse(value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The value parser for the months field.
|
||||
*/
|
||||
private static class MonthValueParser extends SimpleValueParser {
|
||||
|
||||
/**
|
||||
* Months aliases.
|
||||
*/
|
||||
private static String[] ALIASES = { "jan", "feb", "mar", "apr", "may",
|
||||
"jun", "jul", "aug", "sep", "oct", "nov", "dec" };
|
||||
|
||||
/**
|
||||
* Builds the months value parser.
|
||||
*/
|
||||
public MonthValueParser() {
|
||||
super(1, 12);
|
||||
}
|
||||
|
||||
public int parse(String value) throws Exception {
|
||||
try {
|
||||
// try as a simple value
|
||||
return super.parse(value);
|
||||
} catch (Exception e) {
|
||||
// try as an alias
|
||||
return parseAlias(value, ALIASES, 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The value parser for the months field.
|
||||
*/
|
||||
private static class DayOfWeekValueParser extends SimpleValueParser {
|
||||
|
||||
/**
|
||||
* Days of week aliases.
|
||||
*/
|
||||
private static String[] ALIASES = { "sun", "mon", "tue", "wed", "thu", "fri", "sat" };
|
||||
|
||||
/**
|
||||
* Builds the months value parser.
|
||||
*/
|
||||
public DayOfWeekValueParser() {
|
||||
super(0, 7);
|
||||
}
|
||||
|
||||
public int parse(String value) throws Exception {
|
||||
try {
|
||||
// try as a simple value
|
||||
return super.parse(value) % 7;
|
||||
} catch (Exception e) {
|
||||
// try as an alias
|
||||
return parseAlias(value, ALIASES, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* cron4j - A pure Java cron-like scheduler
|
||||
*
|
||||
* Copyright (C) 2007-2010 Carlo Pelliccia (www.sauronsoftware.it)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version
|
||||
* 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License 2.1 for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License version 2.1 along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.gcube.vremanagement.executor.api.scheduling;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This interface describes the ValueMatcher behavior. A ValueMatcher is an
|
||||
* object that validate an integer value against a set of rules.
|
||||
* </p>
|
||||
*
|
||||
* @author Carlo Pelliccia
|
||||
*/
|
||||
interface ValueMatcher {
|
||||
|
||||
/**
|
||||
* Validate the given integer value against a set of rules.
|
||||
*
|
||||
* @param value
|
||||
* The value.
|
||||
* @return true if the given value matches the rules of the ValueMatcher,
|
||||
* false otherwise.
|
||||
*/
|
||||
public boolean match(int value);
|
||||
|
||||
}
|
Loading…
Reference in New Issue