View Javadoc

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