001 package org.apache.turbine.services.schedule; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022 import java.util.List; 023 import java.util.Vector; 024 025 import javax.servlet.ServletConfig; 026 027 import org.apache.commons.configuration.Configuration; 028 029 import org.apache.commons.lang.StringUtils; 030 031 import org.apache.commons.logging.Log; 032 import org.apache.commons.logging.LogFactory; 033 034 import org.apache.turbine.services.InitializationException; 035 import org.apache.turbine.util.TurbineException; 036 037 /** 038 * Service for a cron like scheduler that uses the 039 * TurbineResources.properties file instead of the database. 040 * The methods that operate on jobs ( get,add,update,remove ) 041 * only operate on the queue in memory and changes are not reflected 042 * to the properties file which was used to initilize the jobs. 043 * An example is given below. The job names are the class names that 044 * extend ScheduledJob. 045 * 046 * <PRE> 047 * 048 * services.SchedulerService.scheduler.jobs=scheduledJobName,scheduledJobName2 049 * 050 * services.SchedulerService.scheduler.job.scheduledJobName.ID=1 051 * services.SchedulerService.scheduler.job.scheduledJobName.SECOND=-1 052 * services.SchedulerService.scheduler.job.scheduledJobName.MINUTE=-1 053 * services.SchedulerService.scheduler.job.scheduledJobName.HOUR=7 054 * services.SchedulerService.scheduler.job.scheduledJobName.WEEKDAY=-1 055 * services.SchedulerService.scheduler.job.scheduledJobName.DAY_OF_MONTH=-1 056 * 057 * services.SchedulerService.scheduler.job.scheduledJobName2.ID=1 058 * services.SchedulerService.scheduler.job.scheduledJobName2.SECOND=-1 059 * services.SchedulerService.scheduler.job.scheduledJobName2.MINUTE=-1 060 * services.SchedulerService.scheduler.job.scheduledJobName2.HOUR=7 061 * services.SchedulerService.scheduler.job.scheduledJobName2.WEEKDAY=-1 062 * services.SchedulerService.scheduler.job.scheduledJobName2.DAY_OF_MONTH=-1 063 * 064 * </PRE> 065 * 066 * Based on TamboraSchedulerService written by John Thorhauer. 067 * 068 * @author <a href="mailto:ekkerbj@netscpae.net">Jeff Brekke</a> 069 * @author <a href="mailto:john@zenplex.com">John Thorhauer</a> 070 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a> 071 * @version $Id: TurbineNonPersistentSchedulerService.java 534527 2007-05-02 16:10:59Z tv $ 072 */ 073 public class TurbineNonPersistentSchedulerService 074 extends TurbineSchedulerService 075 { 076 /** Logging */ 077 private static Log log = LogFactory.getLog(ScheduleService.LOGGER_NAME); 078 079 /** 080 * Constructor. 081 * 082 * @exception TurbineException a generic exception. 083 */ 084 public TurbineNonPersistentSchedulerService() 085 throws TurbineException 086 { 087 super(); 088 } 089 090 /** 091 * Called the first time the Service is used.<br> 092 * 093 * Load all the jobs from cold storage. Add jobs to the queue 094 * (sorted in ascending order by runtime) and start the scheduler 095 * thread. 096 */ 097 @SuppressWarnings("unchecked") 098 @Override 099 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 }