31
31
/**
32
32
* Corresponds to SessionTime in C++ code
33
33
*/
34
- public class DefaultSessionSchedule implements SessionSchedule {
34
+ public class DefaultSessionSchedule implements SessionSchedule {
35
35
private static final int NOT_SET = -1 ;
36
36
private static final Pattern TIME_PATTERN = Pattern .compile ("(\\ d{2}):(\\ d{2}):(\\ d{2})(.*)" );
37
37
private final TimeEndPoint startTime ;
38
38
private final TimeEndPoint endTime ;
39
- private final boolean nonStopSession ;
40
- protected final static Logger log = LoggerFactory .getLogger (DefaultSessionSchedule .class );
39
+ private final boolean isNonStopSession ;
40
+ private final boolean isWeekdaySession ;
41
+ private final int [] weekdayOffsets ;
42
+ protected static final Logger LOG = LoggerFactory .getLogger (DefaultSessionSchedule .class );
41
43
42
44
public DefaultSessionSchedule (SessionSettings settings , SessionID sessionID ) throws ConfigError ,
43
45
FieldConvertError {
44
46
45
- nonStopSession = settings .isSetting (sessionID , Session .SETTING_NON_STOP_SESSION ) && settings .getBool (sessionID , Session .SETTING_NON_STOP_SESSION );
47
+ isNonStopSession = settings .isSetting (sessionID , Session .SETTING_NON_STOP_SESSION ) && settings .getBool (sessionID , Session .SETTING_NON_STOP_SESSION );
46
48
TimeZone defaultTimeZone = getDefaultTimeZone (settings , sessionID );
47
- if (nonStopSession ) {
49
+ if (isNonStopSession ) {
50
+ isWeekdaySession = false ;
51
+ weekdayOffsets = new int [0 ];
48
52
startTime = endTime = new TimeEndPoint (NOT_SET , 0 , 0 , 0 , defaultTimeZone );
49
53
return ;
54
+ } else {
55
+ isWeekdaySession = settings .isSetting (sessionID , Session .SETTING_WEEKDAYS );
50
56
}
51
57
52
58
boolean startDayPresent = settings .isSetting (sessionID , Session .SETTING_START_DAY );
53
59
boolean endDayPresent = settings .isSetting (sessionID , Session .SETTING_END_DAY );
54
60
55
- if (startDayPresent && ! endDayPresent ) {
56
- throw new ConfigError ( "Session " + sessionID + ": StartDay used without EndDay" );
57
- }
61
+ if (isWeekdaySession ) {
62
+ if ( startDayPresent || endDayPresent )
63
+ throw new ConfigError ( "Session " + sessionID + ": usage of StartDay or EndDay is not compatible with setting " + Session . SETTING_WEEKDAYS );
58
64
59
- if (endDayPresent && !startDayPresent ) {
60
- throw new ConfigError ("Session " + sessionID + ": EndDay used without StartDay" );
61
- }
65
+ String weekdayNames = settings .getString (sessionID , Session .SETTING_WEEKDAYS );
66
+ if (weekdayNames .isEmpty ())
67
+ throw new ConfigError ("Session " + sessionID + ": " + Session .SETTING_WEEKDAYS + " is empty" );
68
+
69
+ String [] weekdayNameArray = weekdayNames .split ("," );
70
+ weekdayOffsets = new int [weekdayNameArray .length ];
71
+ for (int i = 0 ; i < weekdayNameArray .length ; i ++) {
72
+ weekdayOffsets [i ] = DayConverter .toInteger (weekdayNameArray [i ]);
73
+ }
74
+ } else {
75
+ weekdayOffsets = new int [0 ];
76
+
77
+ if (startDayPresent && !endDayPresent ) {
78
+ throw new ConfigError ("Session " + sessionID + ": StartDay used without EndDay" );
79
+ }
62
80
81
+ if (endDayPresent && !startDayPresent ) {
82
+ throw new ConfigError ("Session " + sessionID + ": EndDay used without StartDay" );
83
+ }
84
+ }
63
85
startTime = getTimeEndPoint (settings , sessionID , defaultTimeZone , Session .SETTING_START_TIME , Session .SETTING_START_DAY );
64
86
endTime = getTimeEndPoint (settings , sessionID , defaultTimeZone , Session .SETTING_END_TIME , Session .SETTING_END_DAY );
65
- log .info ("[" + sessionID + "] " + toString ());
87
+ LOG .info ("[" + sessionID + "] " + toString ());
66
88
}
67
89
68
90
private TimeEndPoint getTimeEndPoint (SessionSettings settings , SessionID sessionID ,
@@ -75,7 +97,8 @@ private TimeEndPoint getTimeEndPoint(SessionSettings settings, SessionID session
75
97
+ settings .getString (sessionID , timeSetting ) + "'." );
76
98
}
77
99
78
- return new TimeEndPoint (getDay (settings , sessionID , daySetting , NOT_SET ),
100
+ return new TimeEndPoint (
101
+ getDay (settings , sessionID , daySetting , NOT_SET ),
79
102
Integer .parseInt (matcher .group (1 )), Integer .parseInt (matcher .group (2 )),
80
103
Integer .parseInt (matcher .group (3 )), getTimeZone (matcher .group (4 ), defaultTimeZone ));
81
104
}
@@ -100,7 +123,7 @@ private TimeZone getTimeZone(String tz, TimeZone defaultZone) {
100
123
return "" .equals (tz ) ? defaultZone : TimeZone .getTimeZone (tz .trim ());
101
124
}
102
125
103
- private class TimeEndPoint {
126
+ private static class TimeEndPoint {
104
127
private final int weekDay ;
105
128
private final int hour ;
106
129
private final int minute ;
@@ -117,34 +140,19 @@ public TimeEndPoint(int day, int hour, int minute, int second, TimeZone tz) {
117
140
timeInSeconds = timeInSeconds (hour , minute , second );
118
141
}
119
142
120
- public int getHour () {
143
+ int getHour () {
121
144
return hour ;
122
145
}
123
146
124
- public int getMinute () {
147
+ int getMinute () {
125
148
return minute ;
126
149
}
127
150
128
- public int getSecond () {
151
+ int getSecond () {
129
152
return second ;
130
153
}
131
154
132
- public String toString () {
133
- try {
134
- Calendar calendar = Calendar .getInstance (tz );
135
- calendar .set (Calendar .HOUR_OF_DAY , hour );
136
- calendar .set (Calendar .MINUTE , minute );
137
- calendar .set (Calendar .SECOND , second );
138
- final SimpleDateFormat utc = new SimpleDateFormat ("HH:mm:ss" );
139
- utc .setTimeZone (TimeZone .getTimeZone ("UTC" ));
140
- return (isSet (weekDay ) ? DayConverter .toString (weekDay ) + "," : "" )
141
- + utc .format (calendar .getTime ()) + "-" + utc .getTimeZone ().getID ();
142
- } catch (ConfigError e ) {
143
- return "ERROR: " + e ;
144
- }
145
- }
146
-
147
- public int getDay () {
155
+ int getDay () {
148
156
return weekDay ;
149
157
}
150
158
@@ -164,11 +172,17 @@ public int hashCode() {
164
172
return 0 ;
165
173
}
166
174
167
- public TimeZone getTimeZone () {
175
+ TimeZone getTimeZone () {
168
176
return tz ;
169
177
}
170
178
}
171
179
180
+ /**
181
+ * find the most recent session date/time range on or before t
182
+ * if t is in a session then that session will be returned
183
+ * @param t specific date/time
184
+ * @return relevant session date/time range
185
+ */
172
186
private TimeInterval theMostRecentIntervalBefore (Calendar t ) {
173
187
TimeInterval timeInterval = new TimeInterval ();
174
188
Calendar intervalStart = timeInterval .getStart ();
@@ -187,24 +201,37 @@ private TimeInterval theMostRecentIntervalBefore(Calendar t) {
187
201
intervalEnd .set (Calendar .SECOND , endTime .getSecond ());
188
202
intervalEnd .set (Calendar .MILLISECOND , 0 );
189
203
190
- if (isSet ( startTime . getDay ()) ) {
191
- intervalStart .set ( Calendar . DAY_OF_WEEK , startTime . getDay ());
192
- if ( intervalStart . getTimeInMillis () > t . getTimeInMillis ( )) {
193
- intervalStart .add (Calendar .WEEK_OF_YEAR , -1 );
194
- intervalEnd .add (Calendar .WEEK_OF_YEAR , -1 );
204
+ if (isWeekdaySession ) {
205
+ while ( intervalStart .getTimeInMillis () > t . getTimeInMillis () ||
206
+ ! validDayOfWeek ( intervalStart )) {
207
+ intervalStart .add (Calendar .DAY_OF_WEEK , -1 );
208
+ intervalEnd .add (Calendar .DAY_OF_WEEK , -1 );
195
209
}
196
- } else if (intervalStart .getTimeInMillis () > t .getTimeInMillis ()) {
197
- intervalStart .add (Calendar .DAY_OF_YEAR , -1 );
198
- intervalEnd .add (Calendar .DAY_OF_YEAR , -1 );
199
- }
200
210
201
- if (isSet (endTime .getDay ())) {
202
- intervalEnd .set (Calendar .DAY_OF_WEEK , endTime .getDay ());
203
211
if (intervalEnd .getTimeInMillis () <= intervalStart .getTimeInMillis ()) {
204
- intervalEnd .add (Calendar .WEEK_OF_MONTH , 1 );
212
+ intervalEnd .add (Calendar .DAY_OF_WEEK , 1 );
213
+ }
214
+
215
+ } else {
216
+ if (isSet (startTime .getDay ())) {
217
+ intervalStart .set (Calendar .DAY_OF_WEEK , startTime .getDay ());
218
+ if (intervalStart .getTimeInMillis () > t .getTimeInMillis ()) {
219
+ intervalStart .add (Calendar .WEEK_OF_YEAR , -1 );
220
+ intervalEnd .add (Calendar .WEEK_OF_YEAR , -1 );
221
+ }
222
+ } else if (intervalStart .getTimeInMillis () > t .getTimeInMillis ()) {
223
+ intervalStart .add (Calendar .DAY_OF_YEAR , -1 );
224
+ intervalEnd .add (Calendar .DAY_OF_YEAR , -1 );
225
+ }
226
+
227
+ if (isSet (endTime .getDay ())) {
228
+ intervalEnd .set (Calendar .DAY_OF_WEEK , endTime .getDay ());
229
+ if (intervalEnd .getTimeInMillis () <= intervalStart .getTimeInMillis ()) {
230
+ intervalEnd .add (Calendar .WEEK_OF_MONTH , 1 );
231
+ }
232
+ } else if (intervalEnd .getTimeInMillis () <= intervalStart .getTimeInMillis ()) {
233
+ intervalEnd .add (Calendar .DAY_OF_WEEK , 1 );
205
234
}
206
- } else if (intervalEnd .getTimeInMillis () <= intervalStart .getTimeInMillis ()) {
207
- intervalEnd .add (Calendar .DAY_OF_WEEK , 1 );
208
235
}
209
236
210
237
return timeInterval ;
@@ -214,7 +241,7 @@ private static class TimeInterval {
214
241
private final Calendar start = SystemTime .getUtcCalendar ();
215
242
private final Calendar end = SystemTime .getUtcCalendar ();
216
243
217
- public boolean isContainingTime (Calendar t ) {
244
+ boolean isContainingTime (Calendar t ) {
218
245
return t .compareTo (start ) >= 0 && t .compareTo (end ) <= 0 ;
219
246
}
220
247
@@ -238,17 +265,18 @@ public int hashCode() {
238
265
return 0 ;
239
266
}
240
267
241
- public Calendar getStart () {
268
+ Calendar getStart () {
242
269
return start ;
243
270
}
244
271
245
- public Calendar getEnd () {
272
+ Calendar getEnd () {
246
273
return end ;
247
274
}
248
275
}
249
276
277
+ @ Override
250
278
public boolean isSameSession (Calendar time1 , Calendar time2 ) {
251
- if (nonStopSession )
279
+ if (isNonStopSession () )
252
280
return true ;
253
281
TimeInterval interval1 = theMostRecentIntervalBefore (time1 );
254
282
if (!interval1 .isContainingTime (time1 )) {
@@ -258,16 +286,18 @@ public boolean isSameSession(Calendar time1, Calendar time2) {
258
286
return interval2 .isContainingTime (time2 ) && interval1 .equals (interval2 );
259
287
}
260
288
289
+ @ Override
261
290
public boolean isNonStopSession () {
262
- return nonStopSession ;
291
+ return isNonStopSession ;
263
292
}
264
293
265
294
private boolean isDailySession () {
266
295
return !isSet (startTime .getDay ()) && !isSet (endTime .getDay ());
267
296
}
268
-
297
+
298
+ @ Override
269
299
public boolean isSessionTime () {
270
- if (nonStopSession ) {
300
+ if (isNonStopSession () ) {
271
301
return true ;
272
302
}
273
303
Calendar now = SystemTime .getUtcCalendar ();
@@ -301,7 +331,16 @@ public String toString() {
301
331
302
332
private void formatTimeInterval (StringBuilder buf , TimeInterval timeInterval ,
303
333
SimpleDateFormat timeFormat , boolean local ) {
304
- if (!isDailySession ()) {
334
+ if (isWeekdaySession ) {
335
+ try {
336
+ for (int i = 0 ; i < weekdayOffsets .length ; i ++) {
337
+ buf .append (DayConverter .toString (weekdayOffsets [i ]));
338
+ buf .append (", " );
339
+ }
340
+ } catch (ConfigError ex ) {
341
+ // this can't happen as these are created using DayConverter.toInteger
342
+ }
343
+ } else if (!isDailySession ()) {
305
344
buf .append ("weekly, " );
306
345
formatDayOfWeek (buf , startTime .getDay ());
307
346
buf .append (" " );
@@ -349,7 +388,20 @@ private boolean isSet(int value) {
349
388
return value != NOT_SET ;
350
389
}
351
390
352
- private int timeInSeconds (int hour , int minute , int second ) {
391
+ private static int timeInSeconds (int hour , int minute , int second ) {
353
392
return (hour * 3600 ) + (minute * 60 ) + second ;
354
393
}
394
+
395
+ /**
396
+ * is the startDateTime a valid day based on the permitted days of week
397
+ * @param startDateTime time to test
398
+ * @return flag indicating if valid
399
+ */
400
+ private boolean validDayOfWeek (Calendar startDateTime ) {
401
+ int dow = startDateTime .get (Calendar .DAY_OF_WEEK );
402
+ for (int i = 0 ; i < weekdayOffsets .length ; i ++)
403
+ if (weekdayOffsets [i ] == dow )
404
+ return true ;
405
+ return false ;
406
+ }
355
407
}
0 commit comments