1 package com.atlassian.core.cron.generator;
2
3 import com.atlassian.core.cron.CronEditorBean;
4 import com.atlassian.core.util.DateUtils;
5 import org.apache.commons.lang.StringUtils;
6
7
8
9
10 public class CronExpressionGenerator
11 {
12 private static final String DAY_IN_MONTH_SEPARATOR = "#";
13 private static final String LAST_DAY_IN_MONTH_FLAG = "L";
14
15
16
17
18
19
20
21
22
23 public String getCronExpressionFromInput(CronEditorBean cronEditorBean)
24 {
25 String cronSpec = null;
26
27 if (cronEditorBean.isDailyMode())
28 {
29
30 cronSpec = generateDailySpec(cronEditorBean) + " ? * *";
31 }
32 else if (cronEditorBean.isDayPerWeekMode())
33 {
34
35 cronSpec = generateDailySpec(cronEditorBean) + " ? * " + generateDaysOfWeekSpec(cronEditorBean);
36 }
37 else if (cronEditorBean.isDaysPerMonthMode())
38 {
39
40 cronSpec = generateDailySpec(cronEditorBean) + " " + generateDaysOfMonthOptSpec(cronEditorBean);
41 }
42 else if (cronEditorBean.isAdvancedMode())
43 {
44 cronSpec = cronEditorBean.getCronString();
45 }
46
47 return cronSpec;
48 }
49
50
51
52
53
54
55
56
57
58
59
60 String generateDaysOfMonthOptSpec(CronEditorBean cronEditorBean)
61 {
62
63 if (cronEditorBean.isDayOfWeekOfMonth())
64 {
65 return generateDayOfWeekOfMonthSpec(cronEditorBean);
66 }
67 else
68 {
69 return generateDayOfMonthSpec(cronEditorBean);
70 }
71 }
72
73 String generateDayOfWeekOfMonthSpec(CronEditorBean cronEditorBean)
74 {
75 String dayInMonthOrdinal = cronEditorBean.getDayInMonthOrdinal();
76 if (dayInMonthOrdinal == null)
77 {
78 throw new IllegalStateException("You must have an ordinal set when generating the day of week of month cron portion: " + cronEditorBean.getCronString());
79 }
80 if (!LAST_DAY_IN_MONTH_FLAG.equalsIgnoreCase(dayInMonthOrdinal))
81 {
82 dayInMonthOrdinal = DAY_IN_MONTH_SEPARATOR + dayInMonthOrdinal;
83 }
84 String specifiedDaysPerWeek = cronEditorBean.getSpecifiedDaysPerWeek();
85 if (specifiedDaysPerWeek == null)
86 {
87 throw new IllegalStateException("The days per week must be specified when creating a days per week cron portion: " + cronEditorBean.getCronString());
88 }
89 String specSegment = specifiedDaysPerWeek + dayInMonthOrdinal;
90 return "? * " + specSegment;
91 }
92
93
94
95
96
97
98
99 String generateDayOfMonthSpec(CronEditorBean cronEditorBean)
100 {
101 String monthDay = cronEditorBean.getDayOfMonth();
102 if (monthDay == null)
103 {
104 throw new IllegalStateException("The day of month must not be null when creating a day of month cron portion: " + cronEditorBean.getCronString());
105 }
106 return monthDay + " * ?";
107 }
108
109
110
111
112
113
114
115 String generateDaysOfWeekSpec(CronEditorBean cronEditorBean)
116 {
117 if (StringUtils.isBlank(cronEditorBean.getSpecifiedDaysPerWeek()))
118 {
119 throw new IllegalStateException("The days per week must be specified when creating a days per week cron portion: " + cronEditorBean.getCronString());
120 }
121 return cronEditorBean.getSpecifiedDaysPerWeek();
122 }
123
124
125
126
127 String generateDailySpec(CronEditorBean cronEditorBean)
128 {
129
130 StringBuffer dailyString = new StringBuffer("0 ");
131
132 int increment = getIntFromString(cronEditorBean.getIncrementInMinutes());
133
134
135 if (increment == 0 || cronEditorBean.isDaysPerMonthMode())
136 {
137
138 if (cronEditorBean.getHoursRunOnceMeridian() == null)
139 {
140 throw new IllegalStateException("You must specify a run once hour meridian when generating a daily spec with no interval: " + cronEditorBean.getCronString());
141 }
142 if (cronEditorBean.getHoursRunOnce() == null)
143 {
144 throw new IllegalStateException("You must specify a run once hour when generating a daily spec with no interval: " + cronEditorBean.getCronString());
145 }
146 if (cronEditorBean.getMinutes() == null)
147 {
148 throw new IllegalStateException("You must specify a minutes when generating a daily spec with no interval: " + cronEditorBean.getCronString());
149 }
150
151
152 int atHours = getIntFromString(cronEditorBean.getHoursRunOnce());
153 int atMins = getIntFromString(cronEditorBean.getMinutes());
154
155 atHours = DateUtils.get24HourTime(cronEditorBean.getHoursRunOnceMeridian(), atHours);
156
157
158 dailyString.append(atMins);
159 dailyString.append(" ");
160 dailyString.append(atHours);
161 }
162
163 else
164 {
165
166 dailyString.append("0");
167
168 if (increment < 60)
169 {
170 dailyString.append("/");
171 dailyString.append(increment);
172 }
173
174 dailyString.append(" ");
175
176
177 if (cronEditorBean.getHoursFrom() == null)
178 {
179 throw new IllegalStateException("You must specify a from hour when generating a daily spec with an interval: " + cronEditorBean.getCronString());
180 }
181 if (cronEditorBean.getHoursFromMeridian() == null)
182 {
183 throw new IllegalStateException("You must specify a from hour meridian when generating a daily spec with an interval: " + cronEditorBean.getCronString());
184 }
185
186 if (cronEditorBean.getHoursTo() == null)
187 {
188 throw new IllegalStateException("You must specify a to hour when generating a daily spec with an interval: " + cronEditorBean.getCronString());
189 }
190 if (cronEditorBean.getHoursToMeridian() == null)
191 {
192 throw new IllegalStateException("You must specify a to hour meridian when generating a daily spec with an interval: " + cronEditorBean.getCronString());
193 }
194
195
196 int fromHours = DateUtils.get24HourTime(cronEditorBean.getHoursFromMeridian(), getIntFromString(cronEditorBean.getHoursFrom()));
197 int toHours = DateUtils.get24HourTime(cronEditorBean.getHoursToMeridian(), getIntFromString(cronEditorBean.getHoursTo()));
198
199 int hourIncrement = increment / 60;
200
201 if (cronEditorBean.is24HourRange())
202 {
203 dailyString.append("*");
204 }
205 else
206 {
207 dailyString.append(fromHours);
208 dailyString.append("-");
209
210
211 dailyString.append(decrementHourByOne(toHours));
212 }
213
214 if (hourIncrement >= 1)
215 {
216 dailyString.append("/");
217 dailyString.append(hourIncrement);
218 }
219 }
220
221 return dailyString.toString();
222 }
223
224 int getIntFromString(String string)
225 {
226 if (string != null && !StringUtils.isEmpty(string))
227 {
228 return Integer.parseInt(string);
229 }
230 return 0;
231 }
232
233 private int decrementHourByOne(int hour)
234 {
235 return hour == 0 ? 23 : hour - 1;
236 }
237 }