1 package org.apache.turbine.services.schedule; 2 3 /* 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 */ 21 22 import java.util.List; 23 import java.util.Vector; 24 25 import javax.servlet.ServletConfig; 26 27 import org.apache.commons.configuration.Configuration; 28 29 import org.apache.commons.lang.StringUtils; 30 31 import org.apache.commons.logging.Log; 32 import org.apache.commons.logging.LogFactory; 33 34 import org.apache.turbine.services.InitializationException; 35 import org.apache.turbine.util.TurbineException; 36 37 /** 38 * Service for a cron like scheduler that uses the 39 * TurbineResources.properties file instead of the database. 40 * The methods that operate on jobs ( get,add,update,remove ) 41 * only operate on the queue in memory and changes are not reflected 42 * to the properties file which was used to initilize the jobs. 43 * An example is given below. The job names are the class names that 44 * extend ScheduledJob. 45 * 46 * <PRE> 47 * 48 * services.SchedulerService.scheduler.jobs=scheduledJobName,scheduledJobName2 49 * 50 * services.SchedulerService.scheduler.job.scheduledJobName.ID=1 51 * services.SchedulerService.scheduler.job.scheduledJobName.SECOND=-1 52 * services.SchedulerService.scheduler.job.scheduledJobName.MINUTE=-1 53 * services.SchedulerService.scheduler.job.scheduledJobName.HOUR=7 54 * services.SchedulerService.scheduler.job.scheduledJobName.WEEKDAY=-1 55 * services.SchedulerService.scheduler.job.scheduledJobName.DAY_OF_MONTH=-1 56 * 57 * services.SchedulerService.scheduler.job.scheduledJobName2.ID=1 58 * services.SchedulerService.scheduler.job.scheduledJobName2.SECOND=-1 59 * services.SchedulerService.scheduler.job.scheduledJobName2.MINUTE=-1 60 * services.SchedulerService.scheduler.job.scheduledJobName2.HOUR=7 61 * services.SchedulerService.scheduler.job.scheduledJobName2.WEEKDAY=-1 62 * services.SchedulerService.scheduler.job.scheduledJobName2.DAY_OF_MONTH=-1 63 * 64 * </PRE> 65 * 66 * Based on TamboraSchedulerService written by John Thorhauer. 67 * 68 * @author <a href="mailto:ekkerbj@netscpae.net">Jeff Brekke</a> 69 * @author <a href="mailto:john@zenplex.com">John Thorhauer</a> 70 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a> 71 * @version $Id: TurbineNonPersistentSchedulerService.java 534527 2007-05-02 16:10:59Z tv $ 72 */ 73 public class TurbineNonPersistentSchedulerService 74 extends TurbineSchedulerService 75 { 76 /** Logging */ 77 private static Log log = LogFactory.getLog(ScheduleService.LOGGER_NAME); 78 79 /** 80 * Constructor. 81 * 82 * @exception TurbineException a generic exception. 83 */ 84 public TurbineNonPersistentSchedulerService() 85 throws TurbineException 86 { 87 super(); 88 } 89 90 /** 91 * Called the first time the Service is used.<br> 92 * 93 * Load all the jobs from cold storage. Add jobs to the queue 94 * (sorted in ascending order by runtime) and start the scheduler 95 * thread. 96 */ 97 @SuppressWarnings("unchecked") 98 @Override 99 public void init() 100 throws InitializationException 101 { 102 Configuration conf = getConfiguration(); 103 104 try 105 { 106 scheduleQueue = new JobQueue(); 107 mainLoop = new MainLoop(); 108 109 List<String> jobProps = conf.getList("scheduler.jobs"); 110 List<JobEntry> jobs = new Vector<JobEntry>(); 111 // If there are scheduler.jobs defined then set up a job vector 112 // for the scheduleQueue 113 if (!jobProps.isEmpty()) 114 { 115 for (int i = 0; i < jobProps.size(); i++) 116 { 117 String jobName = jobProps.get(i); 118 String jobPrefix = "scheduler.job." + jobName; 119 120 String jobId = conf.getString(jobPrefix + ".ID", null); 121 if (StringUtils.isEmpty(jobId)) 122 { 123 throw new Exception( 124 "There is an error in the TurbineResources.properties file. \n" 125 + jobPrefix + ".ID is not found.\n"); 126 } 127 128 int sec = conf.getInt(jobPrefix + ".SECOND", -1); 129 int min = conf.getInt(jobPrefix + ".MINUTE", -1); 130 int hr = conf.getInt(jobPrefix + ".HOUR", -1); 131 int wkday = conf.getInt(jobPrefix + ".WEEKDAY", -1); 132 int dayOfMonth = conf.getInt(jobPrefix + ".DAY_OF_MONTH", -1); 133 134 JobEntry je = new JobEntry( 135 sec, 136 min, 137 hr, 138 wkday, 139 dayOfMonth, 140 jobName); 141 je.setJobId(Integer.parseInt(jobId)); 142 jobs.add(je); 143 144 } 145 } 146 147 if (jobs != null && jobs.size() > 0) 148 { 149 scheduleQueue.batchLoad(jobs); 150 } 151 152 setEnabled(getConfiguration().getBoolean("enabled", true)); 153 restart(); 154 155 setInit(true); 156 } 157 catch (Exception e) 158 { 159 String errorMessage = "Could not initialize the scheduler service"; 160 log.error(errorMessage, e); 161 throw new InitializationException(errorMessage, e); 162 } 163 } 164 165 /** 166 * Called the first time the Service is used.<br> 167 * 168 * Load all the jobs from cold storage. Add jobs to the queue 169 * (sorted in ascending order by runtime) and start the scheduler 170 * thread. 171 * 172 * @param config A ServletConfig. 173 * @deprecated use init() instead. 174 */ 175 @Deprecated 176 @Override 177 public void init(ServletConfig config) 178 throws InitializationException 179 { 180 init(); 181 } 182 183 /** 184 * This method returns the job element from the internal queue. 185 * 186 * @param oid The int id for the job. 187 * @return A JobEntry. 188 * @exception TurbineException could not retrieve job 189 */ 190 @Override 191 public JobEntry getJob(int oid) 192 throws TurbineException 193 { 194 JobEntry je = new JobEntry(); 195 je.setJobId(oid); 196 return scheduleQueue.getJob(je); 197 } 198 199 /** 200 * Add a new job to the queue. 201 * 202 * @param je A JobEntry with the job to add. 203 * @throws TurbineException job could not be added 204 */ 205 @Override 206 public void addJob(JobEntry je) 207 throws TurbineException 208 { 209 updateJob(je); 210 } 211 212 /** 213 * Remove a job from the queue. 214 * 215 * @param je A JobEntry with the job to remove. 216 */ 217 @Override 218 public void removeJob(JobEntry je) 219 { 220 // Remove from the queue. 221 scheduleQueue.remove(je); 222 restart(); 223 } 224 225 /** 226 * Add/update a job 227 * 228 * @param je A JobEntry with the job to modify 229 * @throws TurbineException job could not be updated 230 */ 231 @Override 232 public void updateJob(JobEntry je) 233 throws TurbineException 234 { 235 try 236 { 237 je.calcRunTime(); 238 239 // Update the queue. 240 scheduleQueue.modify(je); 241 restart(); 242 } 243 catch (Exception e) 244 { 245 String errorMessage = "Problem updating Scheduled Job: " + je.getTask(); 246 log.error(errorMessage, e); 247 throw new TurbineException(errorMessage, e); 248 } 249 } 250 }