001 package org.apache.turbine.services.schedule; 002 003 004 import java.sql.Date; 005 import java.util.Calendar; 006 007 import org.apache.commons.lang.StringUtils; 008 import org.apache.commons.logging.Log; 009 import org.apache.commons.logging.LogFactory; 010 import org.apache.torque.om.Persistent; 011 import org.apache.turbine.util.TurbineException; 012 013 /** 014 * The skeleton for this class was autogenerated by Torque on: 015 * 016 * [Mon Jan 24 20:11:00 CET 2011] 017 * 018 * You should add additional methods to this class to meet the 019 * application requirements. This class will only be generated as 020 * long as it does not already exist in the output directory. 021 */ 022 public class JobEntry 023 extends org.apache.turbine.services.schedule.BaseJobEntry 024 implements Persistent 025 { 026 /** 027 * 028 */ 029 private static final long serialVersionUID = -5501116588294474363L; 030 031 /** Logging */ 032 private static Log log = LogFactory.getLog(ScheduleService.LOGGER_NAME); 033 034 /** indicates if job is currently running */ 035 private boolean jobIsActive = false; 036 037 /** Next runtime. **/ 038 private long runtime = 0; 039 040 /** schedule types **/ 041 private static final int SECOND = 0; 042 private static final int MINUTE = 1; 043 private static final int WEEK_DAY = 2; 044 private static final int DAY_OF_MONTH = 3; 045 private static final int DAILY = 4; 046 047 /** 048 * default constructor 049 */ 050 public JobEntry() 051 { 052 // empty 053 } 054 055 /** 056 * Constuctor. 057 * 058 * Schedule a job to run on a certain point of time.<br> 059 * 060 * Example 1: Run the DefaultScheduledJob at 8:00am every 15th of 061 * the month - <br> 062 * 063 * JobEntry je = new JobEntry(0,0,8,15,"DefaultScheduledJob");<br> 064 * 065 * Example 2: Run the DefaultScheduledJob at 8:00am every day - 066 * <br> 067 * 068 * JobEntry je = new JobEntry(0,0,8,-1,"DefaultScheduledJob");<br> 069 * 070 * Example 3: Run the DefaultScheduledJob every 2 hours. - <br> 071 * 072 * JobEntry je = new JobEntry(0,120,-1,-1,"DefaultScheduledJob");<br> 073 * 074 * Example 4: Run the DefaultScheduledJob every 30 seconds. - <br> 075 * 076 * JobEntry je = new JobEntry(30,-1,-1,-1,"DefaultScheduledJob");<br> 077 * 078 * @param sec Value for entry "seconds". 079 * @param min Value for entry "minutes". 080 * @param hour Value for entry "hours". 081 * @param wd Value for entry "week days". 082 * @param day_mo Value for entry "month days". 083 * @param task Task to execute. 084 * @exception TurbineException a generic exception. 085 */ 086 public JobEntry(int sec, 087 int min, 088 int hour, 089 int wd, 090 int day_mo, 091 String task) 092 throws TurbineException 093 { 094 if (StringUtils.isEmpty(task)) 095 { 096 throw new TurbineException("Error in JobEntry. " + 097 "Bad Job parameter. Task not set."); 098 } 099 100 setSecond(sec); 101 setMinute(min); 102 setHour(hour); 103 setWeekDay(wd); 104 setDayOfMonth(day_mo); 105 setTask(task); 106 107 calcRunTime(); 108 } 109 110 /** 111 * Used for ordering Jobentries 112 * Note: this comparator imposes orderings that are inconsistent with 113 * equals. 114 * 115 * @param je The first <code>JobEntry</code> object. 116 * @return An <code>int</code> indicating the result of the comparison. 117 */ 118 public int compareTo(Object je) 119 { 120 int result = -1; 121 if (je instanceof JobEntry) 122 { 123 result = getJobId() - ((JobEntry) je).getJobId(); 124 } 125 return result; 126 } 127 128 /** 129 * Sets whether the job is running. 130 * 131 * @param isActive Whether the job is running. 132 */ 133 public void setActive(boolean isActive) 134 { 135 jobIsActive = isActive; 136 } 137 138 /** 139 * Check to see if job is currently active/running 140 * 141 * @return true if job is currently geing run by the 142 * workerthread, otherwise false 143 */ 144 public boolean isActive() 145 { 146 return jobIsActive; 147 } 148 149 /** 150 * Get the next runtime for this job as a long. 151 * 152 * @return The next run time as a long. 153 */ 154 public long getNextRuntime() 155 { 156 return runtime; 157 } 158 159 /** 160 * Gets the next runtime as a date 161 * 162 * @return Next run date 163 */ 164 public Date getNextRunDate() 165 { 166 return new Date(runtime); 167 } 168 169 /** 170 * Get the next runtime for this job as a String. 171 * 172 * @return The next run time as a String. 173 */ 174 public String getNextRunAsString() 175 { 176 return getNextRunDate().toString(); 177 } 178 179 /** 180 * Calculate how long before the next runtime.<br> 181 * 182 * The runtime determines it's position in the job queue. 183 * Here's the logic:<br> 184 * 185 * 1. Create a date the represents when this job is to run.<br> 186 * 187 * 2. If this date has expired, them "roll" appropriate date 188 * fields forward to the next date.<br> 189 * 190 * 3. Calculate the diff in time between the current time and the 191 * next run time.<br> 192 * 193 * @exception TurbineException a generic exception. 194 */ 195 public void calcRunTime() 196 throws TurbineException 197 { 198 Calendar schedrun = Calendar.getInstance(); 199 Calendar now = Calendar.getInstance(); 200 201 switch (evaluateJobType()) 202 { 203 case SECOND: 204 // SECOND (every so many seconds...) 205 schedrun.add(Calendar.SECOND, getSecond()); 206 runtime = schedrun.getTime().getTime(); 207 break; 208 209 case MINUTE: 210 // MINUTE (every so many minutes...) 211 schedrun.add(Calendar.SECOND, getSecond()); 212 schedrun.add(Calendar.MINUTE, getMinute()); 213 runtime = schedrun.getTime().getTime(); 214 break; 215 216 case WEEK_DAY: 217 // WEEKDAY (day of the week) 218 schedrun.set(Calendar.SECOND, getSecond()); 219 schedrun.set(Calendar.MINUTE, getMinute()); 220 schedrun.set(Calendar.HOUR_OF_DAY, getHour()); 221 schedrun.set(Calendar.DAY_OF_WEEK, getWeekDay()); 222 223 if (now.before(schedrun)) 224 { 225 // Scheduled time has NOT expired. 226 runtime = schedrun.getTime().getTime(); 227 } 228 else 229 { 230 // Scheduled time has expired; roll to the next week. 231 schedrun.add(Calendar.DAY_OF_WEEK, 7); 232 runtime = schedrun.getTime().getTime(); 233 } 234 break; 235 236 case DAY_OF_MONTH: 237 // DAY_OF_MONTH (date of the month) 238 schedrun.set(Calendar.SECOND, getSecond()); 239 schedrun.set(Calendar.MINUTE, getMinute()); 240 schedrun.set(Calendar.HOUR_OF_DAY, getHour()); 241 schedrun.set(Calendar.DAY_OF_MONTH, getDayOfMonth()); 242 243 if (now.before(schedrun)) 244 { 245 // Scheduled time has NOT expired. 246 runtime = schedrun.getTime().getTime(); 247 } 248 else 249 { 250 // Scheduled time has expired; roll to the next month. 251 schedrun.add(Calendar.MONTH, 1); 252 runtime = schedrun.getTime().getTime(); 253 } 254 break; 255 256 case DAILY: 257 // DAILY (certain hour:minutes of the day) 258 schedrun.set(Calendar.SECOND, getSecond()); 259 schedrun.set(Calendar.MINUTE, getMinute()); 260 schedrun.set(Calendar.HOUR_OF_DAY, getHour()); 261 262 // Scheduled time has NOT expired. 263 if (now.before(schedrun)) 264 { 265 runtime = schedrun.getTime().getTime(); 266 } 267 else 268 { 269 // Scheduled time has expired; roll forward 24 hours. 270 schedrun.add(Calendar.HOUR_OF_DAY, 24); 271 runtime = schedrun.getTime().getTime(); 272 } 273 break; 274 275 default: 276 // Do nothing. 277 } 278 279 log.info("Next runtime for task " + this.getTask() + " is " + this.getNextRunDate()); 280 } 281 282 /** 283 * What schedule am I on? 284 * 285 * I know this is kinda ugly! If you can think of a cleaner way 286 * to do this, please jump in! 287 * 288 * @return A number specifying the type of schedule. See 289 * calcRunTime(). 290 * @exception TurbineException a generic exception. 291 */ 292 private int evaluateJobType() 293 throws TurbineException 294 { 295 296 // First start by checking if it's a day of the month job. 297 if (getDayOfMonth() < 0) 298 { 299 // Not a day of the month job... check weekday. 300 if (getWeekDay() < 0) 301 { 302 // Not a weekday job...check if by the hour. 303 if (getHour() < 0) 304 { 305 // Not an hourly job...check if it is by the minute 306 if (getMinute() < 0) 307 { 308 // Not a by the minute job so must be by the second 309 if (getSecond() < 0) 310 throw new TurbineException("Error in JobEntry. Bad Job parameter."); 311 312 return SECOND; 313 } 314 else 315 { 316 // Must be a job run by the minute so we need minutes and 317 // seconds. 318 if (getMinute() < 0 || getSecond() < 0) 319 throw new TurbineException("Error in JobEntry. Bad Job parameter."); 320 321 return MINUTE; 322 } 323 } 324 else 325 { 326 // Must be a daily job by hours minutes, and seconds. In 327 // this case, we need the minute, second, and hour params. 328 if (getMinute() < 0 || getHour() < 0 || getSecond() < 0) 329 throw new TurbineException("Error in JobEntry. Bad Job parameter."); 330 331 return DAILY; 332 } 333 } 334 else 335 { 336 // Must be a weekday job. In this case, we need 337 // minute, second, and hour params 338 if (getMinute() < 0 || getHour() < 0 || getSecond() < 0) 339 throw new TurbineException("Error in JobEntry. Bad Job parameter."); 340 341 return WEEK_DAY; 342 } 343 } 344 else 345 { 346 // Must be a day of the month job. In this case, we need 347 // minute, second, and hour params 348 if (getMinute() < 0 || getHour() < 0) 349 throw new TurbineException("Error in JobEntry. Bad Job parameter."); 350 351 return DAY_OF_MONTH; 352 } 353 } 354 355 }