net.redhogs.cronparser.CronExpressionDescriptor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of quartz-glass Show documentation
Show all versions of quartz-glass Show documentation
A web user interface for quartz
package net.redhogs.cronparser;
import net.redhogs.cronparser.builder.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author grhodes
* @since 10 Dec 2012 11:36:38
*/
public class CronExpressionDescriptor {
private static final Logger LOG = LoggerFactory.getLogger(CronExpressionDescriptor.class);
private static final char[] specialCharacters = new char[]{'/', '-', ',', '*'};
private CronExpressionDescriptor() {
}
public static String getDescription(String expression) throws ParseException {
return getDescription(DescriptionTypeEnum.FULL, expression, new Options());
}
public static String getDescription(DescriptionTypeEnum type, String expression) throws ParseException {
return getDescription(type, expression, new Options());
}
public static String getDescription(DescriptionTypeEnum type, String expression, Options options) throws ParseException {
String[] expressionParts = new String[6];
String description = "";
try {
expressionParts = ExpressionParser.parse(expression);
switch (type) {
case FULL:
description = getFullDescription(expression, expressionParts, options);
break;
case TIMEOFDAY:
description = getTimeOfDayDescription(expression, expressionParts, options);
break;
case HOURS:
description = getHoursDescription(expression, expressionParts, options);
break;
case MINUTES:
description = getMinutesDescription(expression, expressionParts, options);
break;
case SECONDS:
description = getSecondsDescription(expression, expressionParts, options);
break;
case DAYOFMONTH:
description = getDayOfMonthDescription(expression, expressionParts, options);
break;
case MONTH:
description = getMonthDescription(expression, expressionParts, options);
break;
case DAYOFWEEK:
description = getDayOfWeekDescription(expression, expressionParts, options);
break;
default:
description = getSecondsDescription(expression, expressionParts, options);
break;
}
} catch (ParseException e) {
if (!options.isThrowExceptionOnParseError()) {
description = e.getMessage();
LOG.debug("Exception parsing expression.", e);
} else {
LOG.error("Exception parsing expression.", e);
throw e;
}
}
return description;
}
/**
* @param options
* @param expressionParts
* @param expression
* @return
*/
private static String getDayOfWeekDescription(String expression, String[] expressionParts, Options options) {
return new DayOfWeekDescriptionBuilder().getSegmentDescription(expressionParts[5], ", every day");
}
/**
* @param options
* @param expressionParts
* @param expression
* @return
*/
private static String getMonthDescription(String expression, String[] expressionParts, Options options) {
return new MonthDescriptionBuilder().getSegmentDescription(expressionParts[4], "");
}
/**
* @param options
* @param expressionParts
* @param expression
* @return
*/
private static String getDayOfMonthDescription(String expression, String[] expressionParts, Options options) {
String description = null;
String exp = expressionParts[3].replace("?", "*");
if ("L".equals(exp)) {
description = ", on the last day of the month";
} else if ("WL".equals(exp) || "LW".equals(exp)) {
description = ", on the last weekday of the month";
} else {
Pattern pattern = Pattern.compile("(\\dW)|(W\\d)");
Matcher matcher = pattern.matcher(exp);
if (matcher.matches()) {
int dayNumber = Integer.parseInt(matcher.group().replace("W", ""));
String dayString = dayNumber == 1 ? "first weekday" : MessageFormat.format("weekday nearest day {0}", dayNumber);
description = MessageFormat.format(", on the {0} of the month", dayString);
} else {
description = new DayOfMonthDescriptionBuilder().getSegmentDescription(exp, ", every day");
}
}
return description;
}
/**
* @param options
* @param expressionParts
* @param expression
* @return
*/
private static String getSecondsDescription(String expression, String[] expressionParts, Options options) {
return new SecondsDescriptionBuilder().getSegmentDescription(expressionParts[0], "every second");
}
/**
* @param options
* @param expressionParts
* @param expression
* @return
*/
private static String getMinutesDescription(String expression, String[] expressionParts, Options options) {
return new MinutesDescriptionBuilder().getSegmentDescription(expressionParts[1], "every minute");
}
/**
* @param options
* @param expressionParts
* @param expression
* @return
*/
private static String getHoursDescription(String expression, String[] expressionParts, Options options) {
return new HoursDescriptionBuilder().getSegmentDescription(expressionParts[2], "every hour");
}
/**
* @param options
* @param expressionParts
* @param expression
* @return
*/
private static String getTimeOfDayDescription(String expression, String[] expressionParts, Options options) {
String secondsExpression = expressionParts[0];
String minutesExpression = expressionParts[1];
String hoursExpression = expressionParts[2];
StringBuffer description = new StringBuffer();
// Handle special cases first
if (!StringUtils.containsAny(minutesExpression, specialCharacters) && !StringUtils.containsAny(hoursExpression, specialCharacters) && !StringUtils.containsAny(secondsExpression, specialCharacters)) {
description.append("At ").append(DateAndTimeUtils.formatTime(hoursExpression, minutesExpression, secondsExpression)); // Specific time of day (e.g. 10 14)
} else if (minutesExpression.contains("-") && !StringUtils.containsAny(hoursExpression, specialCharacters)) {
// Minute range in single hour (e.g. 0-10 11)
String[] minuteParts = minutesExpression.split("-");
description.append(MessageFormat.format("Every minute between {0} and {1}", DateAndTimeUtils.formatTime(hoursExpression, minuteParts[0]),
DateAndTimeUtils.formatTime(hoursExpression, minuteParts[1])));
} else if (hoursExpression.contains(",") && !StringUtils.containsAny(minutesExpression, specialCharacters)) {
// Hours list with single minute (e.g. 30 6,14,16)
String[] hourParts = hoursExpression.split(",");
description.append("At");
for (int i = 0; i < hourParts.length; i++) {
description.append(" ").append(DateAndTimeUtils.formatTime(hourParts[i], minutesExpression));
if (i < hourParts.length - 2) {
description.append(",");
}
if (i == hourParts.length - 2) {
description.append(" and");
}
}
} else {
String secondsDescription = getSecondsDescription(expression, expressionParts, options);
String minutesDescription = getMinutesDescription(expression, expressionParts, options);
String hoursDescription = getHoursDescription(expression, expressionParts, options);
description.append(secondsDescription);
if (description.length() > 0) {
description.append(", ");
}
description.append(minutesDescription);
if (description.length() > 0) {
description.append(", ");
}
description.append(hoursDescription);
}
return description.toString();
}
/**
* @param options
* @param expressionParts
* @param expression
* @return
*/
private static String getFullDescription(String expression, String[] expressionParts, Options options) {
String description = "";
String timeSegment = getTimeOfDayDescription(expression, expressionParts, options);
String dayOfMonthDesc = getDayOfMonthDescription(expression, expressionParts, options);
String monthDesc = getMonthDescription(expression, expressionParts, options);
String dayOfWeekDesc = getDayOfWeekDescription(expression, expressionParts, options);
description = MessageFormat.format("{0}{1}{2}", timeSegment, ("*".equals(expressionParts[3]) ? dayOfWeekDesc : dayOfMonthDesc), monthDesc);
description = transformVerbosity(description, options);
description = transformCase(description, options);
return description;
}
/**
* @param description
* @return
*/
private static String transformCase(String description, Options options) {
String descTemp = description;
switch (options.getCasingType()) {
case Sentence:
descTemp = StringUtils.upperCase("" + descTemp.charAt(0)) + descTemp.substring(1);
break;
case Title:
descTemp = StringUtils.capitalize(descTemp);
break;
default:
descTemp = descTemp.toLowerCase();
break;
}
return descTemp;
}
/**
* @param description
* @param options
* @return
*/
private static String transformVerbosity(String description, Options options) {
String descTemp = description;
if (!options.isVerbose()) {
descTemp = descTemp.replace("every 1 minute", "every minute");
descTemp = descTemp.replace("every 1 hour", "every hour");
descTemp = descTemp.replace("every 1 day", "every day");
descTemp = descTemp.replace(", every minute", "");
descTemp = descTemp.replace(", every hour", "");
descTemp = descTemp.replace(", every day", "");
}
return descTemp;
}
}