KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > scheduling > commonj > TimerManagerFactoryBean


1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.scheduling.commonj;
18
19 import java.util.Iterator JavaDoc;
20 import java.util.LinkedList JavaDoc;
21 import java.util.List JavaDoc;
22
23 import javax.naming.NamingException JavaDoc;
24
25 import commonj.timers.Timer;
26 import commonj.timers.TimerManager;
27
28 import org.springframework.beans.factory.DisposableBean;
29 import org.springframework.beans.factory.FactoryBean;
30 import org.springframework.beans.factory.InitializingBean;
31 import org.springframework.context.Lifecycle;
32 import org.springframework.jndi.JndiLocatorSupport;
33
34 /**
35  * FactoryBean that retrieves a CommonJ {@link commonj.timers.TimerManager}
36  * and exposes it for bean references.
37  *
38  * <p><b>This is the central convenience class for setting up a
39  * CommonJ TimerManager in a Spring context.</b>
40  *
41  * <p>Allows for registration of ScheduledTimerListeners. This is the main
42  * purpose of this class; the TimerManager itself could also be fetched
43  * from JNDI via {@link org.springframework.jndi.JndiObjectFactoryBean}.
44  * In scenarios that just require static registration of tasks at startup,
45  * there is no need to access the TimerManager itself in application code.
46  *
47  * <p>Note that the TimerManager uses a TimerListener instance that is
48  * shared between repeated executions, in contrast to Quartz which
49  * instantiates a new Job for each execution.
50  *
51  * @author Juergen Hoeller
52  * @since 2.0
53  * @see ScheduledTimerListener
54  * @see commonj.timers.TimerManager
55  * @see commonj.timers.TimerListener
56  */

57 public class TimerManagerFactoryBean extends JndiLocatorSupport
58         implements FactoryBean, InitializingBean, DisposableBean, Lifecycle {
59
60     private TimerManager timerManager;
61
62     private String JavaDoc timerManagerName;
63
64     private boolean shared = false;
65
66     private ScheduledTimerListener[] scheduledTimerListeners;
67
68     private final List JavaDoc timers = new LinkedList JavaDoc();
69
70
71     /**
72      * Specify the CommonJ TimerManager to delegate to.
73      * <p>Note that the given TimerManager's lifecycle will be managed
74      * by this FactoryBean.
75      * <p>Alternatively (and typically), you can specify the JNDI name
76      * of the target TimerManager.
77      * @see #setTimerManagerName
78      */

79     public void setTimerManager(TimerManager timerManager) {
80         this.timerManager = timerManager;
81     }
82
83     /**
84      * Set the JNDI name of the CommonJ TimerManager.
85      * <p>This can either be a fully qualified JNDI name, or the JNDI name relative
86      * to the current environment naming context if "resourceRef" is set to "true".
87      * @see #setTimerManager
88      * @see #setResourceRef
89      */

90     public void setTimerManagerName(String JavaDoc timerManagerName) {
91         this.timerManagerName = timerManagerName;
92     }
93
94     /**
95      * Specify whether the TimerManager obtained by this FactoryBean
96      * is a shared instance ("true") or an independent instance ("false").
97      * The lifecycle of the former is supposed to be managed by the application
98      * server, while the lifecycle of the latter is up to the application.
99      * <p>Default is "false", i.e. managing an independent TimerManager instance.
100      * This is what the CommonJ specification suggests that application servers
101      * are supposed to offer via JNDI lookups, typically declared as a
102      * <code>resource-ref</code> of type <code>commonj.timers.TimerManager</code>
103      * in <code>web.xml<code>, with <code>res-sharing-scope</code> set to 'Unshareable'.
104      * <p>Switch this flag to "true" if you are obtaining a shared TimerManager,
105      * typically through specifying the JNDI location of a TimerManager that
106      * has been explicitly declared as 'Shareable'. Note that WebLogic's
107      * cluster-aware Job Scheduler is a shared TimerManager too.
108      * <p>The sole difference between this FactoryBean being in shared or
109      * non-shared mode is that it will only attempt to suspend / resume / stop
110      * the underlying TimerManager in case of an independent (non-shared) instance.
111      * This only affects the {@link org.springframework.context.Lifecycle} support
112      * as well as application context shutdown.
113      * @see #stop()
114      * @see #start()
115      * @see #destroy()
116      * @see commonj.timers.TimerManager
117      */

118     public void setShared(boolean shared) {
119         this.shared = shared;
120     }
121
122     /**
123      * Register a list of ScheduledTimerListener objects with the TimerManager
124      * that this FactoryBean creates. Depending on each ScheduledTimerListener's settings,
125      * it will be registered via one of TimerManager's schedule methods.
126      * @see commonj.timers.TimerManager#schedule(commonj.timers.TimerListener, long)
127      * @see commonj.timers.TimerManager#schedule(commonj.timers.TimerListener, long, long)
128      * @see commonj.timers.TimerManager#scheduleAtFixedRate(commonj.timers.TimerListener, long, long)
129      */

130     public void setScheduledTimerListeners(ScheduledTimerListener[] scheduledTimerListeners) {
131         this.scheduledTimerListeners = scheduledTimerListeners;
132     }
133
134
135     //---------------------------------------------------------------------
136
// Implementation of InitializingBean interface
137
//---------------------------------------------------------------------
138

139     public void afterPropertiesSet() throws NamingException JavaDoc {
140         if (this.timerManager == null) {
141             if (this.timerManagerName == null) {
142                 throw new IllegalArgumentException JavaDoc("Either 'timerManager' or 'timerManagerName' must be specified");
143             }
144             this.timerManager = (TimerManager) lookup(this.timerManagerName, TimerManager.class);
145         }
146
147         for (int i = 0; i < this.scheduledTimerListeners.length; i++) {
148             ScheduledTimerListener scheduledTask = this.scheduledTimerListeners[i];
149             Timer timer = null;
150             if (scheduledTask.isOneTimeTask()) {
151                 timer = this.timerManager.schedule(scheduledTask.getTimerListener(), scheduledTask.getDelay());
152             }
153             else {
154                 if (scheduledTask.isFixedRate()) {
155                     timer = this.timerManager.scheduleAtFixedRate(
156                             scheduledTask.getTimerListener(), scheduledTask.getDelay(), scheduledTask.getPeriod());
157                 }
158                 else {
159                     timer = this.timerManager.schedule(
160                             scheduledTask.getTimerListener(), scheduledTask.getDelay(), scheduledTask.getPeriod());
161                 }
162             }
163             this.timers.add(timer);
164         }
165     }
166
167
168     //---------------------------------------------------------------------
169
// Implementation of FactoryBean interface
170
//---------------------------------------------------------------------
171

172     public Object JavaDoc getObject() {
173         return this.timerManager;
174     }
175
176     public Class JavaDoc getObjectType() {
177         return (this.timerManager != null ? this.timerManager.getClass() : TimerManager.class);
178     }
179
180     public boolean isSingleton() {
181         return true;
182     }
183
184
185     //---------------------------------------------------------------------
186
// Implementation of Lifecycle interface
187
//---------------------------------------------------------------------
188

189     /**
190      * Resumes the underlying TimerManager (if not shared).
191      * @see commonj.timers.TimerManager#resume()
192      */

193     public void start() {
194         if (!this.shared) {
195             this.timerManager.resume();
196         }
197     }
198
199     /**
200      * Suspends the underlying TimerManager (if not shared).
201      * @see commonj.timers.TimerManager#suspend()
202      */

203     public void stop() {
204         if (!this.shared) {
205             this.timerManager.suspend();
206         }
207     }
208
209     /**
210      * Considers the underlying TimerManager as running if it is
211      * neither suspending nor stopping.
212      * @see commonj.timers.TimerManager#isSuspending()
213      * @see commonj.timers.TimerManager#isStopping()
214      */

215     public boolean isRunning() {
216         return (!this.timerManager.isSuspending() && !this.timerManager.isStopping());
217     }
218
219
220     //---------------------------------------------------------------------
221
// Implementation of DisposableBean interface
222
//---------------------------------------------------------------------
223

224     /**
225      * Cancels all statically registered Timers on shutdown,
226      * and stops the underlying TimerManager (if not shared).
227      * @see commonj.timers.Timer#cancel()
228      * @see commonj.timers.TimerManager#stop()
229      */

230     public void destroy() {
231         // Cancel all registered timers.
232
for (Iterator JavaDoc it = this.timers.iterator(); it.hasNext();) {
233             Timer timer = (Timer) it.next();
234             try {
235                 timer.cancel();
236             }
237             catch (Throwable JavaDoc ex) {
238                 logger.warn("Could not cancel CommonJ Timer", ex);
239             }
240         }
241         this.timers.clear();
242
243         // Stop the entire TimerManager, if necessary.
244
if (!this.shared) {
245             // May return early, but at least we already cancelled all known Timers.
246
this.timerManager.stop();
247         }
248     }
249
250 }
251
Popular Tags