KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sape > carbon > services > scheduler > AbstractTask


1 /*
2  * The contents of this file are subject to the Sapient Public License
3  * Version 1.0 (the "License"); you may not use this file except in compliance
4  * with the License. You may obtain a copy of the License at
5  * http://carbon.sf.net/License.html.
6  *
7  * Software distributed under the License is distributed on an "AS IS" basis,
8  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
9  * the specific language governing rights and limitations under the License.
10  *
11  * The Original Code is The Carbon Component Framework.
12  *
13  * The Initial Developer of the Original Code is Sapient Corporation
14  *
15  * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.
16  */

17
18 package org.sape.carbon.services.scheduler;
19
20 import java.util.Timer JavaDoc;
21 import java.util.TimerTask JavaDoc;
22 import java.lang.reflect.Method JavaDoc;
23 import java.lang.reflect.InvocationTargetException JavaDoc;
24
25 import org.sape.carbon.core.component.Component;
26 import org.sape.carbon.core.component.FunctionalInterface;
27 import org.sape.carbon.core.config.InvalidConfigurationException;
28 import org.sape.carbon.core.exception.ExceptionUtility;
29 import org.sape.carbon.core.exception.IllegalStateException;
30
31 import org.sape.carbon.services.threadpool.ThreadPool;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35
36 /**
37  * Base class for tasks run by the SchedulerService. The main purpose of
38  * this class is to implement a java.util.TimerTask that calls the
39  * runScheduledTask of the Schedulable interface on the configured component.
40  * Subclasses implement their own scheduling functionality
41  * by implementing the schedule method, calling one of the schedule methods
42  * on the java.util.Timer class.
43  *
44  * @see java.util.Timer
45  * @see java.util.TimerTask
46  *
47  * Copyright 2002 Sapient
48  * @since carbon 1.0
49  * @author Douglas Voet, June 2002
50  * @version $Revision: 1.14 $($Author: dvoet $ / $Date: 2003/11/20 21:46:14 $)
51  */

52 public abstract class AbstractTask {
53
54     /**
55      * Provides a handle to Apache-commons logger
56      */

57     private static Log log = LogFactory.getLog(AbstractTask.class);
58
59     /** component to call when the task runs */
60     private FunctionalInterface schedulableComponent;
61
62     private String JavaDoc scheduledMethodName;
63
64     private Method JavaDoc scheduledMethod;
65     
66     private ThreadPool threadPool;
67
68     /**
69      * Loads and validates the component called from this task.
70      *
71      * @param taskConfiguration the configuration of the Schedulable
72      * component called from this task.
73      */

74     protected AbstractTask(
75         BaseTaskConfiguration taskConfiguration,
76         ThreadPool threadPool) {
77
78         this.schedulableComponent =
79             taskConfiguration.getSchedulableComponent();
80         this.scheduledMethodName = taskConfiguration.getScheduledMethod();
81
82         if (this.schedulableComponent == null) {
83             throw new InvalidConfigurationException(
84                 this.getClass(),
85                 taskConfiguration.getConfigurationName(),
86                 "SchedulableComponent",
87                 "SchedulableComponent must be specified");
88         }
89
90         if (!(this.schedulableComponent instanceof Schedulable)) {
91
92             if (this.scheduledMethodName == null) {
93
94                 throw new InvalidConfigurationException(
95                     this.getClass(),
96                     taskConfiguration.getConfigurationName(),
97                     "ScheduledMethodName",
98                     "If a scheduled component is not an instance of "+
99                     Schedulable.class.getName() + " you must provide " +
100                     "the name of a no-argument method to executed.");
101             }
102         }
103
104         if (this.scheduledMethodName != null) {
105             try {
106                 this.scheduledMethod =
107                     this.schedulableComponent.getClass().getMethod(
108                         this.scheduledMethodName,new Class JavaDoc[] {});
109             } catch (NoSuchMethodException JavaDoc nsme) {
110                 throw new InvalidConfigurationException(
111                 this.getClass(),
112                 taskConfiguration.getConfigurationName(),
113                 "ScheduledMethodName",
114                 "The provided scheduled method name [" +
115                 this.scheduledMethodName + "] was not found to be a " +
116                 "no argument method on the configured component [" +
117                 ((Component)this.schedulableComponent).getComponentName() + "].");
118             }
119         }
120
121         this.threadPool = threadPool;
122     }
123     
124     /**
125      * Method called to schedule this task on the given Timer. Implementations
126      * are responsible for determining when to schedule this task, its repeat
127      * period and how it is scheduled (fixed rate or delay). To this end, one
128      * of the schedule mehtods on timer should be called.
129      *
130      * @param timer Timer on which this task should be scheduled
131      */

132     public abstract void schedule(Timer JavaDoc timer);
133
134     /**
135      * Method used to get the java.util.TimerTask reprentation of this Task.
136      * The intended use is within the schedule abstract method.
137      *
138      * @return TimerTask Task to be scheduled within the schedule method.
139      */

140     protected TimerTask JavaDoc getTask() {
141         InternalTask componentExecutor;
142         
143         if (this.scheduledMethod != null) {
144             componentExecutor = new InternalTask(this.schedulableComponent, this.scheduledMethod);
145         } else {
146             componentExecutor = new InternalTask(this.schedulableComponent);
147         }
148         
149         if (this.threadPool == null) {
150             return componentExecutor;
151         } else {
152             String JavaDoc taskName = ((Component) this.schedulableComponent).getComponentName();
153             if (this.scheduledMethodName != null) {
154                 taskName = taskName + "." + this.scheduledMethodName;
155             }
156             
157             return new TaskQueuer(
158                 this.threadPool,
159                 componentExecutor,
160                 taskName);
161         }
162     }
163
164     /**
165      * Class that extends java.util.TimerTask. This task class is the one
166      * that is scheduled on the timer and calls the schedulableComponent.
167      */

168     private static class InternalTask extends TimerTask JavaDoc {
169         /** Holds the schedulable component for this task. */
170         private FunctionalInterface schedulableComponent;
171
172         private Method JavaDoc method;
173
174         /**
175          * Constructs a task for a schedulable component.
176          *
177          * @param schedulableComponent component the task is constructed for.
178          */

179         public InternalTask(FunctionalInterface schedulableComponent) {
180             this.schedulableComponent = schedulableComponent;
181         }
182
183         public InternalTask(FunctionalInterface schedulableComponent, Method JavaDoc method) {
184             this.schedulableComponent = schedulableComponent;
185             this.method = method;
186         }
187
188         /**
189          * Calls runScheduledTask on the scheduled component
190          */

191         public void run() {
192             try {
193                 if (log.isInfoEnabled()) {
194                     log.info("Running scheduled component ["
195                         + ((Component) schedulableComponent).getComponentName()
196                         + "]");
197                 }
198
199                 if (this.method == null) {
200                     ((Schedulable)schedulableComponent).runScheduledTask();
201                 } else {
202                     this.method.invoke(this.schedulableComponent, new Object JavaDoc[] {});
203                 }
204
205             } catch (UnrecoverableTaskException ute) {
206                 // cancel the task
207
cancel();
208                 if (log.isErrorEnabled()) {
209                     log.error("Caught UnrecoverableTaskException while "
210                         + "running, scheduled task, task canceled: "
211                         + ExceptionUtility.printStackTracesToString(ute));
212                 }
213             } catch (InvocationTargetException JavaDoc ite) {
214                 if (log.isWarnEnabled()) {
215                     log.warn("Caught Throwable while running scheduled task, "
216                         + "task has not been canceled: "
217                         + ExceptionUtility.printStackTracesToString(ite.getTargetException()));
218                 }
219             } catch (Throwable JavaDoc t) {
220                 if (log.isWarnEnabled()) {
221                     log.warn("Caught Throwable while running scheduled task, "
222                         + "task has not been canceled: "
223                         + ExceptionUtility.printStackTracesToString(t));
224                 }
225             }
226         }
227     }
228     
229     private static class TaskQueuer extends TimerTask JavaDoc {
230         private ThreadPool threadPool;
231         private InternalTask task;
232         private String JavaDoc taskName;
233         
234         public TaskQueuer(ThreadPool threadPool, InternalTask task, String JavaDoc taskName) {
235             this.threadPool = threadPool;
236             this.task = task;
237             this.taskName = taskName;
238         }
239
240         public void run() {
241             this.threadPool.execute(this.task, this.taskName);
242         }
243
244         
245     }
246 }
247
Popular Tags