1 /**
2  *  Copyright Terracotta, Inc.
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 net.sf.ehcache.util;
18
19 import java.util.Date;
20 import java.util.Timer;
21 import java.util.TimerTask;
22
23 /**
24  * A fail-safe timer in the sense that if the runtime environment restricts
25  * creating new threads, it doesn't blow up with an exception. TimerTasks that are
26  * scheduled will run at least once (inline when they are scheduled) if creating
27  * threads is not allowed.
28  * For example, Google App Engine does not allow creation of new threads.
29  * <p/>
30  * Clients should not use this as a general purpose timing service. To do so could
31  * interfere with the running of the Cache.
32  * 
33  * @author <a href="mailto:asanoujam@terracottatech.com">Abhishek Sanoujam</a>
34  * @since 1.7
35  * 
36  */

37 public class FailSafeTimer {
38
39     private final Timer timer;
40     private final boolean timerThreadRunning;
41
42     /**
43      * Constructor accepting a name for the timer. The scheduling thread is
44      * created as a daemon
45      * 
46      * @param name
47      */

48     public FailSafeTimer(String name) {
49         boolean threadRunning;
50         Timer localTimer = null;
51         try {
52             localTimer = new Timer(name, true);
53             threadRunning = true;
54         } catch (Exception e) {
55             localTimer = null;
56             threadRunning = false;
57         }
58         this.timerThreadRunning = threadRunning;
59         this.timer = localTimer;
60     }
61
62     /**
63      * If the runtime environment restricts thread creation, this method does
64      * nothing.
65      * 
66      * @see java.util.Timer#cancel()
67      */

68     public void cancel() {
69         if (timerThreadRunning) {
70             timer.cancel();
71         }
72     }
73
74     /**
75      * If the runtime environment restricts thread creation, this method does
76      * nothing.
77      * 
78      * @see java.util.Timer#purge()
79      */

80     public int purge() {
81         if (timerThreadRunning) {
82             return timer.purge();
83         } else {
84             return 0;
85         }
86     }
87
88     /**
89      * If the runtime environment restricts thread creation, the task is run
90      * inline for only one time. No further repeated execution happens for the
91      * task
92      * 
93      * @see java.util.Timer#schedule(java.util.TimerTask, java.util.Date, long)
94      */

95     public void schedule(TimerTask task, Date firstTime, long period) {
96         if (timerThreadRunning) {
97             timer.schedule(task, firstTime, period);
98         } else {
99             task.run();
100         }
101     }
102
103     /**
104      * If the runtime environment restricts thread creation, the task is run
105      * inline for only one time. No further repeated execution happens for the
106      * task
107      * 
108      * @see java.util.Timer#schedule(java.util.TimerTask, java.util.Date)
109      */

110     public void schedule(TimerTask task, Date time) {
111         if (timerThreadRunning) {
112             timer.schedule(task, time);
113         } else {
114             task.run();
115         }
116     }
117
118     /**
119      * If the runtime environment restricts thread creation, the task is run
120      * inline for only one time. No further repeated execution happens for the
121      * task
122      * 
123      * @see java.util.Timer#schedule(java.util.TimerTask, longlong)
124      */

125     public void schedule(TimerTask task, long delay, long period) {
126         if (timerThreadRunning) {
127             timer.schedule(task, delay, period);
128         } else {
129             task.run();
130         }
131     }
132
133     /**
134      * If the runtime environment restricts thread creation, the task is run
135      * inline for only one time. No further repeated execution happens for the
136      * task
137      * 
138      * @see java.util.Timer#schedule(java.util.TimerTask, long)
139      */

140     public void schedule(TimerTask task, long delay) {
141         if (timerThreadRunning) {
142             timer.schedule(task, delay);
143         } else {
144             task.run();
145         }
146     }
147
148     /**
149      * If the runtime environment restricts thread creation, the task is run
150      * inline for only one time. No further repeated execution happens for the
151      * task
152      * 
153      * @see java.util.Timer#scheduleAtFixedRate(java.util.TimerTask, java.util.Date, long)
154      */

155     public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) {
156         if (timerThreadRunning) {
157             timer.scheduleAtFixedRate(task, firstTime, period);
158         } else {
159             task.run();
160         }
161     }
162
163     /**
164      * If the runtime environment restricts thread creation, the task is run
165      * inline for only one time. No further repeated execution happens for the
166      * task
167      * 
168      * @see java.util.Timer#scheduleAtFixedRate(java.util.TimerTask, longlong)
169      */

170     public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
171         if (timerThreadRunning) {
172             timer.scheduleAtFixedRate(task, delay, period);
173         } else {
174             task.run();
175         }
176     }
177
178 }
179